Skip to content

Commit

Permalink
rbd-ggate: allow to unmap by image or snap spec
Browse files Browse the repository at this point in the history
(to match the behaviour of krbd unmap)

Signed-off-by: Mykola Golub <to.my.trociny@gmail.com>
  • Loading branch information
trociny committed Dec 25, 2017
1 parent 777a129 commit e7dc1d5
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 23 deletions.
15 changes: 15 additions & 0 deletions qa/workunits/rbd/rbd-ggate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,19 @@ _sudo rbd-ggate unmap ${DEV}
DEV=
rbd bench -p ${POOL} ${IMAGE} --io-type=write --io-size=1024 --io-total=1024

# unmap by image name test
DEV=`_sudo rbd-ggate map ${POOL}/${IMAGE}`
_sudo rbd-ggate list | grep " ${DEV} *$"
_sudo rbd-ggate unmap "${POOL}/${IMAGE}"
rbd-ggate list-mapped | expect_false grep " ${DEV} *$"
DEV=

# map/unmap snap test
rbd snap create ${POOL}/${IMAGE}@snap
DEV=`_sudo rbd-ggate map ${POOL}/${IMAGE}@snap`
_sudo rbd-ggate list | grep " ${DEV} *$"
_sudo rbd-ggate unmap "${POOL}/${IMAGE}@snap"
rbd-ggate list-mapped | expect_false grep " ${DEV} *$"
DEV=

echo OK
66 changes: 45 additions & 21 deletions src/tools/rbd/action/Ggate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,30 @@ static int call_ggate_cmd(const po::variables_map &vm,
return 0;
}

int get_image_or_snap_spec(const po::variables_map &vm, std::string *spec) {
size_t arg_index = 0;
std::string pool_name;
std::string image_name;
std::string snap_name;
int r = utils::get_pool_image_snapshot_names(
vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
&snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED,
utils::SPEC_VALIDATION_NONE);
if (r < 0) {
return r;
}

spec->append(pool_name);
spec->append("/");
spec->append(image_name);
if (!snap_name.empty()) {
spec->append("@");
spec->append(snap_name);
}

return 0;
}

void get_list_arguments(po::options_description *positional,
po::options_description *options)
{ }
Expand All @@ -102,28 +126,13 @@ void get_map_arguments(po::options_description *positional,

int execute_map(const po::variables_map &vm)
{
size_t arg_index = 0;
std::string pool_name;
std::string image_name;
std::string snap_name;
int r = utils::get_pool_image_snapshot_names(
vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
&snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED,
utils::SPEC_VALIDATION_NONE);
if (r < 0) {
return r;
}

std::vector<const char*> args;

args.push_back("map");
std::string img;
img.append(pool_name);
img.append("/");
img.append(image_name);
if (!snap_name.empty()) {
img.append("@");
img.append(snap_name);
int r = get_image_or_snap_spec(vm, &img);
if (r < 0) {
return r;
}
args.push_back(img.c_str());

Expand All @@ -145,7 +154,12 @@ void get_unmap_arguments(po::options_description *positional,
po::options_description *options)
{
positional->add_options()
("device-spec", "specify ggate device");
("image-or-snap-or-device-spec",
"image, snapshot, or device specification\n"
"[<pool-name>/]<image-name>[@<snapshot-name>] or <device-path>");
at::add_pool_option(options, at::ARGUMENT_MODIFIER_NONE);
at::add_image_option(options, at::ARGUMENT_MODIFIER_NONE);
at::add_snap_option(options, at::ARGUMENT_MODIFIER_NONE);
}

int execute_unmap(const po::variables_map &vm)
Expand All @@ -155,15 +169,25 @@ int execute_unmap(const po::variables_map &vm)
device_name.clear();
}

std::string image_name;
if (device_name.empty()) {
std::cerr << "rbd: ggate unmap requires device path" << std::endl;
int r = get_image_or_snap_spec(vm, &image_name);
if (r < 0) {
return r;
}
}

if (device_name.empty() && image_name.empty()) {
std::cerr << "rbd: unmap requires either image name or device path"
<< std::endl;
return -EINVAL;
}

std::vector<const char*> args;

args.push_back("unmap");
args.push_back(device_name.c_str());
args.push_back(device_name.empty() ? image_name.c_str() :
device_name.c_str());

return call_ggate_cmd(vm, args);
}
Expand Down
48 changes: 46 additions & 2 deletions src/tools/rbd_ggate/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,46 @@ static int parse_imgpath(const std::string &imgpath, std::string *poolname,
return 0;
}

static bool find_mapped_dev_by_spec(const std::string &spec,
std::string *devname) {
std::string poolname, imgname, snapname;
int r = parse_imgpath(spec, &poolname, &imgname, &snapname);
if (r < 0) {
return false;
}
if (poolname.empty()) {
// We could use rbd_default_pool config to set pool name but then
// we would need to initialize the global context. So right now it
// is mandatory for the user to specify a pool. Fortunately the
// preferred way for users to call rbd-ggate is via rbd, which
// cares to set the pool name.
return false;
}

std::map<std::string, rbd::ggate::Driver::DevInfo> devs;
r = rbd::ggate::Driver::list(&devs);
if (r < 0) {
return false;
}

for (auto &it : devs) {
auto &name = it.second.first;
auto &info = it.second.second;
if (!boost::starts_with(info, "RBD ")) {
continue;
}

std::string p, i, s;
parse_imgpath(info.substr(4), &p, &i, &s);
if (p == poolname && i == imgname && s == snapname) {
*devname = name;
return true;
}
}

return false;
}

static int do_list()
{
rbd::ggate::Driver::load();
Expand Down Expand Up @@ -373,10 +413,14 @@ int main(int argc, const char *argv[]) {
break;
case Disconnect:
if (args.begin() == args.end()) {
cerr << "rbd-ggate: must specify ggate device path" << std::endl;
std::cerr << "rbd-ggate: must specify ggate device or image-or-snap-spec"
<< std::endl;
return EXIT_FAILURE;
}
devpath = *args.begin();
if (boost::starts_with(*args.begin(), "/dev/") ||
!find_mapped_dev_by_spec(*args.begin(), &devpath)) {
devpath = *args.begin();
}
args.erase(args.begin());
break;
default:
Expand Down

0 comments on commit e7dc1d5

Please sign in to comment.