]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: unified way to map images using different drivers 19711/head
authorMykola Golub <mgolub@suse.com>
Thu, 28 Dec 2017 16:53:46 +0000 (18:53 +0200)
committerMykola Golub <mgolub@suse.com>
Mon, 29 Jan 2018 07:34:11 +0000 (09:34 +0200)
Instead of "rbd map|unmap|showmapped", "rbd ndb map|unmap|list",
"rbd ggate map|unmap|list" commands, provide:

 rbd device -t krbd|nbd|ggate|... map|unmap|list

which gives interface consistent between drivers.

Signed-off-by: Mykola Golub <mgolub@suse.com>
17 files changed:
doc/man/8/rbd.rst
doc/rbd/rbd-ko.rst
qa/tasks/rbd_fio.py
qa/workunits/rbd/kernel.sh
src/init-rbdmap
src/ocf/rbd.in
src/rbdmap
src/stop.sh
src/test/cli-integration/rbd/unmap.t
src/test/cli/rbd/help.t
src/test/cli/rbd/not-enough-args.t
src/test/cli/rbd/too-many-args.t
src/tools/rbd/CMakeLists.txt
src/tools/rbd/action/Device.cc [new file with mode: 0644]
src/tools/rbd/action/Ggate.cc
src/tools/rbd/action/Kernel.cc
src/tools/rbd/action/Nbd.cc

index 3096d234e70f798a6baeef84009470e0f61030eb..13b67ecc5ebc0757760e9d8e877f93e2c672a370 100644 (file)
@@ -205,6 +205,25 @@ Commands
   Deep copy the content of a src-image into the newly created dest-image.
   Dest-image will have the same size, object size, image format, and snapshots as src-image.
 
+:command:`device list` [-t | --device-type *device-type*] [--format plain | json | xml] --pretty-format
+  Show the rbd images that are mapped via the rbd kernel module
+  (default) or other supported device.
+
+:command:`device map` [-t | --device-type *device-type*] [--read-only] [--exclusive] [-o | --options *device-options*] *image-spec* | *snap-spec*
+  Map the specified image to a block device via the rbd kernel module
+  (default) or other supported device (*nbd* on Linux or *ggate* on
+  FreeBSD).
+
+  The --options argument is a comma separated list of device type
+  specific options (opt1,opt2=val,...).
+
+:command:`device unmap` [-t | --device-type *device-type*] [-o | --options *device-options*] *image-spec* | *snap-spec* | *device-path*
+  Unmap the block device that was mapped via the rbd kernel module
+  (default) or other supported device.
+
+  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
@@ -347,9 +366,6 @@ Commands
   -l, also show snapshots, and use longer-format output including
   size, parent (if clone), format, etc.
 
-:command:`map` [-o | --options *krbd-options* ] [--read-only] *image-spec* | *snap-spec*
-  Map the specified image to a block device via the rbd kernel module.
-
 :command:`merge-diff` *first-diff-path* *second-diff-path* *merged-diff-path*
   Merge two continuous incremental diffs of an image into one single diff. The
   first diff's end snapshot must be equal with the second diff's start snapshot.
@@ -437,15 +453,6 @@ Commands
 :command:`mv` *src-image-spec* *dest-image-spec*
   Rename an image.  Note: rename across pools is not supported.
 
-:command:`nbd ls`
-  Show the list of used nbd devices via the rbd-nbd tool.
-
-:command:`nbd map` [--device *device-path*] [--read-only] *image-spec* | *snap-spec*
-  Map the specified image to a block device via the rbd-nbd tool.
-
-:command:`nbd unmap` *device-path*
-  Unmap the block device that was mapped via the rbd-nbd tool.
-
 :command:`object-map check` *image-spec* | *snap-spec*
   Verify the object map is correct.
 
@@ -465,9 +472,6 @@ Commands
   Delete an rbd image (including all data blocks). If the image has
   snapshots, this fails and nothing is deleted.
 
-:command:`showmapped`
-  Show the rbd images that are mapped via the rbd kernel module.
-
 :command:`snap create` *snap-spec*
   Create a new snapshot. Requires the snapshot name parameter specified.
 
@@ -528,9 +532,6 @@ Commands
   you can not removed it unless use force. But an actively in-use by clones 
   or has snapshots can not be removed.
 
-:command:`unmap` [-o | --options *krbd-options* ] *image-spec* | *snap-spec* | *device-path*
-  Unmap the block device that was mapped via the rbd kernel module.
-
 :command:`watch` *image-spec*
   Watch events on image.
 
@@ -589,7 +590,7 @@ Most of these options are useful mainly for debugging and benchmarking.  The
 default values are set in the kernel and may therefore depend on the version of
 the running kernel.
 
-Per client instance `rbd map` options:
+Per client instance `rbd device map` options:
 
 * fsid=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee - FSID that should be assumed by
   the client.
@@ -619,16 +620,16 @@ Per client instance `rbd map` options:
 
 * nocephx_sign_messages - Disable message signing (since 4.4).
 
-* mount_timeout=x - A timeout on various steps in `rbd map` and `rbd unmap`
-  sequences (default is 60 seconds).  In particular, since 4.2 this can be used
-  to ensure that `rbd unmap` eventually times out when there is no network
-  connection to a cluster.
+* mount_timeout=x - A timeout on various steps in `rbd device map` and
+  `rbd device unmap` sequences (default is 60 seconds).  In particular,
+  since 4.2 this can be used to ensure that `rbd device unmap` eventually
+  times out when there is no network connection to a cluster.
 
 * osdkeepalive=x - OSD keepalive timeout (default is 5 seconds).
 
 * osd_idle_ttl=x - OSD idle TTL (default is 60 seconds).
 
-Per mapping (block device) `rbd map` options:
+Per mapping (block device) `rbd device map` options:
 
 * rw - Map the image read-write (default).
 
@@ -641,7 +642,7 @@ Per mapping (block device) `rbd map` options:
 
 * exclusive - Disable automatic exclusive lock transitions (since 4.12).
 
-`rbd unmap` options:
+`rbd device unmap` options:
 
 * force - Force the unmapping of a block device that is open (since 4.9).  The
   driver will wait for running requests to complete and then unmap; requests
@@ -681,15 +682,15 @@ To delete a snapshot::
 
 To map an image via the kernel with cephx enabled::
 
-       rbd map mypool/myimage --id admin --keyfile secretfile
+       rbd device map mypool/myimage --id admin --keyfile secretfile
 
 To map an image via the kernel with different cluster name other than default *ceph*::
 
-       rbd map mypool/myimage --cluster cluster-name
+       rbd device map mypool/myimage --cluster cluster-name
 
 To unmap an image::
 
-       rbd unmap /dev/rbd0
+       rbd device unmap /dev/rbd0
 
 To create an image and a clone from it::
 
index 951757c78179569db138c0cf093e23bf1daee30b..70c4078391ca43c4d5168652d5cdce353573c4a4 100644 (file)
@@ -20,40 +20,40 @@ Use ``rbd`` to map an image name to a kernel module. You must specify the
 image name, the pool name, and the user name. ``rbd`` will load RBD kernel
 module on your behalf if it's not already loaded. ::
 
-  sudo rbd map {pool-name}/{image-name} --id {user-name}
+  sudo rbd device map {pool-name}/{image-name} --id {user-name}
 
 For example:: 
 
-  sudo rbd map rbd/myimage --id admin
+  sudo rbd device map rbd/myimage --id admin
  
 If you use `cephx`_ authentication, you must also specify a secret.  It may come
 from a keyring or a file containing the secret. ::
 
-  sudo rbd map rbd/myimage --id admin --keyring /path/to/keyring
-  sudo rbd map rbd/myimage --id admin --keyfile /path/to/file
+  sudo rbd device map rbd/myimage --id admin --keyring /path/to/keyring
+  sudo rbd device map rbd/myimage --id admin --keyfile /path/to/file
 
 
 Show Mapped Block Devices
 =========================
 
-To show block device images mapped to kernel modules with the ``rbd`` command,
-specify the ``showmapped`` option. ::
+To show block device images mapped to kernel modules with the ``rbd``,
+specify ``device list`` arguments. ::
 
-       rbd showmapped
+       rbd device list
 
 
 Unmapping a Block Device
-========================       
+========================
 
-To unmap a block device image with the ``rbd`` command, specify the ``unmap``
-option  and the device name (i.e., by convention the same as the block device
-image name). :: 
+To unmap a block device image with the ``rbd`` command, specify the
+``device unmap`` arguments and the device name (i.e., by convention the
+same as the block device image name). :: 
+
+       sudo rbd device unmap /dev/rbd/{poolname}/{imagename}
 
-       sudo rbd unmap /dev/rbd/{poolname}/{imagename}
-       
 For example::
 
-       sudo rbd unmap /dev/rbd/rbd/foo
+       sudo rbd device unmap /dev/rbd/rbd/foo
 
 
 .. _cephx: ../../rados/operations/user-management/
