From b1d3f918fb96c50d3ed07bf1b3c6043d7541820f Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Sat, 11 Apr 2015 13:07:59 +0300 Subject: [PATCH] rbd: allow unmapping by spec Make use of krbd_unmap_by_spec() and allow unmapping by (i.e. pool/image@snap spec) with a bunch of careful adjustments to the fragile command args/options parsing process to make --pool, --image and --snap options work as expected for rbd unmap case. Signed-off-by: Ilya Dryomov --- doc/man/8/rbd.rst | 2 +- src/rbd.cc | 33 +++++++++++++++++++----------- src/test/cli/rbd/help.t | 2 +- src/test/cli/rbd/not-enough-args.t | 2 +- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/doc/man/8/rbd.rst b/doc/man/8/rbd.rst index 162c6b16dda3..06158ce3c555 100644 --- a/doc/man/8/rbd.rst +++ b/doc/man/8/rbd.rst @@ -291,7 +291,7 @@ Commands :command:`map` [*image-name*] [-o | --options *map-options* ] [--read-only] Maps the specified image to a block device via the rbd kernel module. -:command:`unmap` [*device-path*] +:command:`unmap` [*image-name*] | [*device-path*] Unmaps the block device that was mapped via the rbd kernel module. :command:`showmapped` diff --git a/src/rbd.cc b/src/rbd.cc index d12dcd45715d..3c192f98f2e7 100644 --- a/src/rbd.cc +++ b/src/rbd.cc @@ -137,7 +137,7 @@ void usage() " status show the status of this image\n" " map map image to a block device\n" " using the kernel\n" -" unmap unmap a rbd device that was\n" +" unmap | unmap a rbd device that was\n" " mapped by the kernel\n" " showmapped show the rbd images mapped\n" " by the kernel\n" @@ -2425,7 +2425,8 @@ static int do_kernel_showmapped(Formatter *f) return r; } -static int do_kernel_unmap(const char *dev) +static int do_kernel_unmap(const char *dev, const char *poolname, + const char *imgname, const char *snapname) { struct krbd_ctx *krbd; int r; @@ -2434,7 +2435,10 @@ static int do_kernel_unmap(const char *dev) if (r < 0) return r; - r = krbd_unmap(krbd, dev); + if (dev) + r = krbd_unmap(krbd, dev); + else + r = krbd_unmap_by_spec(krbd, poolname, imgname, snapname); krbd_destroy(krbd); return r; @@ -2969,6 +2973,7 @@ if (!set_conf_param(v, p1, p2, p3)) { \ case OPT_WATCH: case OPT_STATUS: case OPT_MAP: + case OPT_UNMAP: case OPT_BENCH_WRITE: case OPT_LOCK_LIST: case OPT_METADATA_LIST: @@ -2976,9 +2981,6 @@ if (!set_conf_param(v, p1, p2, p3)) { \ case OPT_OBJECT_MAP_REBUILD: SET_CONF_PARAM(v, &imgname, NULL, NULL); break; - case OPT_UNMAP: - SET_CONF_PARAM(v, &devpath, NULL, NULL); - break; case OPT_EXPORT: case OPT_EXPORT_DIFF: SET_CONF_PARAM(v, &imgname, &path, NULL); @@ -3105,7 +3107,7 @@ if (!set_conf_param(v, p1, p2, p3)) { \ if (opt_cmd != OPT_LIST && opt_cmd != OPT_IMPORT && opt_cmd != OPT_IMPORT_DIFF && - opt_cmd != OPT_UNMAP && + opt_cmd != OPT_UNMAP && /* needs imgname but handled below */ opt_cmd != OPT_SHOWMAPPED && opt_cmd != OPT_MERGE_DIFF && !imgname) { cerr << "rbd: image name was not specified" << std::endl; @@ -3126,9 +3128,16 @@ if (!set_conf_param(v, p1, p2, p3)) { \ } } - if (opt_cmd == OPT_UNMAP && !devpath) { - cerr << "rbd: device path was not specified" << std::endl; - return EXIT_FAILURE; + if (opt_cmd == OPT_UNMAP) { + if (!imgname) { + cerr << "rbd: unmap requires either image name or device path" << std::endl; + return EXIT_FAILURE; + } + + if (strncmp(imgname, "/dev/", 5) == 0) { + devpath = imgname; + imgname = NULL; + } } if (opt_cmd == OPT_FEATURE_DISABLE || opt_cmd == OPT_FEATURE_ENABLE) { @@ -3157,7 +3166,7 @@ if (!set_conf_param(v, p1, p2, p3)) { \ opt_cmd != OPT_SNAP_REMOVE && opt_cmd != OPT_INFO && opt_cmd != OPT_EXPORT && opt_cmd != OPT_EXPORT_DIFF && opt_cmd != OPT_DIFF && opt_cmd != OPT_COPY && - opt_cmd != OPT_MAP && opt_cmd != OPT_CLONE && + opt_cmd != OPT_MAP && opt_cmd != OPT_UNMAP && opt_cmd != OPT_CLONE && opt_cmd != OPT_SNAP_PROTECT && opt_cmd != OPT_SNAP_UNPROTECT && opt_cmd != OPT_CHILDREN && opt_cmd != OPT_OBJECT_MAP_REBUILD) { cerr << "rbd: snapname specified for a command that doesn't use it" @@ -3627,7 +3636,7 @@ if (!set_conf_param(v, p1, p2, p3)) { \ break; case OPT_UNMAP: - r = do_kernel_unmap(devpath); + r = do_kernel_unmap(devpath, poolname, imgname, snapname); if (r < 0) { cerr << "rbd: unmap failed: " << cpp_strerror(-r) << std::endl; return -r; diff --git a/src/test/cli/rbd/help.t b/src/test/cli/rbd/help.t index b51d0137a07a..d0e37f175979 100644 --- a/src/test/cli/rbd/help.t +++ b/src/test/cli/rbd/help.t @@ -50,7 +50,7 @@ status show the status of this image map map image to a block device using the kernel - unmap unmap a rbd device that was + unmap | unmap a rbd device that was mapped by the kernel showmapped show the rbd images mapped by the kernel diff --git a/src/test/cli/rbd/not-enough-args.t b/src/test/cli/rbd/not-enough-args.t index 40fe0d12468a..958f5c2b6dda 100644 --- a/src/test/cli/rbd/not-enough-args.t +++ b/src/test/cli/rbd/not-enough-args.t @@ -2,7 +2,7 @@ rbd: image name was not specified [1] $ rbd unmap - rbd: device path was not specified + rbd: unmap requires either image name or device path [1] $ rbd clone foo@snap bar@snap rbd: cannot clone to a snapshot -- 2.47.3