]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: promote rbd-nbd attach and detach at rbd integrated cli
authorPrasanna Kumar Kalever <prasanna.kalever@redhat.com>
Thu, 6 May 2021 07:27:56 +0000 (12:57 +0530)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 23 Mar 2022 12:31:59 +0000 (13:31 +0100)
Example:
$ rbd device attach rbd-pool/image --device /dev/nbd0 --device-type nbd --force
$ rbd device detach rpool/image --device-type nbd

for now returning EOPNOTSUPP with krbd, ggate and wnbd

Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
(cherry picked from commit 35e5352f719857bed99caa4c76ae19bb68918c8e)

Conflicts:
src/tools/rbd/action/Device.cc [ commit e1b4811bc324 ("rbd: add
  missing switch arguments for recognition by get_command_spec()")
  already in pacific ]
src/tools/rbd/action/Wnbd.cc [ ditto ]

doc/man/8/rbd.rst
src/test/cli/rbd/help.t
src/tools/rbd/action/Device.cc
src/tools/rbd/action/Ggate.cc
src/tools/rbd/action/Kernel.cc
src/tools/rbd/action/Nbd.cc
src/tools/rbd/action/Wnbd.cc

index 7488d1197d2f5d8701d69cc9a5e6f0f3806ad703..c4ae2507ef6b7e005b276a0829e4f9470792e5b4 100644 (file)
@@ -268,6 +268,22 @@ Commands
   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
index 98d440213925e9e506f82f5ea1a40090b28b5bd5..c2ce02e48841b5e324fb8a39f62aeeaeab785d39 100644 (file)
@@ -27,6 +27,8 @@
       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] 
index d88725f23f8aed426a8c9239816f779c00103634..17d286421d301c242aff3bce78b7968a89e1d35d 100644 (file)
@@ -23,6 +23,10 @@ namespace po = boost::program_options;
                   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);
@@ -41,30 +45,42 @@ struct DeviceOperations {
                      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 {
@@ -189,6 +205,44 @@ int execute_unmap(const po::variables_map &vm,
   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"});
 
@@ -208,6 +262,14 @@ Shell::Action action_unmap(
   {"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
index bae9778bbce9f19a7bffa8667c1236562d839fad..4ff02d48748191e7ebb84259fb8b418306a86b65 100644 (file)
@@ -207,6 +207,16 @@ int execute_unmap(const po::variables_map &vm,
   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
index cb59334652a557e7ba33312370c107028a3ec4fe..ef6f878546fc73ded996a06396f8c050a3aa7a79 100644 (file)
@@ -656,6 +656,16 @@ int execute_unmap(const po::variables_map &vm,
   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
index 592ea5194352aa0265858f87a2cb200f050d0a07..94a5f1701bf8b388e08c623003bcc507b8e50d0b 100644 (file)
@@ -134,6 +134,106 @@ int execute_list(const po::variables_map &vm,
   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)
index e6c30a5a13482063dd3040adf237dec2bb4807b9..6a5f34ba7a6a333579c99fdef7318dae27bc10a1 100644 (file)
@@ -187,6 +187,16 @@ int execute_unmap(const po::variables_map &vm,
   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