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
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) {
at::add_format_options(options);
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());
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)
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);
}
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(const std::string &format, bool pretty_format)
{
rbd::ggate::Driver::load();
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: