The --options argument is a comma separated list of device type
specific options (opt1,opt2=val,...).
+:command:`device attach` [-t | --device-type *device-type*] --device *device-path* [--read-only] [--exclusive] [--force] [-o | --options *device-options*] *image-spec* | *snap-spec*
+ Attach the specified image to the specified block device (currently only
+ `nbd` on Linux). This operation is unsafe and should not be normally used.
+ In particular, specifying the wrong image or the wrong block device may
+ lead to data corruption as no validation is performed by `nbd` kernel driver.
+
+ The --options argument is a comma separated list of device type
+ specific options (opt1,opt2=val,...).
+
+:command:`device detach` [-t | --device-type *device-type*] [-o | --options *device-options*] *image-spec* | *snap-spec* | *device-path*
+ Detach the block device that was mapped or attached (currently only `nbd`
+ on Linux). This operation is unsafe and should not be normally used.
+
+ The --options argument is a comma separated list of device type
+ specific options (opt1,opt2=val,...).
+
:command:`diff` [--from-snap *snap-name*] [--whole-object] *image-spec* | *snap-spec*
Dump a list of byte extents in the image that have changed since the specified start
snapshot, or since the image was created. Each output line includes the starting offset
copy (cp) Copy src image to dest.
create Create an empty image.
deep copy (deep cp) Deep copy src image to dest.
+ device attach Attach image to device.
+ device detach Detach image from device.
device list (showmapped) List mapped rbd images.
device map (map) Map an image to a block device.
device unmap (unmap) Unmap a rbd device.
(-) supports disabling-only on existing images
(+) enabled by default for new images if features not specified
+ rbd help device attach
+ usage: rbd device attach [--device-type <device-type>] [--pool <pool>]
+ [--namespace <namespace>] [--image <image>]
+ [--snap <snap>] --device <device> [--read-only]
+ [--force] [--exclusive] [--quiesce]
+ [--quiesce-hook <quiesce-hook>] [--options <options>]
+ <image-or-snap-spec>
+
+ Attach image to device.
+
+ Positional arguments
+ <image-or-snap-spec> image or snapshot specification
+ (example:
+ [<pool-name>/[<namespace>/]]<image-name>[@<snap-name>
+ ])
+
+ Optional arguments
+ -t [ --device-type ] arg device type [ggate, krbd (default), nbd]
+ -p [ --pool ] arg pool name
+ --namespace arg namespace name
+ --image arg image name
+ --snap arg snapshot name
+ --device arg specify device path
+ --read-only attach read-only
+ --force force attach
+ --exclusive disable automatic exclusive lock transitions
+ --quiesce use quiesce hooks
+ --quiesce-hook arg quiesce hook path
+ -o [ --options ] arg device specific options
+
+ rbd help device detach
+ usage: rbd device detach [--device-type <device-type>] [--pool <pool>]
+ [--image <image>] [--snap <snap>]
+ [--options <options>]
+ <image-or-snap-or-device-spec>
+
+ Detach image from device.
+
+ Positional arguments
+ <image-or-snap-or-device-spec> image, snapshot, or device specification
+ [<pool-name>/]<image-name>[@<snap-name>] or
+ <device-path>
+
+ Optional arguments
+ -t [ --device-type ] arg device type [ggate, krbd (default), nbd]
+ -p [ --pool ] arg pool name
+ --image arg image name
+ --snap arg snapshot name
+ -o [ --options ] arg device specific options
+
rbd help device list
usage: rbd device list [--device-type <device-type>] [--format <format>]
[--pretty-format]
const std::vector<std::string> &ceph_global_args); \
int execute_unmap(const po::variables_map &vm, \
const std::vector<std::string> &ceph_global_args); \
+ int execute_attach(const po::variables_map &vm, \
+ const std::vector<std::string> &ceph_global_args); \
+ int execute_detach(const po::variables_map &vm, \
+ const std::vector<std::string> &ceph_global_args); \
}
DECLARE_DEVICE_OPERATIONS(ggate);
const std::vector<std::string> &ceph_global_args);
int (*execute_unmap)(const po::variables_map &vm,
const std::vector<std::string> &ceph_global_args);
+ int (*execute_attach)(const po::variables_map &vm,
+ const std::vector<std::string> &ceph_global_args);
+ int (*execute_detach)(const po::variables_map &vm,
+ const std::vector<std::string> &ceph_global_args);
};
const DeviceOperations ggate_operations = {
ggate::execute_list,
ggate::execute_map,
ggate::execute_unmap,
+ ggate::execute_attach,
+ ggate::execute_detach,
};
const DeviceOperations krbd_operations = {
kernel::execute_list,
kernel::execute_map,
kernel::execute_unmap,
+ kernel::execute_attach,
+ kernel::execute_detach,
};
const DeviceOperations nbd_operations = {
nbd::execute_list,
nbd::execute_map,
nbd::execute_unmap,
+ nbd::execute_attach,
+ nbd::execute_detach,
};
const DeviceOperations wnbd_operations = {
wnbd::execute_list,
wnbd::execute_map,
wnbd::execute_unmap,
+ wnbd::execute_attach,
+ wnbd::execute_detach,
};
enum device_type_t {
return (*get_device_operations(vm)->execute_unmap)(vm, ceph_global_init_args);
}
+void get_attach_arguments(po::options_description *positional,
+ po::options_description *options) {
+ add_device_type_option(options);
+ at::add_image_or_snap_spec_options(positional, options,
+ at::ARGUMENT_MODIFIER_NONE);
+ options->add_options()
+ ("device", po::value<std::string>()->required(), "specify device path")
+ ("read-only", po::bool_switch(), "attach read-only")
+ ("force", po::bool_switch(), "force attach")
+ ("exclusive", po::bool_switch(), "disable automatic exclusive lock transitions")
+ ("quiesce", po::bool_switch(), "use quiesce hooks")
+ ("quiesce-hook", po::value<std::string>(), "quiesce hook path");
+ add_device_specific_options(options);
+}
+
+int execute_attach(const po::variables_map &vm,
+ const std::vector<std::string> &ceph_global_init_args) {
+ return (*get_device_operations(vm)->execute_attach)(vm, ceph_global_init_args);
+}
+
+void get_detach_arguments(po::options_description *positional,
+ po::options_description *options) {
+ add_device_type_option(options);
+ positional->add_options()
+ ("image-or-snap-or-device-spec",
+ "image, snapshot, or device specification\n"
+ "[<pool-name>/]<image-name>[@<snap-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);
+ add_device_specific_options(options);
+}
+
+int execute_detach(const po::variables_map &vm,
+ const std::vector<std::string> &ceph_global_init_args) {
+ return (*get_device_operations(vm)->execute_detach)(vm, ceph_global_init_args);
+}
+
Shell::SwitchArguments switched_arguments({"exclusive", "force", "quiesce",
"read-only"});
{"device", "unmap"}, {"unmap"}, "Unmap a rbd device.", "",
&get_unmap_arguments, &execute_unmap);
+Shell::Action action_attach(
+ {"device", "attach"}, {}, "Attach image to device.", "",
+ &get_attach_arguments, &execute_attach);
+
+Shell::Action action_detach(
+ {"device", "detach"}, {}, "Detach image from device.", "",
+ &get_detach_arguments, &execute_detach);
+
} // namespace device
} // namespace action
} // namespace rbd
return call_ggate_cmd(vm, args, ceph_global_init_args);
}
+int execute_attach(const po::variables_map &vm,
+ const std::vector<std::string> &ceph_global_init_args) {
+ return -EOPNOTSUPP;
+}
+
+int execute_detach(const po::variables_map &vm,
+ const std::vector<std::string> &ceph_global_init_args) {
+ return -EOPNOTSUPP;
+}
+
} // namespace ggate
} // namespace action
} // namespace rbd
return 0;
}
+int execute_attach(const po::variables_map &vm,
+ const std::vector<std::string> &ceph_global_init_args) {
+ return -EOPNOTSUPP;
+}
+
+int execute_detach(const po::variables_map &vm,
+ const std::vector<std::string> &ceph_global_init_args) {
+ return -EOPNOTSUPP;
+}
+
} // namespace kernel
} // namespace action
} // namespace rbd
return call_nbd_cmd(vm, args, ceph_global_init_args);
}
+int execute_attach(const po::variables_map &vm,
+ const std::vector<std::string> &ceph_global_init_args) {
+#if defined(__FreeBSD__) || defined(_WIN32)
+ std::cerr << "rbd: nbd device is not supported" << std::endl;
+ return -EOPNOTSUPP;
+#endif
+ std::vector<std::string> args;
+ std::string device_path;
+
+ args.push_back("attach");
+ std::string img;
+ int r = get_image_or_snap_spec(vm, &img);
+ if (r < 0) {
+ return r;
+ }
+ args.push_back(img);
+
+ if (vm.count("device")) {
+ device_path = vm["device"].as<std::string>();
+ args.push_back("--device");
+ args.push_back(device_path);
+ } else {
+ std::cerr << "rbd: device was not specified" << std::endl;
+ return -EINVAL;
+ }
+
+ if (!vm["force"].as<bool>()) {
+ std::cerr << "rbd: could not validate attach request\n";
+ std::cerr << "rbd: mismatching the image and the device may lead to data corruption\n";
+ std::cerr << "rbd: must specify --force to proceed" << std::endl;
+ return -EINVAL;
+ }
+
+ if (vm["quiesce"].as<bool>()) {
+ args.push_back("--quiesce");
+ }
+
+ if (vm["read-only"].as<bool>()) {
+ args.push_back("--read-only");
+ }
+
+ if (vm["exclusive"].as<bool>()) {
+ args.push_back("--exclusive");
+ }
+
+ if (vm.count("quiesce-hook")) {
+ args.push_back("--quiesce-hook");
+ args.push_back(vm["quiesce-hook"].as<std::string>());
+ }
+
+ if (vm.count("options")) {
+ r = parse_options(vm["options"].as<std::vector<std::string>>(), &args);
+ if (r < 0) {
+ return r;
+ }
+ }
+
+ return call_nbd_cmd(vm, args, ceph_global_init_args);
+}
+
+int execute_detach(const po::variables_map &vm,
+ const std::vector<std::string> &ceph_global_init_args) {
+#if defined(__FreeBSD__) || defined(_WIN32)
+ std::cerr << "rbd: nbd device is not supported" << std::endl;
+ return -EOPNOTSUPP;
+#endif
+ std::string device_name = utils::get_positional_argument(vm, 0);
+ if (!boost::starts_with(device_name, "/dev/")) {
+ device_name.clear();
+ }
+
+ std::string image_name;
+ if (device_name.empty()) {
+ 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: detach requires either image name or device path"
+ << std::endl;
+ return -EINVAL;
+ }
+
+ std::vector<std::string> args;
+
+ args.push_back("detach");
+ args.push_back(device_name.empty() ? image_name : device_name);
+
+ if (vm.count("options")) {
+ int r = parse_options(vm["options"].as<std::vector<std::string>>(), &args);
+ if (r < 0) {
+ return r;
+ }
+ }
+
+ return call_nbd_cmd(vm, args, ceph_global_init_args);
+}
+
int execute_map(const po::variables_map &vm,
const std::vector<std::string> &ceph_global_init_args) {
#if defined(__FreeBSD__) || defined(_WIN32)
return call_wnbd_cmd(vm, args, ceph_global_init_args);
}
+int execute_attach(const po::variables_map &vm,
+ const std::vector<std::string> &ceph_global_init_args) {
+ return -EOPNOTSUPP;
+}
+
+int execute_detach(const po::variables_map &vm,
+ const std::vector<std::string> &ceph_global_init_args) {
+ return -EOPNOTSUPP;
+}
+
} // namespace wnbd
} // namespace action
} // namespace rbd