index bbd6ce0c6e913e57832b6d353ba1a068d9a8ecf5..1d153a26420316f942f42e732b14de3ec8bf75a4 100644 (file)
@@ -78,7 +78,8 @@ def get_ioengine_package_name(ioengine, remote):
 def run_rbd_map(remote, image, iodepth):
     iodepth = max(iodepth, 128)  # RBD_QUEUE_DEPTH_DEFAULT
     out = StringIO.StringIO()
-    remote.run(args=['sudo', 'rbd', 'map', '-o', 'queue_depth={}'.format(iodepth), image], stdout=out)
+    remote.run(args=['sudo', 'rbd', 'device', 'map', '-o',
+                     'queue_depth={}'.format(iodepth), image], stdout=out)
     dev = out.getvalue().rstrip('\n')
     teuthology.sudo_write_file(
         remote,
@@ -214,12 +215,13 @@ def run_fio(remote, config, rbd_test_dir):
         remote.run(args=['ceph', '-s'])
     finally:
         out=StringIO.StringIO()
-        remote.run(args=['rbd','showmapped', '--format=json'], stdout=out)
+        remote.run(args=['rbd', 'device', 'list', '--format=json'], stdout=out)
         mapped_images = json.loads(out.getvalue())
         if mapped_images:
             log.info("Unmapping rbd images on {sn}".format(sn=sn))
             for image in mapped_images:
-                remote.run(args=['sudo', 'rbd', 'unmap', str(image['device'])])
+                remote.run(args=['sudo', 'rbd', 'device', 'unmap',
+                                 str(image['device'])])
         log.info("Cleaning up fio install")
         remote.run(args=['rm','-rf', run.Raw(rbd_test_dir)])
         if ioengine_pkg:
index 735396b3f3191830e2eda8975d2de6e28d704c76..f733b93c10f23a30af8263bb37a541ea3872e35f 100755 (executable)
@@ -14,14 +14,15 @@ function get_device_dir {
        local POOL=$1
        local IMAGE=$2
        local SNAP=$3
-       rbd showmapped | tail -n +2 | egrep "\s+$POOL\s+$IMAGE\s+$SNAP\s+" | awk '{print $1;}'
+       rbd device list | tail -n +2 | egrep "\s+$POOL\s+$IMAGE\s+$SNAP\s+" |
+           awk '{print $1;}'
 }
 
 function clean_up {
        [ -e /dev/rbd/rbd/testimg1@snap1 ] &&
-               sudo rbd unmap /dev/rbd/rbd/testimg1@snap1
+               sudo rbd device unmap /dev/rbd/rbd/testimg1@snap1
        if [ -e /dev/rbd/rbd/testimg1 ]; then
-               sudo rbd unmap /dev/rbd/rbd/testimg1
+               sudo rbd device unmap /dev/rbd/rbd/testimg1
                rbd snap purge testimg1 || true
        fi
        rbd ls | grep testimg1 > /dev/null && rbd rm testimg1 || true
@@ -42,7 +43,7 @@ dd if=/dev/zero of=/tmp/img1 count=0 seek=150000
 
 # import
 rbd import /tmp/img1 testimg1
-sudo rbd map testimg1 --user $CEPH_ID $SECRET_ARGS
+sudo rbd device map testimg1 --user $CEPH_ID $SECRET_ARGS
 
 DEV_ID1=$(get_device_dir rbd testimg1 -)
 echo "dev_id1 = $DEV_ID1"
@@ -54,7 +55,7 @@ cmp /tmp/img1 /tmp/img1.export
 
 # snapshot
 rbd snap create testimg1 --snap=snap1
-sudo rbd map --snap=snap1 testimg1 --user $CEPH_ID $SECRET_ARGS
+sudo rbd device map --snap=snap1 testimg1 --user $CEPH_ID $SECRET_ARGS
 
 DEV_ID2=$(get_device_dir rbd testimg1 snap1)
 cat /sys/bus/rbd/devices/$DEV_ID2/size | grep 76800000
index bc79f587fb923b70f98e6e55798c514abd1530f1..6058e397e405ae7b7bcfb722941cecdb20be263c 100755 (executable)
@@ -29,11 +29,11 @@ fi
 
 case "$1" in
   start)
-       rbdmap map
+       rbdmap device map
        ;;
 
   stop)
-       rbdmap unmap
+       rbdmap device unmap
        ;;
 
   restart|force-reload)
@@ -42,11 +42,11 @@ case "$1" in
        ;;
 
   reload)
-       rbdmap map
+       rbdmap device map
        ;;
 
   status)
-       rbd showmapped
+       rbd device list
        ;;
 
   *)
index 150ad6e6b21b50dff969886ed0881ea9e96c5bc0..aab376440c24f92b9937721f335ba295d3ff0c6f 100644 (file)
@@ -123,12 +123,12 @@ do_rbd() {
     ocf_run rbd $rbd_options $@
 }
 
