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
-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.
: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.
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.
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.
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.
* 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).
* 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
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::
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/
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,
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:
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
# 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"
# 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
case "$1" in
start)
- rbdmap map
+ rbdmap device map
;;
stop)
- rbdmap unmap
+ rbdmap device unmap
;;
restart|force-reload)
;;
reload)
- rbdmap map
+ rbdmap device map
;;
status)
- rbd showmapped
+ rbd device list
;;
*)
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
# 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() {
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
# 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
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
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
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
# 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
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
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]
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]
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
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
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
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
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
-Skip test on FreeBSD as it generates different output there.
-
- $ test "$(uname)" = "FreeBSD" && exit 80 || true
-
$ rbd --help
usage: rbd <command> ...
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
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.
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.
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:
(-) 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>]
-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>
--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]
--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>
--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>
$ 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
A command taking no args:
- $ rbd showmapped junk
+ $ rbd device list junk
rbd: too many arguments
[1]
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
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>)
--- /dev/null
+// -*- 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
#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>
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");
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");
}
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();
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
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, ",")) {
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, ",")) {
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;
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,
krbd_destroy(krbd);
return r;
#else
- return -1;
+ std::cerr << "rbd: kernel device is not supported" << std::endl;
+ return -EOPNOTSUPP;
#endif
}
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);
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;
}
// 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;
+ }
}
}
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);
}
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;
+ }
}
}
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
#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 {
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");
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");
}
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();
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