-# Convenience function that uses "rbd showmapped" to retrieve the
+# Convenience function that uses "rbd device list" to retrieve the
 # mapped device name from the pool, RBD name, and snapshot.
 find_rbd_dev() {
     local sedpat
 
-    # Example output from "rbd showmapped" (tab separated):
+    # Example output from "rbd device list" (tab separated):
     # id        pool    image   snap    device
     # 0         rbd     test    -       /dev/rbd0
 
@@ -136,9 +136,9 @@ find_rbd_dev() {
     # it's unset
     sedpat="[0-9]\+[ \t]\+${OCF_RESKEY_pool}[ \t]\+${OCF_RESKEY_name}[ \t]\+${OCF_RESKEY_snap:--}[ \t]\+\(/dev/rbd[0-9]\+\).*"
 
-    # Run rbd showmapped, filter out the header line, then try to
+    # Run "rbd device list", filter out the header line, then try to
     # extract the device name
-    rbd showmapped | tail -n +2 | sed -n -e "s,$sedpat,\1,p"
+    rbd device list | tail -n +2 | sed -n -e "s,$sedpat,\1,p"
 }
 
 rbd_validate_all() {
@@ -211,7 +211,7 @@ rbd_start() {
         rbd_name="$rbd_name@${OCF_RESKEY_snap}"
     fi
 
-    do_rbd map $rbd_name $rbd_map_options || exit $OCF_ERR_GENERIC
+    do_rbd device map $rbd_name $rbd_map_options || exit $OCF_ERR_GENERIC
 
     # After the resource has been started, check whether it started up
     # correctly. If the resource starts asynchronously, the agent may
@@ -249,7 +249,7 @@ rbd_stop() {
     # exit with an $OCF_ERR_ error code if anything goes seriously
     # wrong)
     rbd_dev=`find_rbd_dev`
-    do_rbd unmap $rbd_dev || exit $OCF_ERR_GENERIC
+    do_rbd device unmap $rbd_dev || exit $OCF_ERR_GENERIC
 
     # After the resource has been stopped, check whether it shut down
     # correctly. If the resource stops asynchronously, the agent may
index f4503ab9d60247bf75bd3616e98dccce5c7690a6..2b13517491f2c54331d8d62ea5e3ad7c096e54e4 100755 (executable)
@@ -27,7 +27,7 @@ do_map() {
                if [ -b /dev/rbd/$DEV ]; then
                        MAP_RV="$(readlink -f /dev/rbd/$DEV)"
                else
-                       MAP_RV="$(rbd map $DEV $CMDPARAMS 2>&1)"
+                       MAP_RV="$(rbd device map $DEV $CMDPARAMS 2>&1)"
                        if [ $? -eq 0 ]; then
                            newrbd="yes"
                        else
@@ -72,7 +72,7 @@ unmount_unmap() {
            fi
        done
        ## Un-mapping.
-       rbd unmap $rbd_dev >>/dev/null 2>&1
+       rbd device unmap $rbd_dev >>/dev/null 2>&1
        if [ $? -ne 0 ]; then
            logger -p "daemon.warning" -t rbdmap "Failed to unmap '${mnt}'"
            return 1
index 0eafe018559e345033ecb9a85633c54abc5e8344..7838c53144456eb1484be451e0ecdf9e3b3c60f8 100755 (executable)
@@ -73,8 +73,8 @@ while [ $# -ge 1 ]; do
 done
 
 if [ $stop_all -eq 1 ]; then
-    if "${CEPH_BIN}"/rbd showmapped >/dev/null 2>&1; then
-        "${CEPH_BIN}"/rbd showmapped | tail -n +2 |
+    if "${CEPH_BIN}"/rbd device list >/dev/null 2>&1; then
+        "${CEPH_BIN}"/rbd device list | tail -n +2 |
         while read DEV; do
             # While it is currently possible to create an rbd image with
             # whitespace chars in its name, krbd will refuse mapping such
@@ -82,10 +82,10 @@ if [ $stop_all -eq 1 ]; then
             # same goes for whitespace chars in names of the pools that
             # contain rbd images).
             DEV="$(echo "${DEV}" | tr -s '[:space:]' | awk '{ print $5 }')"
-            sudo "${CEPH_BIN}"/rbd unmap "${DEV}"
+            sudo "${CEPH_BIN}"/rbd device unmap "${DEV}"
         done
 
-        if [ -n "$("${CEPH_BIN}"/rbd showmapped)" ]; then
+        if [ -n "$("${CEPH_BIN}"/rbd device list)" ]; then
             echo "WARNING: Some rbd images are still mapped!" >&2
         fi
     fi
index df64b09441c44f91840309b55b7cdc4f0eccd95c..b52a16db0f4ffb4150aa409d51ea6da9d0cdb03f 100644 (file)
@@ -13,7 +13,7 @@ Setup
 
 Spell out device instead of using $DEV - sfdisk is not a joke.
 
-  $ DEV=$(sudo rbd map img)
+  $ DEV=$(sudo rbd device map img)
   $ cat <<EOF | sudo sfdisk /dev/rbd[01] >/dev/null 2>&1
   > unit: sectors
   > /dev/rbd0p1 : start=        2, size=        2, Id=83
@@ -29,48 +29,48 @@ Unmap by device
 
 Unmap by device (img is already mapped):
 
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   -    /dev/rbd?  (glob)
-  $ sudo rbd unmap $DEV
-  $ rbd showmapped
+  $ sudo rbd device unmap $DEV
+  $ rbd device list
 
 Unmap by device partition:
 
-  $ DEV=$(sudo rbd map img)
-  $ rbd showmapped
+  $ DEV=$(sudo rbd device map img)
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   -    /dev/rbd?  (glob)
-  $ sudo rbd unmap ${DEV}p1
-  $ rbd showmapped
+  $ sudo rbd device unmap ${DEV}p1
+  $ rbd device list
 
-  $ DEV=$(sudo rbd map img)
-  $ rbd showmapped
+  $ DEV=$(sudo rbd device map img)
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   -    /dev/rbd?  (glob)
-  $ sudo rbd unmap ${DEV}p5
-  $ rbd showmapped
+  $ sudo rbd device unmap ${DEV}p5
+  $ rbd device list
 
 Not a block device - random junk prefixed with /dev/ (so it's not
 interpreted as a spec):
 
-  $ sudo rbd unmap /dev/foobar
+  $ sudo rbd device unmap /dev/foobar
   rbd: '/dev/foobar' is not a block device
   rbd: unmap failed: (22) Invalid argument
   [22]
 
 Not a block device - device that's just been unmapped:
 
-  $ DEV=$(sudo rbd map img)
-  $ sudo rbd unmap $DEV
-  $ sudo rbd unmap $DEV
+  $ DEV=$(sudo rbd device map img)
+  $ sudo rbd device unmap $DEV
+  $ sudo rbd device unmap $DEV
   rbd: '/dev/rbd?' is not a block device (glob)
   rbd: unmap failed: (22) Invalid argument
   [22]
 
 A block device, but not rbd:
 
-  $ sudo rbd unmap /dev/[sv]da
+  $ sudo rbd device unmap /dev/[sv]da
   rbd: '/dev/?da' is not an rbd device (glob)
   rbd: unmap failed: (22) Invalid argument
   [22]
@@ -81,149 +81,149 @@ Unmap by spec
 
 img:
 
-  $ sudo rbd map img
+  $ sudo rbd device map img
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   -    /dev/rbd?  (glob)
-  $ sudo rbd unmap img
-  $ rbd showmapped
+  $ sudo rbd device unmap img
+  $ rbd device list
 
-  $ sudo rbd map img
+  $ sudo rbd device map img
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   -    /dev/rbd?  (glob)
-  $ sudo rbd --image img unmap
-  $ rbd showmapped
+  $ sudo rbd --image img device unmap
+  $ rbd device list
 
 img@snap:
 
-  $ sudo rbd map img@snap
+  $ sudo rbd device map img@snap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap img@snap
-  $ rbd showmapped
+  $ sudo rbd device unmap img@snap
+  $ rbd device list
 
-  $ sudo rbd map img@snap
+  $ sudo rbd device map img@snap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd --snap snap unmap img
-  $ rbd showmapped
+  $ sudo rbd --snap snap device unmap img
+  $ rbd device list
 
-  $ sudo rbd map img@snap
+  $ sudo rbd device map img@snap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd --image img --snap snap unmap
-  $ rbd showmapped
+  $ sudo rbd --image img --snap snap device unmap
+  $ rbd device list
 
 pool/img@snap, default pool:
 
-  $ sudo rbd map rbd/img@snap
+  $ sudo rbd device map rbd/img@snap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap rbd/img@snap
-  $ rbd showmapped
+  $ sudo rbd device unmap rbd/img@snap
+  $ rbd device list
 
-  $ sudo rbd map rbd/img@snap
+  $ sudo rbd device map rbd/img@snap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd --pool rbd unmap img@snap
-  $ rbd showmapped
+  $ sudo rbd --pool rbd device unmap img@snap
+  $ rbd device list
 
-  $ sudo rbd map rbd/img@snap
+  $ sudo rbd device map rbd/img@snap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd --pool rbd --snap snap unmap img
-  $ rbd showmapped
+  $ sudo rbd --pool rbd --snap snap device unmap img
+  $ rbd device list
 
-  $ sudo rbd map rbd/img@snap
+  $ sudo rbd device map rbd/img@snap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd --pool rbd --image img --snap snap unmap
-  $ rbd showmapped
+  $ sudo rbd --pool rbd --image img --snap snap device unmap
+  $ rbd device list
 
 pool/img@snap, custom pool:
 
-  $ sudo rbd map custom/img@snap
+  $ sudo rbd device map custom/img@snap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool   image snap device    
   ?  custom img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap custom/img@snap
-  $ rbd showmapped
+  $ sudo rbd device unmap custom/img@snap
+  $ rbd device list
 
-  $ sudo rbd map custom/img@snap
+  $ sudo rbd device map custom/img@snap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool   image snap device    
   ?  custom img   snap /dev/rbd?  (glob)
-  $ sudo rbd --pool custom unmap img@snap
-  $ rbd showmapped
+  $ sudo rbd --pool custom device unmap img@snap
+  $ rbd device list
 
-  $ sudo rbd map custom/img@snap
+  $ sudo rbd device map custom/img@snap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool   image snap device    
   ?  custom img   snap /dev/rbd?  (glob)
-  $ sudo rbd --pool custom --snap snap unmap img
-  $ rbd showmapped
+  $ sudo rbd --pool custom --snap snap device unmap img
+  $ rbd device list
 
-  $ sudo rbd map custom/img@snap
+  $ sudo rbd device map custom/img@snap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool   image snap device    
   ?  custom img   snap /dev/rbd?  (glob)
-  $ sudo rbd --pool custom --image img --snap snap unmap
-  $ rbd showmapped
+  $ sudo rbd --pool custom --image img --snap snap device unmap
+  $ rbd device list
 
 Not a mapped spec - random junk (which gets interpreted as a spec):
 
-  $ sudo rbd unmap foobar
+  $ sudo rbd device unmap foobar
   rbd: rbd/foobar@-: not a mapped image or snapshot
   rbd: unmap failed: (22) Invalid argument
   [22]
 
-  $ sudo rbd --image foobar unmap
+  $ sudo rbd --image foobar device unmap
   rbd: rbd/foobar@-: not a mapped image or snapshot
   rbd: unmap failed: (22) Invalid argument
   [22]
 
 Not a mapped spec - spec that's just been unmapped:
 
-  $ sudo rbd map img
+  $ sudo rbd device map img
   /dev/rbd? (glob)
-  $ sudo rbd unmap img
-  $ sudo rbd unmap img
+  $ sudo rbd device unmap img
+  $ sudo rbd device unmap img
   rbd: rbd/img@-: not a mapped image or snapshot
   rbd: unmap failed: (22) Invalid argument
   [22]
 
-  $ sudo rbd map img@snap
+  $ sudo rbd device map img@snap
   /dev/rbd? (glob)
-  $ sudo rbd unmap img@snap
-  $ sudo rbd unmap img@snap
+  $ sudo rbd device unmap img@snap
+  $ sudo rbd device unmap img@snap
   rbd: rbd/img@snap: not a mapped image or snapshot
   rbd: unmap failed: (22) Invalid argument
   [22]
 
 Need an arg:
 
-  $ sudo rbd unmap
+  $ sudo rbd device unmap
   rbd: unmap requires either image name or device path
   [22]
 
@@ -233,37 +233,37 @@ Two images
 
 Unmap img first:
 
-  $ sudo rbd map img
+  $ sudo rbd device map img
   /dev/rbd? (glob)
-  $ sudo rbd map anotherimg
+  $ sudo rbd device map anotherimg
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image      snap device    
   ?  rbd  img        -    /dev/rbd?  (glob)
   ?  rbd  anotherimg -    /dev/rbd?  (glob)
-  $ sudo rbd unmap img
-  $ rbd showmapped
+  $ sudo rbd device unmap img
+  $ rbd device list
   id pool image      snap device    
   ?  rbd  anotherimg -    /dev/rbd?  (glob)
-  $ sudo rbd unmap anotherimg
-  $ rbd showmapped
+  $ sudo rbd device unmap anotherimg
+  $ rbd device list
 
 Unmap anotherimg first:
 
-  $ sudo rbd map img
+  $ sudo rbd device map img
   /dev/rbd? (glob)
-  $ sudo rbd map anotherimg
+  $ sudo rbd device map anotherimg
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image      snap device    
   ?  rbd  img        -    /dev/rbd?  (glob)
   ?  rbd  anotherimg -    /dev/rbd?  (glob)
-  $ sudo rbd unmap anotherimg
-  $ rbd showmapped
+  $ sudo rbd device unmap anotherimg
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   -    /dev/rbd?  (glob)
-  $ sudo rbd unmap img
-  $ rbd showmapped
+  $ sudo rbd device unmap img
+  $ rbd device list
 
 
 Image and its snap
@@ -271,37 +271,37 @@ Image and its snap
 
 Unmap the image first:
 
-  $ sudo rbd map img
+  $ sudo rbd device map img
   /dev/rbd? (glob)
-  $ sudo rbd map img@snap
+  $ sudo rbd device map img@snap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   -    /dev/rbd?  (glob)
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap img
-  $ rbd showmapped
+  $ sudo rbd device unmap img
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap img@snap
-  $ rbd showmapped
+  $ sudo rbd device unmap img@snap
+  $ rbd device list
 
 Unmap the snap first:
 
-  $ sudo rbd map img
+  $ sudo rbd device map img
   /dev/rbd? (glob)
-  $ sudo rbd map img@snap
+  $ sudo rbd device map img@snap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   -    /dev/rbd?  (glob)
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap img@snap
-  $ rbd showmapped
+  $ sudo rbd device unmap img@snap
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   -    /dev/rbd?  (glob)
-  $ sudo rbd unmap img
-  $ rbd showmapped
+  $ sudo rbd device unmap img
+  $ rbd device list
 
 
 Two snaps of the same image
@@ -309,37 +309,37 @@ Two snaps of the same image
 
 Unmap snap first:
 
-  $ sudo rbd map custom/img@snap
+  $ sudo rbd device map custom/img@snap
   /dev/rbd? (glob)
-  $ sudo rbd map custom/img@anothersnap
+  $ sudo rbd device map custom/img@anothersnap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool   image snap        device    
   ?  custom img   snap        /dev/rbd?  (glob)
   ?  custom img   anothersnap /dev/rbd?  (glob)
-  $ sudo rbd unmap custom/img@snap
-  $ rbd showmapped
+  $ sudo rbd device unmap custom/img@snap
+  $ rbd device list
   id pool   image snap        device    
   ?  custom img   anothersnap /dev/rbd?  (glob)
-  $ sudo rbd unmap custom/img@anothersnap
-  $ rbd showmapped
+  $ sudo rbd device unmap custom/img@anothersnap
+  $ rbd device list
 
 Unmap anothersnap first:
 
-  $ sudo rbd map custom/img@snap
+  $ sudo rbd device map custom/img@snap
   /dev/rbd? (glob)
-  $ sudo rbd map custom/img@anothersnap
+  $ sudo rbd device map custom/img@anothersnap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool   image snap        device    
   ?  custom img   snap        /dev/rbd?  (glob)
   ?  custom img   anothersnap /dev/rbd?  (glob)
-  $ sudo rbd unmap custom/img@anothersnap
-  $ rbd showmapped
+  $ sudo rbd device unmap custom/img@anothersnap
+  $ rbd device list
   id pool   image snap device    
   ?  custom img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap custom/img@snap
-  $ rbd showmapped
+  $ sudo rbd device unmap custom/img@snap
+  $ rbd device list
 
 
 Same img and snap in different pools
@@ -347,37 +347,37 @@ Same img and snap in different pools
 
 img:
 
-  $ sudo rbd map img
+  $ sudo rbd device map img
   /dev/rbd? (glob)
-  $ sudo rbd map custom/img
+  $ sudo rbd device map custom/img
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool   image snap device    
   ?  rbd    img   -    /dev/rbd?  (glob)
   ?  custom img   -    /dev/rbd?  (glob)
-  $ sudo rbd unmap img
-  $ rbd showmapped
+  $ sudo rbd device unmap img
+  $ rbd device list
   id pool   image snap device    
   ?  custom img   -    /dev/rbd?  (glob)
-  $ sudo rbd unmap custom/img
-  $ rbd showmapped
+  $ sudo rbd device unmap custom/img
+  $ rbd device list
 
 img@snap:
 
-  $ sudo rbd map img@snap
+  $ sudo rbd device map img@snap
   /dev/rbd? (glob)
-  $ sudo rbd map custom/img@snap
+  $ sudo rbd device map custom/img@snap
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool   image snap device    
   ?  rbd    img   snap /dev/rbd?  (glob)
   ?  custom img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap custom/img@snap
-  $ rbd showmapped
+  $ sudo rbd device unmap custom/img@snap
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap img@snap
-  $ rbd showmapped
+  $ sudo rbd device unmap img@snap
+  $ rbd device list
 
 
 Same spec mapped twice
@@ -385,79 +385,79 @@ Same spec mapped twice
 
 img:
 
-  $ sudo rbd map img
+  $ sudo rbd device map img
   /dev/rbd? (glob)
-  $ sudo rbd map img
+  $ sudo rbd device map img
   rbd: warning: image already mapped as /dev/rbd? (glob)
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   -    /dev/rbd?  (glob)
   ?  rbd  img   -    /dev/rbd?  (glob)
-  $ sudo rbd unmap img
+  $ sudo rbd device unmap img
   rbd: rbd/img@-: mapped more than once, unmapping /dev/rbd? only (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   -    /dev/rbd?  (glob)
-  $ sudo rbd unmap img
-  $ rbd showmapped
+  $ sudo rbd device unmap img
+  $ rbd device list
 
 img@snap:
 
-  $ sudo rbd map img@snap
+  $ sudo rbd device map img@snap
   /dev/rbd? (glob)
-  $ sudo rbd map img@snap
+  $ sudo rbd device map img@snap
   rbd: warning: image already mapped as /dev/rbd? (glob)
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   snap /dev/rbd?  (glob)
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap img@snap
+  $ sudo rbd device unmap img@snap
   rbd: rbd/img@snap: mapped more than once, unmapping /dev/rbd? only (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap img@snap
-  $ rbd showmapped
+  $ sudo rbd device unmap img@snap
+  $ rbd device list
 
 pool/img@snap, default pool:
 
-  $ sudo rbd map rbd/img@snap
+  $ sudo rbd device map rbd/img@snap
   /dev/rbd? (glob)
-  $ sudo rbd map rbd/img@snap
+  $ sudo rbd device map rbd/img@snap
   rbd: warning: image already mapped as /dev/rbd? (glob)
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   snap /dev/rbd?  (glob)
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap rbd/img@snap
+  $ sudo rbd device unmap rbd/img@snap
   rbd: rbd/img@snap: mapped more than once, unmapping /dev/rbd? only (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool image snap device    
   ?  rbd  img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap rbd/img@snap
-  $ rbd showmapped
+  $ sudo rbd device unmap rbd/img@snap
+  $ rbd device list
 
 pool/img@snap, custom pool:
 
-  $ sudo rbd map custom/img@snap
+  $ sudo rbd device map custom/img@snap
   /dev/rbd? (glob)
-  $ sudo rbd map custom/img@snap
+  $ sudo rbd device map custom/img@snap
   rbd: warning: image already mapped as /dev/rbd? (glob)
   /dev/rbd? (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool   image snap device    
   ?  custom img   snap /dev/rbd?  (glob)
   ?  custom img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap custom/img@snap
+  $ sudo rbd device unmap custom/img@snap
   rbd: custom/img@snap: mapped more than once, unmapping /dev/rbd? only (glob)
-  $ rbd showmapped
+  $ rbd device list
   id pool   image snap device    
   ?  custom img   snap /dev/rbd?  (glob)
-  $ sudo rbd unmap custom/img@snap
-  $ rbd showmapped
+  $ sudo rbd device unmap custom/img@snap
+  $ rbd device list
 
 
 Teardown
index 5007698f34d5adb42fbdc54a47ff16c7d40d6911..cf80ac67ec1134a19dc8e22b78ecaaa0a353845b 100644 (file)
@@ -1,7 +1,3 @@
-Skip test on FreeBSD as it generates different output there.
-
-  $ test "$(uname)" = "FreeBSD" && exit 80 || true
-
   $ rbd --help
   usage: rbd <command> ...
   
@@ -15,6 +11,9 @@ Skip test on FreeBSD as it generates different output there.
       copy (cp)                           Copy src image to dest.
       create                              Create an empty image.
       deep copy (deep cp)                 Deep copy src image to dest.
+      device list (showmapped)            List mapped rbd images.
+      device map (map)                    Map an image to a block device.
+      device unmap (unmap)                Unmap a rbd device.
       diff                                Print extents that differ since a
                                           previous snap, or image creation.
       disk-usage (du)                     Show disk usage stats for pool, image
@@ -58,8 +57,6 @@ Skip test on FreeBSD as it generates different output there.
       lock add                            Take a lock on an image.
       lock list (lock ls)                 Show locks held on an image.
       lock remove (lock rm)               Release a lock on an image.
-      map                                 Map image to a block device using the
-                                          kernel.
       merge-diff                          Merge two diff exports together.
       mirror image demote                 Demote an image to non-primary for RBD
                                           mirroring.
@@ -84,17 +81,12 @@ Skip test on FreeBSD as it generates different output there.
                                           pool.
       mirror pool status                  Show status for all mirrored images in
                                           the pool.
-      nbd list (nbd ls)                   List the nbd devices already used.
-      nbd map                             Map image to a nbd device.
-      nbd unmap                           Unmap a nbd device.
       object-map check                    Verify the object map is correct.
       object-map rebuild                  Rebuild an invalid object map.
       pool init                           Initialize pool for use by RBD.
       remove (rm)                         Delete an image.
       rename (mv)                         Rename image within pool.
       resize                              Resize (expand or shrink) image.
-      showmapped                          Show the rbd images mapped by the
-                                          kernel.
       snap create (snap add)              Create a snapshot.
       snap limit clear                    Remove snapshot limit.
       snap limit set                      Limit the number of snapshots.
@@ -111,8 +103,6 @@ Skip test on FreeBSD as it generates different output there.
       trash purge                         Remove all expired images from trash.
       trash remove (trash rm)             Remove an image from trash.
       trash restore                       Restore an image from trash.
-      unmap                               Unmap a rbd device that was used by the
-                                          kernel.
       watch                               Watch events on image.
   
   Optional arguments:
@@ -354,6 +344,57 @@ Skip test on FreeBSD as it generates different output there.
     (-) supports disabling-only on existing images
     (+) enabled by default for new images if features not specified
   
+  rbd help device list
+  usage: rbd device list [--device-type <device-type>] [--format <format>] 
+                         [--pretty-format] 
+  
+  List mapped rbd images.
+  
+  Optional arguments
+    -t [ --device-type ] arg device type [ggate, krbd (default), nbd]
+    --format arg             output format (plain, json, or xml) [default: plain]
+    --pretty-format          pretty formatting (json and xml)
+  
+  rbd help device map
+  usage: rbd device map [--device-type <device-type>] [--pool <pool>] 
+                        [--image <image>] [--snap <snap>] [--read-only] 
+                        [--exclusive] [--options <options>] 
+                        <image-or-snap-spec> 
+  
+  Map an image to a block device.
+  
+  Positional arguments
+    <image-or-snap-spec>     image or snapshot specification
+                             (example: [<pool-name>/]<image-name>[@<snap-name>])
+  
+  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
+    --read-only              map read-only
+    --exclusive              disable automatic exclusive lock transitions
+    -o [ --options ] arg     device specific options
+  
+  rbd help device unmap
+  usage: rbd device unmap [--device-type <device-type>] [--pool <pool>] 
+                          [--image <image>] [--snap <snap>] [--options <options>] 
+                          <image-or-snap-or-device-spec> 
+  
+  Unmap a rbd device.
+  
+  Positional arguments
+    <image-or-snap-or-device-spec>  image, snapshot, or device specification
+                                    [<pool-name>/]<image-name>[@<snapshot-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 diff
   usage: rbd diff [--pool <pool>] [--image <image>] [--snap <snap>] 
                   [--from-snap <from-snap>] [--whole-object] [--format <format>] 
@@ -1005,25 +1046,6 @@ Skip test on FreeBSD as it generates different output there.
     -p [ --pool ] arg    pool name
     --image arg          image name
   
-  rbd help map
-  usage: rbd map [--pool <pool>] [--image <image>] [--snap <snap>] 
-                 [--options <options>] [--read-only] [--exclusive] 
-                 <image-or-snap-spec> 
-  
-  Map image to a block device using the kernel.
-  
-  Positional arguments
-    <image-or-snap-spec>  image or snapshot specification
-                          (example: [<pool-name>/]<image-name>[@<snap-name>])
-  
-  Optional arguments
-    -p [ --pool ] arg     pool name
-    --image arg           image name
-    --snap arg            snapshot name
-    -o [ --options ] arg  map options
-    --read-only           map read-only
-    --exclusive           disable automatic exclusive lock transitions
-  
   rbd help merge-diff
   usage: rbd merge-diff [--path <path>] [--no-progress] 
                         <diff1-path> <diff2-path> <path-name> 
@@ -1255,55 +1277,6 @@ Skip test on FreeBSD as it generates different output there.
     --pretty-format      pretty formatting (json and xml)
     --verbose            be verbose
   
-  rbd help nbd list
-  usage: rbd nbd list [--format <format>] [--pretty-format] 
-  
-  List the nbd devices already used.
-  
-  Optional arguments
-    --format arg         output format (plain, json, or xml) [default: plain]
-    --pretty-format      pretty formatting (json and xml)
-  
-  rbd help nbd map
-  usage: rbd nbd map [--pool <pool>] [--image <image>] [--snap <snap>] 
-                     [--read-only] [--exclusive] [--device <device>] 
-                     [--nbds_max <nbds_max>] [--max_part <max_part>] 
-                     [--timeout <timeout>] 
-                     <image-or-snap-spec> 
-  
-  Map image to a nbd device.
-  
-  Positional arguments
-    <image-or-snap-spec>  image or snapshot specification
-                          (example: [<pool-name>/]<image-name>[@<snap-name>])
-  
-  Optional arguments
-    -p [ --pool ] arg     pool name
-    --image arg           image name
-    --snap arg            snapshot name
-    --read-only           map read-only
-    --exclusive           forbid writes by other clients
-    --device arg          specify nbd device
-    --nbds_max arg        override module param nbds_max
-    --max_part arg        override module param max_part
-    --timeout arg         set nbd request timeout (seconds)
-  
-  rbd help nbd unmap
-  usage: rbd nbd unmap [--pool <pool>] [--image <image>] [--snap <snap>] 
-                       <image-or-snap-or-device-spec> 
-  
-  Unmap a nbd device.
-  
-  Positional arguments
-    <image-or-snap-or-device-spec>  image, snapshot, or device specification
-                                    [<pool-name>/]<image-name>[@<snapshot-name>]
-                                    or <device-path>
-  
-  Optional arguments
-    -p [ --pool ] arg               pool name
-    --image arg                     image name
-    --snap arg                      snapshot name
-  
   rbd help object-map check
   usage: rbd object-map check [--pool <pool>] [--image <image>] [--snap <snap>] 
                               [--no-progress] 
@@ -1404,15 +1377,6 @@ Skip test on FreeBSD as it generates different output there.
     --allow-shrink       permit shrinking
     --no-progress        disable progress output
   
-  rbd help showmapped
-  usage: rbd showmapped [--format <format>] [--pretty-format] 
-  
-  Show the rbd images mapped by the kernel.
-  
-  Optional arguments
-    --format arg         output format (plain, json, or xml) [default: plain]
-    --pretty-format      pretty formatting (json and xml)
-  
   rbd help snap create
   usage: rbd snap create [--pool <pool>] [--image <image>] [--snap <snap>] 
                          <snap-spec> 
@@ -1685,24 +1649,6 @@ Skip test on FreeBSD as it generates different output there.
     --image-id arg       image id
     --image arg          image name
   
-  rbd help unmap
-  usage: rbd unmap [--pool <pool>] [--image <image>] [--snap <snap>] 
-                   [--options <options>] 
-                   <image-or-snap-or-device-spec> 
-  
-  Unmap a rbd device that was used by the kernel.
-  
-  Positional arguments
-    <image-or-snap-or-device-spec>  image, snapshot, or device specification
-                                    [<pool-name>/]<image-name>[@<snapshot-name>]
-                                    or <device-path>
-  
-  Optional arguments
-    -p [ --pool ] arg               pool name
-    --image arg                     image name
-    --snap arg                      snapshot name
-    -o [ --options ] arg            unmap options
-  
   rbd help watch
   usage: rbd watch [--pool <pool>] [--image <image>] 
                    <image-spec> 
index 3d44eaf688a77cbd76731d61493b5d32b9d94ad1..2fb1df8059674190add2400a8b77c271e21676f9 100644 (file)
   $ rbd status
   rbd: image name was not specified
   [22]
-  $ rbd map
+  $ rbd device map
   rbd: image name was not specified
   [22]
-  $ rbd unmap
+  $ rbd device unmap
   rbd: unmap requires either image name or device path
   [22]
   $ rbd feature disable
index 957845c277536ccf488f51290360162458ee0ca7..cf075fb30aa18bf071456866a98b8b1dcc923388 100644 (file)
@@ -1,6 +1,6 @@
 A command taking no args:
 
-  $ rbd showmapped junk
+  $ rbd device list junk
   rbd: too many arguments
   [1]
 
index 21250690e6daac8c69df8c783376d782241c9182..45d5d33768fe2b1c8a74814860e4f943c82d22f8 100644 (file)
@@ -10,11 +10,13 @@ set(rbd_srcs
   action/Clone.cc
   action/Copy.cc
   action/Create.cc
+  action/Device.cc
   action/Diff.cc
   action/DiskUsage.cc
   action/Export.cc
   action/Feature.cc
   action/Flatten.cc
+  action/Ggate.cc
   action/Group.cc
   action/ImageMeta.cc
   action/Import.cc
@@ -36,9 +38,6 @@ set(rbd_srcs
   action/Status.cc
   action/Trash.cc
   action/Watch.cc)
-if(FREEBSD)
-  list(APPEND rbd_srcs action/Ggate.cc)
-endif()
 
 add_executable(rbd ${rbd_srcs}
   $<TARGET_OBJECTS:common_texttable_obj>)
diff --git a/src/tools/rbd/action/Device.cc b/src/tools/rbd/action/Device.cc
new file mode 100644 (file)
index 0000000..175bc0c
--- /dev/null
@@ -0,0 +1,183 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "acconfig.h"
+#include "tools/rbd/ArgumentTypes.h"
+#include "tools/rbd/Shell.h"
+
+#include <boost/program_options.hpp>
+
+namespace rbd {
+namespace action {
+
+namespace at = argument_types;
+namespace po = boost::program_options;
+
+#define DECLARE_DEVICE_OPERATIONS(ns)                                   \
+  namespace ns {                                                        \
+  int execute_list(const po::variables_map &vm,                         \
+                   const std::vector<std::string> &ceph_global_args);   \
+  int execute_map(const po::variables_map &vm,                          \
+                  const std::vector<std::string> &ceph_global_args);    \
+  int execute_unmap(const po::variables_map &vm,                        \
+                    const std::vector<std::string> &ceph_global_args);  \
+  }
+
+DECLARE_DEVICE_OPERATIONS(ggate);
+DECLARE_DEVICE_OPERATIONS(kernel);
+DECLARE_DEVICE_OPERATIONS(nbd);
+
+namespace device {
+
+namespace {
+
+struct DeviceOperations {
+  int (*execute_list)(const po::variables_map &vm,
+                      const std::vector<std::string> &ceph_global_args);
+  int (*execute_map)(const po::variables_map &vm,
+                     const std::vector<std::string> &ceph_global_args);
+  int (*execute_unmap)(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,
+};
+
+const DeviceOperations krbd_operations = {
+  kernel::execute_list,
+  kernel::execute_map,
+  kernel::execute_unmap,
+};
+
+const DeviceOperations nbd_operations = {
+  nbd::execute_list,
+  nbd::execute_map,
+  nbd::execute_unmap,
+};
+
+enum device_type_t {
+  DEVICE_TYPE_GGATE,
+  DEVICE_TYPE_KRBD,
+  DEVICE_TYPE_NBD,
+};
+
+struct DeviceType {};
+
+void validate(boost::any& v, const std::vector<std::string>& values,
+              DeviceType *target_type, int) {
+  po::validators::check_first_occurrence(v);
+  const std::string &s = po::validators::get_single_string(values);
+  if (s == "ggate") {
+    v = boost::any(DEVICE_TYPE_GGATE);
+  } else if (s == "krbd") {
+    v = boost::any(DEVICE_TYPE_KRBD);
+  } else if (s == "nbd") {
+    v = boost::any(DEVICE_TYPE_NBD);
+  } else {
+    throw po::validation_error(po::validation_error::invalid_option_value);
+  }
+}
+
+void add_device_type_option(po::options_description *options) {
+  options->add_options()
+    ("device-type,t", po::value<DeviceType>(),
+     "device type [ggate, krbd (default), nbd]");
+}
+
+void add_device_specific_options(po::options_description *options) {
+  options->add_options()
+    ("options,o", po::value<std::vector<std::string>>(),
+     "device specific options");
+}
+
+device_type_t get_device_type(const po::variables_map &vm) {
+  if (vm.count("device-type")) {
+    return vm["device-type"].as<device_type_t>();
+  }
+  return DEVICE_TYPE_KRBD;
+}
+
+const DeviceOperations *get_device_operations(const po::variables_map &vm) {
+  switch (get_device_type(vm)) {
+  case DEVICE_TYPE_GGATE:
+    return &ggate_operations;
+  case DEVICE_TYPE_KRBD:
+    return &krbd_operations;
+  case DEVICE_TYPE_NBD:
+    return &nbd_operations;
+  default:
+    assert(0);
+    return nullptr;
+  }
+}
+
+} // anonymous namespace
+
+void get_list_arguments(po::options_description *positional,
+                        po::options_description *options) {
+  add_device_type_option(options);
+  at::add_format_options(options);
+}
+
+int execute_list(const po::variables_map &vm,
+                 const std::vector<std::string> &ceph_global_init_args) {
+  return (*get_device_operations(vm)->execute_list)(vm, ceph_global_init_args);
+}
+
+void get_map_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()
+    ("read-only", po::bool_switch(), "map read-only")
+    ("exclusive", po::bool_switch(), "disable automatic exclusive lock transitions");
+  add_device_specific_options(options);
+}
+
+int execute_map(const po::variables_map &vm,
+                const std::vector<std::string> &ceph_global_init_args) {
+  return (*get_device_operations(vm)->execute_map)(vm, ceph_global_init_args);
+}
+
+void get_unmap_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>[@<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);
+  add_device_specific_options(options);
+}
+
+int execute_unmap(const po::variables_map &vm,
+                  const std::vector<std::string> &ceph_global_init_args) {
+  return (*get_device_operations(vm)->execute_unmap)(vm, ceph_global_init_args);
+}
+
+Shell::SwitchArguments switched_arguments({"read-only", "exclusive"});
+Shell::Action action_list(
+  {"device", "list"}, {"showmapped"}, "List mapped rbd images.", "",
+  &get_list_arguments, &execute_list);
+// yet another alias for list command
+Shell::Action action_ls(
+  {"device", "ls"}, {}, "List mapped rbd images.", "",
+  &get_list_arguments, &execute_list, false);
+
+Shell::Action action_map(
+  {"device", "map"}, {"map"}, "Map an image to a block device.", "",
+  &get_map_arguments, &execute_map);
+
+Shell::Action action_unmap(
+  {"device", "unmap"}, {"unmap"}, "Unmap a rbd device.", "",
+  &get_unmap_arguments, &execute_unmap);
+
+} // namespace device
+} // namespace action
+} // namespace rbd
index 9dc71dfb67a4fc1b5d6b0a86d9966a541016da65..7757785a58d92743b3e0e68551b9eaa13d12d066 100644 (file)
@@ -12,8 +12,8 @@
 #include "tools/rbd/Shell.h"
 #include "tools/rbd/Utils.h"
 
+#include <boost/algorithm/string.hpp>
 #include <boost/algorithm/string/predicate.hpp>
-#include <boost/scope_exit.hpp>
 #include <boost/program_options.hpp>
 
 #include <iostream>
@@ -75,13 +75,25 @@ int get_image_or_snap_spec(const po::variables_map &vm, std::string *spec) {
   return 0;
 }
 
-void get_list_arguments(po::options_description *positional,
-                        po::options_description *options) {
-  at::add_format_options(options);
+int parse_options(const std::vector<std::string> &options,
+                  std::vector<std::string> *args) {
+  for (auto &opts : options) {
+    std::vector<std::string> args_;
+    boost::split(args_, opts, boost::is_any_of(","));
+    for (auto &o : args_) {
+      args->push_back("--" + o);
+    }
+  }
+
+  return 0;
 }
 
 int execute_list(const po::variables_map &vm,
                  const std::vector<std::string> &ceph_global_init_args) {
+#if !defined(__FreeBSD__)
+  std::cerr << "rbd: ggate is only supported on FreeBSD" << std::endl;
+  return -EOPNOTSUPP;
+#endif
   std::vector<std::string> args;
 
   args.push_back("list");
@@ -97,19 +109,12 @@ int execute_list(const po::variables_map &vm,
   return call_ggate_cmd(vm, args, ceph_global_init_args);
 }
 
-void get_map_arguments(po::options_description *positional,
-                       po::options_description *options)
-{
-  at::add_image_or_snap_spec_options(positional, options,
-                                     at::ARGUMENT_MODIFIER_NONE);
-  options->add_options()
-    ("read-only", po::bool_switch(), "map read-only")
-    ("exclusive", po::bool_switch(), "forbid writes by other clients")
-    ("device", po::value<std::string>(), "specify ggate device");
-}
-
 int execute_map(const po::variables_map &vm,
                 const std::vector<std::string> &ceph_global_init_args) {
+#if !defined(__FreeBSD__)
+  std::cerr << "rbd: ggate is only supported on FreeBSD" << std::endl;
+  return -EOPNOTSUPP;
+#endif
   std::vector<std::string> args;
 
   args.push_back("map");
@@ -120,34 +125,30 @@ int execute_map(const po::variables_map &vm,
   }
   args.push_back(img);
 
-  if (vm["read-only"].as<bool>())
+  if (vm["read-only"].as<bool>()) {
     args.push_back("--read-only");
+  }
 
-  if (vm["exclusive"].as<bool>())
+  if (vm["exclusive"].as<bool>()) {
     args.push_back("--exclusive");
+  }
 
-  if (vm.count("device")) {
-    args.push_back("--device");
-    args.push_back(vm["device"].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_ggate_cmd(vm, args, ceph_global_init_args);
 }
 
-void get_unmap_arguments(po::options_description *positional,
-                         po::options_description *options)
-{
-  positional->add_options()
-    ("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,
                   const std::vector<std::string> &ceph_global_init_args) {
+#if !defined(__FreeBSD__)
+  std::cerr << "rbd: ggate is only supported on FreeBSD" << 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();
@@ -172,23 +173,16 @@ int execute_unmap(const po::variables_map &vm,
   args.push_back("unmap");
   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_ggate_cmd(vm, args, ceph_global_init_args);
 }
 
-Shell::SwitchArguments switched_arguments({"read-only", "exclusive"});
-
-Shell::Action action_list(
-  {"ggate", "list"}, {"ggate", "ls"}, "List mapped ggate devices.", "",
-  &get_list_arguments, &execute_list);
-
-Shell::Action action_map(
-  {"ggate", "map"}, {}, "Map an image to a ggate device.", "",
-  &get_map_arguments, &execute_map);
-
-Shell::Action action_unmap(
-  {"ggate", "unmap"}, {}, "Unmap a ggate device.", "",
-  &get_unmap_arguments, &execute_unmap);
-
 } // namespace ggate
 } // namespace action
 } // namespace rbd
index 7d0b718c20c6bb9cc4ec9722ea3397bafb5f712c..6f60ec02bce1faa9f6592f30ed7314cf124447e9 100644 (file)
@@ -88,8 +88,13 @@ static int put_map_option_value(const std::string &opt, const char *value_char,
   return 0;
 }
 
-static int parse_map_options(char *options)
+static int parse_map_options(const std::string &options_string)
 {
+  char *options = strdup(options_string.c_str());
+  BOOST_SCOPE_EXIT(options) {
+    free(options);
+  } BOOST_SCOPE_EXIT_END;
+
   for (char *this_char = strtok(options, ", ");
        this_char != NULL;
        this_char = strtok(NULL, ",")) {
@@ -144,8 +149,13 @@ static int parse_map_options(char *options)
   return 0;
 }
 
-static int parse_unmap_options(char *options)
+static int parse_unmap_options(const std::string &options_string)
 {
+  char *options = strdup(options_string.c_str());
+  BOOST_SCOPE_EXIT(options) {
+    free(options);
+  } BOOST_SCOPE_EXIT_END;
+
   for (char *this_char = strtok(options, ", ");
        this_char != NULL;
        this_char = strtok(NULL, ",")) {
@@ -165,8 +175,7 @@ static int parse_unmap_options(char *options)
   return 0;
 }
 
-static int do_kernel_showmapped(Formatter *f)
-{
+static int do_kernel_list(Formatter *f) {
 #if defined(WITH_KRBD)
   struct krbd_ctx *krbd;
   int r;
@@ -180,9 +189,9 @@ static int do_kernel_showmapped(Formatter *f)
   krbd_destroy(krbd);
   return r;
 #else
-  return -1;
+  std::cerr << "rbd: kernel device is not supported" << std::endl;
+  return -EOPNOTSUPP;
 #endif
-
 }
 
 static int get_unsupported_features(librbd::Image &image,
@@ -335,7 +344,8 @@ out:
   krbd_destroy(krbd);
   return r;
 #else
-  return -1;
+  std::cerr << "rbd: kernel device is not supported" << std::endl;
+  return -EOPNOTSUPP;
 #endif
 }
 
@@ -366,17 +376,12 @@ static int do_kernel_unmap(const char *dev, const char *poolname,
   krbd_destroy(krbd);
   return r;
 #else
-  return -1;
+  std::cerr << "rbd: kernel device is not supported" << std::endl;
+  return -EOPNOTSUPP;
 #endif
-
 }
 
-void get_show_arguments(po::options_description *positional,
-                        po::options_description *options) {
-  at::add_format_options(options);
-}
-
-int execute_show(const po::variables_map &vm,
+int execute_list(const po::variables_map &vm,
                  const std::vector<std::string> &ceph_global_init_args) {
   at::Format::Formatter formatter;
   int r = utils::get_formatter(vm, &formatter);
@@ -386,24 +391,14 @@ int execute_show(const po::variables_map &vm,
 
   utils::init_context();
 
-  r = do_kernel_showmapped(formatter.get());
+  r = do_kernel_list(formatter.get());
   if (r < 0) {
-    std::cerr << "rbd: showmapped failed: " << cpp_strerror(r) << std::endl;
+    std::cerr << "rbd: device list failed: " << cpp_strerror(r) << std::endl;
     return r;
   }
   return 0;
 }
 
-void get_map_arguments(po::options_description *positional,
-                       po::options_description *options) {
-  at::add_image_or_snap_spec_options(positional, options,
-                                     at::ARGUMENT_MODIFIER_NONE);
-  options->add_options()
-    ("options,o", po::value<std::string>(), "map options")
-    ("read-only", po::bool_switch(), "map read-only")
-    ("exclusive", po::bool_switch(), "disable automatic exclusive lock transitions");
-}
-
 int execute_map(const po::variables_map &vm,
                 const std::vector<std::string> &ceph_global_init_args) {
   size_t arg_index = 0;
@@ -426,26 +421,20 @@ int execute_map(const po::variables_map &vm,
   }
 
   // parse default options first so they can be overwritten by cli options
-  char *default_map_options = strdup(g_conf->get_val<std::string>(
-    "rbd_default_map_options").c_str());
-  BOOST_SCOPE_EXIT( (default_map_options) ) {
-    free(default_map_options);
-  } BOOST_SCOPE_EXIT_END;
-
-  if (parse_map_options(default_map_options)) {
+  r = parse_map_options(
+      g_conf->get_val<std::string>("rbd_default_map_options"));
+  if (r < 0) {
     std::cerr << "rbd: couldn't parse default map options" << std::endl;
-    return -EINVAL;
+    return r;
   }
 
   if (vm.count("options")) {
-    char *cli_map_options = strdup(vm["options"].as<std::string>().c_str());
-    BOOST_SCOPE_EXIT( (cli_map_options) ) {
-      free(cli_map_options);
-    } BOOST_SCOPE_EXIT_END;
-
-    if (parse_map_options(cli_map_options)) {
-      std::cerr << "rbd: couldn't parse map options" << std::endl;
-      return -EINVAL;
+    for (auto &options : vm["options"].as<std::vector<std::string>>()) {
+      r = parse_map_options(options);
+      if (r < 0) {
+        std::cerr << "rbd: couldn't parse map options" << std::endl;
+        return r;
+      }
     }
   }
 
@@ -460,19 +449,6 @@ int execute_map(const po::variables_map &vm,
   return 0;
 }
 
-void get_unmap_arguments(po::options_description *positional,
-                   po::options_description *options) {
-  positional->add_options()
-    ("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);
-  options->add_options()
-    ("options,o", po::value<std::string>(), "unmap options");
-}
-
 int execute_unmap(const po::variables_map &vm,
                   const std::vector<std::string> &ceph_global_init_args) {
   std::string device_name = utils::get_positional_argument(vm, 0);
@@ -502,14 +478,12 @@ int execute_unmap(const po::variables_map &vm,
   }
 
   if (vm.count("options")) {
-    char *cli_unmap_options = strdup(vm["options"].as<std::string>().c_str());
-    BOOST_SCOPE_EXIT( (cli_unmap_options) ) {
-      free(cli_unmap_options);
-    } BOOST_SCOPE_EXIT_END;
-
-    if (parse_unmap_options(cli_unmap_options)) {
-      std::cerr << "rbd: couldn't parse unmap options" << std::endl;
-      return -EINVAL;
+    for (auto &options : vm["options"].as<std::vector<std::string>>()) {
+      r = parse_unmap_options(options);
+      if (r < 0) {
+        std::cerr << "rbd: couldn't parse unmap options" << std::endl;
+        return r;
+      }
     }
   }
 
@@ -525,19 +499,6 @@ int execute_unmap(const po::variables_map &vm,
   return 0;
 }
 
-Shell::SwitchArguments switched_arguments({"read-only", "exclusive"});
-Shell::Action action_show(
-  {"showmapped"}, {}, "Show the rbd images mapped by the kernel.", "",
-  &get_show_arguments, &execute_show);
-
-Shell::Action action_map(
-  {"map"}, {}, "Map image to a block device using the kernel.", "",
-  &get_map_arguments, &execute_map);
-
-Shell::Action action_unmap(
-  {"unmap"}, {}, "Unmap a rbd device that was used by the kernel.", "",
-  &get_unmap_arguments, &execute_unmap);
-
 } // namespace kernel
 } // namespace action
 } // namespace rbd
index eaf26f592319b78fcc30d5294dfca14f4500bf76..de64b5e89fc8a13da152f72754943ea0a427f019 100644 (file)
@@ -7,8 +7,8 @@
 #include "include/stringify.h"
 #include "common/SubProcess.h"
 #include <iostream>
+#include <boost/algorithm/string.hpp>
 #include <boost/algorithm/string/predicate.hpp>
-#include <boost/scope_exit.hpp>
 #include <boost/program_options.hpp>
 
 namespace rbd {
@@ -79,20 +79,32 @@ int get_image_or_snap_spec(const po::variables_map &vm, std::string *spec) {
   return 0;
 }
 
-void get_show_arguments(po::options_description *positional,
-                        po::options_description *options) {
-  at::add_format_options(options);
+int parse_options(const std::vector<std::string> &options,
+                  std::vector<std::string> *args) {
+  for (auto &opts : options) {
+    std::vector<std::string> args_;
+    boost::split(args_, opts, boost::is_any_of(","));
+    for (auto &o : args_) {
+      args->push_back("--" + o);
+    }
+  }
+
+  return 0;
 }
 
-int execute_show(const po::variables_map &vm,
+int execute_list(const po::variables_map &vm,
                  const std::vector<std::string> &ceph_global_init_args) {
+#if defined(__FreeBSD__)
+  std::cerr << "rbd: nbd device is not supported" << std::endl;
+  return -EOPNOTSUPP;
+#endif
   std::vector<std::string> args;
 
   args.push_back("list-mapped");
 
   if (vm.count("format")) {
     args.push_back("--format");
-    args.push_back(vm["format"].as<at::Format>().value.c_str());
+    args.push_back(vm["format"].as<at::Format>().value);
   }
   if (vm["pretty-format"].as<bool>()) {
     args.push_back("--pretty-format");
@@ -101,22 +113,12 @@ int execute_show(const po::variables_map &vm,
   return call_nbd_cmd(vm, args, ceph_global_init_args);
 }
 
-void get_map_arguments(po::options_description *positional,
-                       po::options_description *options)
-{
-  at::add_image_or_snap_spec_options(positional, options,
-                                     at::ARGUMENT_MODIFIER_NONE);
-  options->add_options()
-    ("read-only", po::bool_switch(), "map read-only")
-    ("exclusive", po::bool_switch(), "forbid writes by other clients")
-    ("device", po::value<std::string>(), "specify nbd device")
-    ("nbds_max", po::value<std::string>(), "override module param nbds_max")
-    ("max_part", po::value<std::string>(), "override module param max_part")
-    ("timeout", po::value<std::string>(), "set nbd request timeout (seconds)");
-}
-
 int execute_map(const po::variables_map &vm,
                 const std::vector<std::string> &ceph_global_init_args) {
+#if defined(__FreeBSD__)
+  std::cerr << "rbd: nbd device is not supported" << std::endl;
+  return -EOPNOTSUPP;
+#endif
   std::vector<std::string> args;
 
   args.push_back("map");
@@ -127,46 +129,30 @@ int execute_map(const po::variables_map &vm,
   }
   args.push_back(img);
 
-  if (vm["read-only"].as<bool>())
+  if (vm["read-only"].as<bool>()) {
     args.push_back("--read-only");
+  }
 
-  if (vm["exclusive"].as<bool>())
+  if (vm["exclusive"].as<bool>()) {
     args.push_back("--exclusive");
-
-  if (vm.count("device")) {
-    args.push_back("--device");
-    args.push_back(vm["device"].as<std::string>());
-  }
-  if (vm.count("nbds_max")) {
-    args.push_back("--nbds_max");
-    args.push_back(vm["nbds_max"].as<std::string>());
-  }
-  if (vm.count("max_part")) {
-    args.push_back("--max_part");
-    args.push_back(vm["max_part"].as<std::string>());
   }
-  if (vm.count("timeout")) {
-    args.push_back("--timeout");
-    args.push_back(vm["timeout"].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);
 }
 
-void get_unmap_arguments(po::options_description *positional,
-                   po::options_description *options)
-{
-  positional->add_options()
-    ("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,
                   const std::vector<std::string> &ceph_global_init_args) {
+#if defined(__FreeBSD__)
+  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();
@@ -191,22 +177,112 @@ int execute_unmap(const po::variables_map &vm,
   args.push_back("unmap");
   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);
 }
 
-Shell::SwitchArguments switched_arguments({"read-only"});
+void get_list_arguments_deprecated(po::options_description *positional,
+                                   po::options_description *options) {
+  at::add_format_options(options);
+}
+
+int execute_list_deprecated(const po::variables_map &vm,
+                            const std::vector<std::string> &ceph_global_args) {
+  std::cerr << "rbd: 'nbd list' command is deprecated, "
+            << "use 'device list -t nbd' instead" << std::endl;
+  return execute_list(vm, ceph_global_args);
+}
+
+void get_map_arguments_deprecated(po::options_description *positional,
+                                  po::options_description *options) {
+  at::add_image_or_snap_spec_options(positional, options,
+                                     at::ARGUMENT_MODIFIER_NONE);
+  options->add_options()
+    ("read-only", po::bool_switch(), "map read-only")
+    ("exclusive", po::bool_switch(), "forbid writes by other clients")
+    ("device", po::value<std::string>(), "specify nbd device")
+    ("nbds_max", po::value<std::string>(), "override module param nbds_max")
+    ("max_part", po::value<std::string>(), "override module param max_part")
+    ("timeout", po::value<std::string>(), "set nbd request timeout (seconds)");
+}
+
+int execute_map_deprecated(const po::variables_map &vm_deprecated,
+                           const std::vector<std::string> &ceph_global_args) {
+  std::cerr << "rbd: 'nbd map' command is deprecated, "
+            << "use 'device map -t nbd' instead" << std::endl;
+
+  po::options_description options;
+  options.add_options()
+    ("read-only", po::bool_switch(), "")
+    ("exclusive", po::bool_switch(), "")
+    ("options,o", po::value<std::vector<std::string>>(), "");
+
+  po::variables_map vm;
+  po::store(po::command_line_parser({}).options(options).run(), vm);
+
+  if (vm_deprecated["read-only"].as<bool>()) {
+    vm.at("read-only").value() = boost::any(true);
+  }
+  if (vm_deprecated["exclusive"].as<bool>()) {
+    vm.at("exclusive").value() = boost::any(true);
+  }
+
+  std::vector<std::string> opts;
+  if (vm_deprecated.count("device")) {
+    opts.push_back("device=" + vm_deprecated["device"].as<std::string>());
+  }
+  if (vm.count("nbds_max")) {
+    opts.push_back("nbds_max=" + vm_deprecated["nbds_max"].as<std::string>());
+  }
+  if (vm.count("max_part")) {
+    opts.push_back("max_part=" + vm_deprecated["max_part"].as<std::string>());
+  }
+  if (vm.count("timeout")) {
+    opts.push_back("timeout=" + vm_deprecated["timeout"].as<std::string>());
+  }
+
+  vm.at("options").value() = boost::any(opts);
+
+  return execute_map(vm, ceph_global_args);
+}
+
+void get_unmap_arguments_deprecated(po::options_description *positional,
+                                    po::options_description *options) {
+  positional->add_options()
+    ("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_deprecated(const po::variables_map &vm,
+                             const std::vector<std::string> &ceph_global_args) {
+  std::cerr << "rbd: 'nbd unmap' command is deprecated, "
+            << "use 'device unmap -t nbd' instead" << std::endl;
+  return execute_unmap(vm, ceph_global_args);
+}
+
+Shell::SwitchArguments switched_arguments({"read-only", "exclusive"});
 
-Shell::Action action_show(
+Shell::Action action_show_deprecated(
   {"nbd", "list"}, {"nbd", "ls"}, "List the nbd devices already used.", "",
-  &get_show_arguments, &execute_show);
+  &get_list_arguments_deprecated, &execute_list_deprecated, false);
 
-Shell::Action action_map(
+Shell::Action action_map_deprecated(
   {"nbd", "map"}, {}, "Map image to a nbd device.", "",
-  &get_map_arguments, &execute_map);
+  &get_map_arguments_deprecated, &execute_map_deprecated, false);
 
-Shell::Action action_unmap(
+Shell::Action action_unmap_deprecated(
   {"nbd", "unmap"}, {}, "Unmap a nbd device.", "",
-  &get_unmap_arguments, &execute_unmap);
+  &get_unmap_arguments_deprecated, &execute_unmap_deprecated, false);
 
 } // namespace nbd
 } // namespace action