From 3e8624f157a1acaea91633403483e09c69707230 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 21 Jun 2018 15:23:59 -0400 Subject: [PATCH] rbd: add support for namespaces Signed-off-by: Jason Dillaman --- doc/man/8/rbd.rst | 22 +- qa/workunits/rbd/cli_generic.sh | 27 +- src/test/cli/rbd/help.t | 625 +++++++++++++++++--------- src/test/cli/rbd/invalid-snap-usage.t | 76 ++-- src/test/cli/rbd/not-enough-args.t | 18 +- src/tools/rbd/ArgumentTypes.cc | 107 +---- src/tools/rbd/ArgumentTypes.h | 31 +- src/tools/rbd/Utils.cc | 498 +++++--------------- src/tools/rbd/Utils.h | 72 +-- src/tools/rbd/action/Bench.cc | 9 +- src/tools/rbd/action/Children.cc | 9 +- src/tools/rbd/action/Clone.cc | 24 +- src/tools/rbd/action/Copy.cc | 38 +- src/tools/rbd/action/Create.cc | 15 +- src/tools/rbd/action/Diff.cc | 9 +- src/tools/rbd/action/DiskUsage.cc | 9 +- src/tools/rbd/action/Export.cc | 20 +- src/tools/rbd/action/Feature.cc | 10 +- src/tools/rbd/action/Flatten.cc | 10 +- src/tools/rbd/action/Ggate.cc | 6 +- src/tools/rbd/action/Group.cc | 364 +++++++++------ src/tools/rbd/action/ImageMeta.cc | 40 +- src/tools/rbd/action/Import.cc | 23 +- src/tools/rbd/action/Info.cc | 40 +- src/tools/rbd/action/Journal.cc | 207 +++++++-- src/tools/rbd/action/Kernel.cc | 12 +- src/tools/rbd/action/List.cc | 9 +- src/tools/rbd/action/Lock.cc | 30 +- src/tools/rbd/action/MirrorImage.cc | 40 +- src/tools/rbd/action/MirrorPool.cc | 24 +- src/tools/rbd/action/Namespace.cc | 7 +- src/tools/rbd/action/Nbd.cc | 4 +- src/tools/rbd/action/ObjectMap.cc | 18 +- src/tools/rbd/action/Pool.cc | 2 +- src/tools/rbd/action/Remove.cc | 16 +- src/tools/rbd/action/Rename.cc | 21 +- src/tools/rbd/action/Resize.cc | 10 +- src/tools/rbd/action/Snap.cc | 195 ++++---- src/tools/rbd/action/Status.cc | 10 +- src/tools/rbd/action/Trash.cc | 60 ++- src/tools/rbd/action/Watch.cc | 10 +- 41 files changed, 1441 insertions(+), 1336 deletions(-) diff --git a/doc/man/8/rbd.rst b/doc/man/8/rbd.rst index b5b72ebd0eab5..40f986ab9d506 100644 --- a/doc/man/8/rbd.rst +++ b/doc/man/8/rbd.rst @@ -43,6 +43,10 @@ Options Interact with the given pool. Required by most commands. +.. option:: --namespace namespace-name + + Use a pre-defined image namespace within a pool + .. option:: --no-progress Do not output progress information (goes to standard error by @@ -568,19 +572,19 @@ Commands Image, snap, group and journal specs ==================================== -| *image-spec* is [*pool-name*/]\ *image-name* -| *snap-spec* is [*pool-name*/]\ *image-name*\ @\ *snap-name* -| *group-spec* is [*pool-name*/]\ *group-name* -| *group-snap-spec* is [*pool-name*/]\ *group-name*\ @\ *snap-name* -| *journal-spec* is [*pool-name*/]\ *journal-name* +| *image-spec* is [*pool-name*/[*namespace-name*/]]\ *image-name* +| *snap-spec* is [*pool-name*/[*namespace-name*/]]\ *image-name*\ @\ *snap-name* +| *group-spec* is [*pool-name*/[*namespace-name*/]]\ *group-name* +| *group-snap-spec* is [*pool-name*/[*namespace-name*/]]\ *group-name*\ @\ *snap-name* +| *journal-spec* is [*pool-name*/[*namespace-name*/]]\ *journal-name* -The default for *pool-name* is "rbd". If an image name contains a slash -character ('/'), *pool-name* is required. +The default for *pool-name* is "rbd" and *namespace-name* is "". If an image +name contains a slash character ('/'), *pool-name* is required. The *journal-name* is *image-id*. -You may specify each name individually, using --pool, --image and --snap -options, but this is discouraged in favor of the above spec syntax. +You may specify each name individually, using --pool, --namespace, --image, and +--snap options, but this is discouraged in favor of the above spec syntax. Striping ======== diff --git a/qa/workunits/rbd/cli_generic.sh b/qa/workunits/rbd/cli_generic.sh index 219186015055c..adb1ccf06f887 100755 --- a/qa/workunits/rbd/cli_generic.sh +++ b/qa/workunits/rbd/cli_generic.sh @@ -7,6 +7,14 @@ rbd ls | wc -l | grep -v '^0$' && echo "nonempty rbd pool, aborting! run this s IMGS="testimg1 testimg2 testimg3 testimg4 testimg5 testimg6 testimg-diff1 testimg-diff2 testimg-diff3 foo foo2 bar bar2 test1 test2 test3 test4 clone2" +expect_fail() +{ + set -x + set +e + "$@" + if [ $? == 0 ]; then return 1; else return 0; fi +} + tiered=0 if ceph osd dump | grep ^pool | grep "'rbd'" | grep tier; then tiered=1 @@ -619,11 +627,26 @@ test_namespace() { rbd namespace create rbd test1 rbd namespace create --pool rbd test2 rbd namespace create --namespace test3 - rbd namespace create rbd test3 || true + expect_fail rbd namespace create rbd test3 rbd namespace list | grep 'test' | wc -l | grep '^3$' - rbd namespace remove --pool rbd missing || true + expect_fail rbd namespace remove --pool rbd missing + + rbd create rbd/test1/image1 --size 1G + rbd create --namespace test1 image2 --size 1G + expect_fail rbd namespace remove --pool rbd test1 + + rbd group create rbd/test1/group1 + rbd group image add rbd/test1/group1 rbd/test1/image1 + rbd group rm rbd/test1/group1 + + rbd trash move rbd/test1/image1 + ID=`rbd trash --namespace test1 ls | cut -d ' ' -f 1` + rbd trash rm rbd/test1/${ID} + + rbd remove rbd/test1/image2 + rbd namespace remove --pool rbd test1 rbd namespace remove --namespace test3 diff --git a/src/test/cli/rbd/help.t b/src/test/cli/rbd/help.t index efc9e2ffc6d71..2304409dcfde7 100644 --- a/src/test/cli/rbd/help.t +++ b/src/test/cli/rbd/help.t @@ -7,7 +7,7 @@ bench Simple benchmark. children Display children of snapshot. - clone Clone a snapshot into a COW child image. + clone Clone a snapshot into a CoW child image. copy (cp) Copy src image to dest. create Create an empty image. deep copy (deep cp) Deep copy src image to dest. @@ -123,9 +123,9 @@ See 'rbd help ' for help on a specific command. $ rbd help | grep '^ [a-z]' | sed 's/^ \([a-z -]*[a-z]\).*/\1/g' | while read -r line; do echo rbd help $line ; rbd help $line; done rbd help bench - usage: rbd bench [--pool ] [--image ] [--io-size ] - [--io-threads ] [--io-total ] - [--io-pattern ] + usage: rbd bench [--pool ] [--namespace ] [--image ] + [--io-size ] [--io-threads ] + [--io-total ] [--io-pattern ] [--rw-mix-read ] --io-type @@ -133,10 +133,11 @@ Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --io-size arg IO size (in B/K/M/G/T) [default: 4K] --io-threads arg ios in flight [default: 16] @@ -146,19 +147,22 @@ --io-type arg IO type (read , write, or readwrite(rw)) rbd help children - usage: rbd children [--pool ] [--image ] [--snap ] - [--snap-id ] [--all] [--format ] - [--pretty-format] + usage: rbd children [--pool ] [--namespace ] + [--image ] [--snap ] [--snap-id ] + [--all] [--format ] [--pretty-format] Display children of snapshot. Positional arguments snapshot specification - (example: [/]@) + (example: + [/[/]]@) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --snap arg snapshot name --snap-id arg snapshot id @@ -167,9 +171,10 @@ --pretty-format pretty formatting (json and xml) rbd help clone - usage: rbd clone [--pool ] [--image ] [--snap ] - [--dest-pool ] [--dest ] [--order ] - [--object-size ] + usage: rbd clone [--pool ] [--namespace ] [--image ] + [--snap ] [--dest-pool ] + [--dest-namespace ] [--dest ] + [--order ] [--object-size ] [--image-feature ] [--image-shared] [--stripe-unit ] [--stripe-count ] [--data-pool ] @@ -178,20 +183,24 @@ [--journal-pool ] - Clone a snapshot into a COW child image. + Clone a snapshot into a CoW child image. Positional arguments source snapshot specification (example: - [/]@) + [/[/]]@) destination image specification - (example: [/]) + (example: + [/[/]]) Optional arguments -p [ --pool ] arg source pool name + --namespace arg source namespace name --image arg source image name --snap arg source snapshot name --dest-pool arg destination pool name + --dest-namespace arg destination namespace name --dest arg destination image name --order arg object order [12 <= order <= 25] --object-size arg object size in B/K/M [4K <= object size <= 32M] @@ -212,9 +221,10 @@ (+) enabled by default for new images if features not specified rbd help copy - usage: rbd copy [--pool ] [--image ] [--snap ] - [--dest-pool ] [--dest ] [--order ] - [--object-size ] + usage: rbd copy [--pool ] [--namespace ] [--image ] + [--snap ] [--dest-pool ] + [--dest-namespace ] [--dest ] + [--order ] [--object-size ] [--image-feature ] [--image-shared] [--stripe-unit ] [--stripe-count ] [--data-pool ] @@ -229,15 +239,19 @@ Positional arguments source image or snapshot specification (example: - [/][@]) + [/[/]][@]) destination image specification - (example: [/]) + (example: + [/[/]]) Optional arguments -p [ --pool ] arg source pool name + --namespace arg source namespace name --image arg source image name --snap arg source snapshot name --dest-pool arg destination pool name + --dest-namespace arg destination namespace name --dest arg destination image name --order arg object order [12 <= order <= 25] --object-size arg object size in B/K/M [4K <= object size <= 32M] @@ -260,7 +274,7 @@ (+) enabled by default for new images if features not specified rbd help create - usage: rbd create [--pool ] [--image ] + usage: rbd create [--pool ] [--namespace ] [--image ] [--image-format ] [--new-format] [--order ] [--object-size ] [--image-feature ] [--image-shared] @@ -276,10 +290,12 @@ Positional arguments image specification - (example: [/]) + (example: + [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --image-format arg image format [1 (deprecated) or 2] --new-format use image format 2 @@ -306,8 +322,10 @@ (+) enabled by default for new images if features not specified rbd help deep copy - usage: rbd deep copy [--pool ] [--image ] [--snap ] - [--dest-pool ] [--dest ] + usage: rbd deep copy [--pool ] [--namespace ] + [--image ] [--snap ] + [--dest-pool ] + [--dest-namespace ] [--dest ] [--order ] [--object-size ] [--image-feature ] [--image-shared] [--stripe-unit ] @@ -323,15 +341,19 @@ Positional arguments source image or snapshot specification (example: - [/][@]) + [/[/]][@]) destination image specification - (example: [/]) + (example: + [/[/]]) Optional arguments -p [ --pool ] arg source pool name + --namespace arg source namespace name --image arg source image name --snap arg source snapshot name --dest-pool arg destination pool name + --dest-namespace arg destination namespace name --dest arg destination image name --order arg object order [12 <= order <= 25] --object-size arg object size in B/K/M [4K <= object size <= 32M] @@ -366,19 +388,23 @@ rbd help device map usage: rbd device map [--device-type ] [--pool ] - [--image ] [--snap ] [--read-only] - [--exclusive] [--options ] + [--namespace ] [--image ] + [--snap ] [--read-only] [--exclusive] + [--options ] Map an image to a block device. Positional arguments image or snapshot specification - (example: [/][@]) + (example: + [/[/]][@]) Optional arguments -t [ --device-type ] arg device type [ggate, krbd (default), nbd] -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --snap arg snapshot name --read-only map read-only @@ -405,19 +431,22 @@ -o [ --options ] arg device specific options rbd help diff - usage: rbd diff [--pool ] [--image ] [--snap ] - [--from-snap ] [--whole-object] [--format ] - [--pretty-format] + usage: rbd diff [--pool ] [--namespace ] [--image ] + [--snap ] [--from-snap ] [--whole-object] + [--format ] [--pretty-format] Print extents that differ since a previous snap, or image creation. Positional arguments image or snapshot specification - (example: [/][@]) + (example: + [/[/]][@]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --snap arg snapshot name --from-snap arg snapshot starting point @@ -426,19 +455,22 @@ --pretty-format pretty formatting (json and xml) rbd help disk-usage - usage: rbd disk-usage [--pool ] [--image ] [--snap ] - [--format ] [--pretty-format] - [--from-snap ] [--exact] + usage: rbd disk-usage [--pool ] [--namespace ] + [--image ] [--snap ] [--format ] + [--pretty-format] [--from-snap ] [--exact] Show disk usage stats for pool, image or snapshot. Positional arguments image or snapshot specification - (example: [/][@]) + (example: + [/[/]][@]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --snap arg snapshot name --format arg output format (plain, json, or xml) [default: plain] @@ -447,8 +479,8 @@ --exact compute exact disk usage (slow) rbd help export - usage: rbd export [--pool ] [--image ] [--snap ] - [--path ] [--no-progress] + usage: rbd export [--pool ] [--namespace ] [--image ] + [--snap ] [--path ] [--no-progress] [--export-format ] @@ -457,11 +489,13 @@ Positional arguments source image or snapshot specification (example: - [/][@]) + [/[/]][@]) export file (or '-' for stdout) Optional arguments -p [ --pool ] arg source pool name + --namespace arg source namespace name --image arg source image name --snap arg source snapshot name --path arg export file (or '-' for stdout) @@ -469,9 +503,10 @@ --export-format arg format of image file rbd help export-diff - usage: rbd export-diff [--pool ] [--image ] [--snap ] - [--path ] [--from-snap ] - [--whole-object] [--no-progress] + usage: rbd export-diff [--pool ] [--namespace ] + [--image ] [--snap ] [--path ] + [--from-snap ] [--whole-object] + [--no-progress] Export incremental diff to file. @@ -479,11 +514,13 @@ Positional arguments source image or snapshot specification (example: - [/][@]) + [/[/]][@]) export file (or '-' for stdout) Optional arguments -p [ --pool ] arg source pool name + --namespace arg source namespace name --image arg source image name --snap arg source snapshot name --path arg export file (or '-' for stdout) @@ -492,23 +529,26 @@ --no-progress disable progress output rbd help feature disable - usage: rbd feature disable [--pool ] [--image ] + usage: rbd feature disable [--pool ] [--namespace ] + [--image ] [ ...] Disable the specified image feature. Positional arguments image specification - (example: [/]) + (example: [/[/]]) image features [exclusive-lock, object-map, journaling] Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name rbd help feature enable - usage: rbd feature enable [--pool ] [--image ] + usage: rbd feature enable [--pool ] [--namespace ] + [--image ] [--journal-splay-width ] [--journal-object-size ] [--journal-pool ] @@ -518,198 +558,234 @@ Positional arguments image specification - (example: [/]) + (example: + [/[/]]) image features [exclusive-lock, object-map, journaling] Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --journal-splay-width arg number of active journal objects --journal-object-size arg size of journal objects --journal-pool arg pool for journal objects rbd help flatten - usage: rbd flatten [--pool ] [--image ] [--no-progress] + usage: rbd flatten [--pool ] [--namespace ] [--image ] + [--no-progress] Fill clone with parent data (make it independent). Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --no-progress disable progress output rbd help group create - usage: rbd group create [--pool ] [--group ] + usage: rbd group create [--pool ] [--namespace ] + [--group ] Create a group. Positional arguments group specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --group arg group name rbd help group image add - usage: rbd group image add [--group-pool ] [--group ] - [--image-pool ] [--image ] - [--pool ] + usage: rbd group image add [--group-pool ] + [--group-namespace ] + [--group ] [--image-pool ] + [--image-namespace ] + [--image ] [--pool ] Add an image to a group. Positional arguments - group specification - (example: [/]) - image specification - (example: [/]) + group specification + (example: [/[/]]) + image specification + (example: [/[/]]) Optional arguments - --group-pool arg group pool name - --group arg group name - --image-pool arg image pool name - --image arg image name - -p [ --pool ] arg pool name unless overridden + --group-pool arg group pool name + --group-namespace arg group namespace name + --group arg group name + --image-pool arg image pool name + --image-namespace arg image namespace name + --image arg image name + -p [ --pool ] arg pool name unless overridden rbd help group image list usage: rbd group image list [--format ] [--pretty-format] - [--pool ] [--group ] + [--pool ] [--namespace ] + [--group ] List images in a group. Positional arguments group specification - (example: [/]) + (example: [/[/]]) Optional arguments --format arg output format (plain, json, or xml) [default: plain] --pretty-format pretty formatting (json and xml) -p [ --pool ] arg pool name + --namespace arg namespace name --group arg group name rbd help group image remove - usage: rbd group image remove [--group-pool ] [--group ] - [--image-pool ] [--image ] - [--pool ] [--image-id ] + usage: rbd group image remove [--group-pool ] + [--group-namespace ] + [--group ] [--image-pool ] + [--image-namespace ] + [--image ] [--pool ] + [--image-id ] Remove an image from a group. Positional arguments - group specification - (example: [/]) - image specification - (example: [/]) + group specification + (example: [/[/]]) + image specification + (example: [/[/]]) Optional arguments - --group-pool arg group pool name - --group arg group name - --image-pool arg image pool name - --image arg image name - -p [ --pool ] arg pool name unless overridden - --image-id arg image id + --group-pool arg group pool name + --group-namespace arg group namespace name + --group arg group name + --image-pool arg image pool name + --image-namespace arg image namespace name + --image arg image name + -p [ --pool ] arg pool name unless overridden + --image-id arg image id rbd help group list - usage: rbd group list [--pool ] [--format ] [--pretty-format] + usage: rbd group list [--pool ] [--namespace ] + [--format ] [--pretty-format] List rbd groups. Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --format arg output format (plain, json, or xml) [default: plain] --pretty-format pretty formatting (json and xml) rbd help group remove - usage: rbd group remove [--pool ] [--group ] + usage: rbd group remove [--pool ] [--namespace ] + [--group ] Delete a group. Positional arguments group specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --group arg group name rbd help group rename - usage: rbd group rename [--pool ] [--group ] - [--dest-pool ] [--dest-group ] + usage: rbd group rename [--pool ] [--namespace ] + [--group ] [--dest-pool ] + [--dest-namespace ] + [--dest-group ] Rename a group within pool. Positional arguments source group specification - (example: [/]) + (example: [/[/]]) destination group specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg source pool name + --namespace arg source namespace name --group arg source group name --dest-pool arg destination pool name + --dest-namespace arg destination namespace name --dest-group arg destination group name rbd help group snap create - usage: rbd group snap create [--pool ] [--group ] [--snap ] + usage: rbd group snap create [--pool ] [--namespace ] + [--group ] [--snap ] Make a snapshot of a group. Positional arguments group specification - (example: [/]@) + (example: + [/[/]]@ + ) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --group arg group name --snap arg snapshot name rbd help group snap list usage: rbd group snap list [--format ] [--pretty-format] - [--pool ] [--group ] + [--pool ] [--namespace ] + [--group ] List snapshots of a group. Positional arguments group specification - (example: [/]) + (example: [/[/]]) Optional arguments --format arg output format (plain, json, or xml) [default: plain] --pretty-format pretty formatting (json and xml) -p [ --pool ] arg pool name + --namespace arg namespace name --group arg group name rbd help group snap remove - usage: rbd group snap remove [--pool ] [--group ] [--snap ] + usage: rbd group snap remove [--pool ] [--namespace ] + [--group ] [--snap ] Remove a snapshot from a group. Positional arguments group specification - (example: [/]@) + (example: + [/[/]]@ + ) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --group arg group name --snap arg snapshot name rbd help group snap rename - usage: rbd group snap rename [--pool ] [--group ] [--snap ] + usage: rbd group snap rename [--pool ] [--namespace ] + [--group ] [--snap ] [--dest-snap ] @@ -717,81 +793,93 @@ Positional arguments group specification - (example: [/]@) + (example: + [/[/]]@ + ) destination snapshot name (example: ) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --group arg group name --snap arg snapshot name --dest-snap arg destination snapshot name rbd help image-meta get - usage: rbd image-meta get [--pool ] [--image ] + usage: rbd image-meta get [--pool ] [--namespace ] + [--image ] Image metadata get the value associated with the key. Positional arguments image specification - (example: [/]) + (example: [/[/]]) image meta key Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name rbd help image-meta list - usage: rbd image-meta list [--pool ] [--image ] - [--format ] [--pretty-format] + usage: rbd image-meta list [--pool ] [--namespace ] + [--image ] [--format ] + [--pretty-format] Image metadata list keys with values. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --format arg output format (plain, json, or xml) [default: plain] --pretty-format pretty formatting (json and xml) rbd help image-meta remove - usage: rbd image-meta remove [--pool ] [--image ] + usage: rbd image-meta remove [--pool ] [--namespace ] + [--image ] Image metadata remove the key and value associated. Positional arguments image specification - (example: [/]) + (example: [/[/]]) image meta key Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name rbd help image-meta set - usage: rbd image-meta set [--pool ] [--image ] + usage: rbd image-meta set [--pool ] [--namespace ] + [--image ] Image metadata set key with value. Positional arguments image specification - (example: [/]) + (example: [/[/]]) image meta key image meta value Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name rbd help import - usage: rbd import [--path ] [--dest-pool ] [--dest ] + usage: rbd import [--path ] [--dest-pool ] + [--dest-namespace ] [--dest ] [--image-format ] [--new-format] [--order ] [--object-size ] [--image-feature ] [--image-shared] @@ -810,11 +898,13 @@ Positional arguments import file (or '-' for stdin) destination image specification - (example: [/]) + (example: + [/[/]]) Optional arguments --path arg import file (or '-' for stdin) --dest-pool arg destination pool name + --dest-namespace arg destination namespace name --dest arg destination image name --image-format arg image format [1 (deprecated) or 2] --new-format use image format 2 @@ -843,7 +933,8 @@ (+) enabled by default for new images if features not specified rbd help import-diff - usage: rbd import-diff [--path ] [--pool ] [--image ] + usage: rbd import-diff [--path ] [--pool ] + [--namespace ] [--image ] [--sparse-size ] [--no-progress] @@ -852,28 +943,33 @@ Positional arguments import file (or '-' for stdin) image specification - (example: [/]) + (example: [/[/]]) Optional arguments --path arg import file (or '-' for stdin) -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --sparse-size arg sparse size in B/K/M [default: 4K] --no-progress disable progress output rbd help info - usage: rbd info [--pool ] [--image ] [--snap ] - [--image-id ] [--format ] [--pretty-format] + usage: rbd info [--pool ] [--namespace ] [--image ] + [--snap ] [--image-id ] [--format ] + [--pretty-format] Show information about image size, striping, etc. Positional arguments image or snapshot specification - (example: [/][@]) + (example: + [/[/]][@]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --snap arg snapshot name --image-id arg image id @@ -881,8 +977,8 @@ --pretty-format pretty formatting (json and xml) rbd help journal client disconnect - usage: rbd journal client disconnect [--pool ] [--image ] - [--journal ] + usage: rbd journal client disconnect [--pool ] [--namespace ] + [--image ] [--journal ] [--client-id ] @@ -890,29 +986,33 @@ Positional arguments journal specification - (example: [/]) + (example: + [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --journal arg journal name --client-id arg client ID (or leave unspecified to disconnect all) rbd help journal export - usage: rbd journal export [--pool ] [--image ] - [--journal ] [--path ] [--verbose] - [--no-error] + usage: rbd journal export [--pool ] [--namespace ] + [--image ] [--journal ] + [--path ] [--verbose] [--no-error] Export image journal. Positional arguments source journal specification - (example: [/]) + (example: + [/[/]]) export file (or '-' for stdout) Optional arguments -p [ --pool ] arg source pool name + --namespace arg source namespace name --image arg source image name --journal arg source journal name --path arg export file (or '-' for stdout) @@ -921,8 +1021,9 @@ rbd help journal import usage: rbd journal import [--path ] [--dest-pool ] - [--dest ] [--dest-journal ] - [--verbose] [--no-error] + [--dest-namespace ] [--dest ] + [--dest-journal ] [--verbose] + [--no-error] Import image journal. @@ -930,149 +1031,167 @@ Positional arguments import file (or '-' for stdin) destination journal specification - (example: [/]) + (example: + [/[/]]) Optional arguments --path arg import file (or '-' for stdin) --dest-pool arg destination pool name + --dest-namespace arg destination namespace name --dest arg destination image name --dest-journal arg destination journal name --verbose be verbose --no-error continue after error rbd help journal info - usage: rbd journal info [--pool ] [--image ] - [--journal ] [--format ] - [--pretty-format] + usage: rbd journal info [--pool ] [--namespace ] + [--image ] [--journal ] + [--format ] [--pretty-format] Show information about image journal. Positional arguments journal specification - (example: [/]) + (example: + [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --journal arg journal name --format arg output format (plain, json, or xml) [default: plain] --pretty-format pretty formatting (json and xml) rbd help journal inspect - usage: rbd journal inspect [--pool ] [--image ] - [--journal ] [--verbose] + usage: rbd journal inspect [--pool ] [--namespace ] + [--image ] [--journal ] [--verbose] Inspect image journal for structural errors. Positional arguments journal specification - (example: [/]) + (example: + [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --journal arg journal name --verbose be verbose rbd help journal reset - usage: rbd journal reset [--pool ] [--image ] - [--journal ] + usage: rbd journal reset [--pool ] [--namespace ] + [--image ] [--journal ] Reset image journal. Positional arguments journal specification - (example: [/]) + (example: + [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --journal arg journal name rbd help journal status - usage: rbd journal status [--pool ] [--image ] - [--journal ] [--format ] - [--pretty-format] + usage: rbd journal status [--pool ] [--namespace ] + [--image ] [--journal ] + [--format ] [--pretty-format] Show status of image journal. Positional arguments journal specification - (example: [/]) + (example: + [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --journal arg journal name --format arg output format (plain, json, or xml) [default: plain] --pretty-format pretty formatting (json and xml) rbd help list - usage: rbd list [--long] [--pool ] [--format ] [--pretty-format] - + usage: rbd list [--long] [--pool ] [--namespace ] + [--format ] [--pretty-format] + List rbd images. Positional arguments pool name + namespace name Optional arguments -l [ --long ] long listing format -p [ --pool ] arg pool name + --namespace arg namespace name --format arg output format (plain, json, or xml) [default: plain] --pretty-format pretty formatting (json and xml) rbd help lock add - usage: rbd lock add [--pool ] [--image ] [--shared ] + usage: rbd lock add [--pool ] [--namespace ] + [--image ] [--shared ] Take a lock on an image. Positional arguments image specification - (example: [/]) + (example: [/[/]]) unique lock id Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --shared arg shared lock tag rbd help lock list - usage: rbd lock list [--pool ] [--image ] [--format ] - [--pretty-format] + usage: rbd lock list [--pool ] [--namespace ] + [--image ] [--format ] [--pretty-format] Show locks held on an image. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --format arg output format (plain, json, or xml) [default: plain] --pretty-format pretty formatting (json and xml) rbd help lock remove - usage: rbd lock remove [--pool ] [--image ] + usage: rbd lock remove [--pool ] [--namespace ] + [--image ] Release a lock on an image. Positional arguments image specification - (example: [/]) + (example: [/[/]]) unique lock id locker client Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name rbd help merge-diff @@ -1091,90 +1210,102 @@ --no-progress disable progress output rbd help mirror image demote - usage: rbd mirror image demote [--pool ] [--image ] + usage: rbd mirror image demote [--pool ] [--namespace ] + [--image ] Demote an image to non-primary for RBD mirroring. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name rbd help mirror image disable - usage: rbd mirror image disable [--force] [--pool ] [--image ] + usage: rbd mirror image disable [--force] [--pool ] + [--namespace ] [--image ] Disable RBD mirroring for an image. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments --force disable even if not primary -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name rbd help mirror image enable - usage: rbd mirror image enable [--pool ] [--image ] + usage: rbd mirror image enable [--pool ] [--namespace ] + [--image ] Enable RBD mirroring for an image. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name rbd help mirror image promote - usage: rbd mirror image promote [--force] [--pool ] [--image ] + usage: rbd mirror image promote [--force] [--pool ] + [--namespace ] [--image ] Promote an image to primary for RBD mirroring. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments --force promote even if not cleanly demoted by remote cluster -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name rbd help mirror image resync - usage: rbd mirror image resync [--pool ] [--image ] + usage: rbd mirror image resync [--pool ] [--namespace ] + [--image ] Force resync to primary image for RBD mirroring. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name rbd help mirror image status - usage: rbd mirror image status [--pool ] [--image ] - [--format ] [--pretty-format] + usage: rbd mirror image status [--pool ] [--namespace ] + [--image ] [--format ] + [--pretty-format] Show RBD mirroring status for an image. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --format arg output format (plain, json, or xml) [default: plain] --pretty-format pretty formatting (json and xml) @@ -1321,19 +1452,16 @@ --namespace arg namespace name rbd help namespace list - usage: rbd namespace list [--pool ] [--namespace ] - [--format ] [--pretty-format] - + usage: rbd namespace list [--pool ] [--format ] [--pretty-format] + List RBD image namespaces. Positional arguments pool name - namespace name Optional arguments -p [ --pool ] arg pool name - --namespace arg namespace name --format arg output format (plain, json, or xml) [default: plain] --pretty-format pretty formatting (json and xml) @@ -1352,35 +1480,41 @@ --namespace arg namespace name rbd help object-map check - usage: rbd object-map check [--pool ] [--image ] [--snap ] - [--no-progress] + usage: rbd object-map check [--pool ] [--namespace ] + [--image ] [--snap ] [--no-progress] Verify the object map is correct. Positional arguments image or snapshot specification - (example: [/][@]) + (example: + [/[/]][@]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --snap arg snapshot name --no-progress disable progress output rbd help object-map rebuild - usage: rbd object-map rebuild [--pool ] [--image ] - [--snap ] [--no-progress] + usage: rbd object-map rebuild [--pool ] [--namespace ] + [--image ] [--snap ] [--no-progress] Rebuild an invalid object map. Positional arguments image or snapshot specification - (example: [/][@]) + (example: + [/[/]][@]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --snap arg snapshot name --no-progress disable progress output @@ -1400,103 +1534,119 @@ another application rbd help remove - usage: rbd remove [--pool ] [--image ] [--no-progress] + usage: rbd remove [--pool ] [--namespace ] [--image ] + [--no-progress] Delete an image. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --no-progress disable progress output rbd help rename - usage: rbd rename [--pool ] [--image ] [--dest-pool ] - [--dest ] + usage: rbd rename [--pool ] [--namespace ] [--image ] + [--dest-pool ] + [--dest-namespace ] [--dest ] Rename image within pool. Positional arguments source image specification - (example: [/]) + (example: [/[/]]) destination image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg source pool name + --namespace arg source namespace name --image arg source image name --dest-pool arg destination pool name + --dest-namespace arg destination namespace name --dest arg destination image name rbd help resize - usage: rbd resize [--pool ] [--image ] --size - [--allow-shrink] [--no-progress] + usage: rbd resize [--pool ] [--namespace ] + [--image ] --size [--allow-shrink] + [--no-progress] Resize (expand or shrink) image. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name -s [ --size ] arg image size (in M/G/T) [default: M] --allow-shrink permit shrinking --no-progress disable progress output rbd help snap create - usage: rbd snap create [--pool ] [--image ] [--snap ] + usage: rbd snap create [--pool ] [--namespace ] + [--image ] [--snap ] Create a snapshot. Positional arguments snapshot specification - (example: [/]@) + (example: + [/[/]]@) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --snap arg snapshot name rbd help snap limit clear - usage: rbd snap limit clear [--pool ] [--image ] + usage: rbd snap limit clear [--pool ] [--namespace ] + [--image ] Remove snapshot limit. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name rbd help snap limit set - usage: rbd snap limit set [--pool ] [--image ] [--limit ] + usage: rbd snap limit set [--pool ] [--namespace ] + [--image ] [--limit ] Limit the number of snapshots. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --limit arg maximum allowed snapshot count rbd help snap list - usage: rbd snap list [--pool ] [--image ] [--image-id ] + usage: rbd snap list [--pool ] [--namespace ] + [--image ] [--image-id ] [--format ] [--pretty-format] [--all] @@ -1504,10 +1654,11 @@ Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --image-id arg image id --format arg output format (plain, json, or xml) [default: plain] @@ -1515,50 +1666,59 @@ -a [ --all ] list snapshots from all namespaces rbd help snap protect - usage: rbd snap protect [--pool ] [--image ] [--snap ] + usage: rbd snap protect [--pool ] [--namespace ] + [--image ] [--snap ] Prevent a snapshot from being deleted. Positional arguments snapshot specification - (example: [/]@) + (example: + [/[/]]@) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --snap arg snapshot name rbd help snap purge - usage: rbd snap purge [--pool ] [--image ] - [--image-id ] [--no-progress] + usage: rbd snap purge [--pool ] [--namespace ] + [--image ] [--image-id ] [--no-progress] Delete all unprotected snapshots. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --image-id arg image id --no-progress disable progress output rbd help snap remove - usage: rbd snap remove [--pool ] [--image ] [--snap ] - [--no-progress] [--image-id ] [--force] + usage: rbd snap remove [--pool ] [--namespace ] + [--image ] [--snap ] [--no-progress] + [--image-id ] [--force] Delete a snapshot. Positional arguments snapshot specification - (example: [/]@) + (example: + [/[/]]@) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --snap arg snapshot name --no-progress disable progress output @@ -1566,8 +1726,10 @@ --force flatten children and unprotect snapshot if needed. rbd help snap rename - usage: rbd snap rename [--pool ] [--image ] [--snap ] - [--dest-pool ] [--dest ] + usage: rbd snap rename [--pool ] [--namespace ] + [--image ] [--snap ] + [--dest-pool ] + [--dest-namespace ] [--dest ] [--dest-snap ] @@ -1575,37 +1737,47 @@ Positional arguments source snapshot specification - (example: [/]@) + (example: + [/[/]]@) destination snapshot specification - (example: [/]@) + (example: + [/[/]]@) Optional arguments -p [ --pool ] arg source pool name + --namespace arg source namespace name --image arg source image name --snap arg source snapshot name --dest-pool arg destination pool name + --dest-namespace arg destination namespace name --dest arg destination image name --dest-snap arg destination snapshot name rbd help snap rollback - usage: rbd snap rollback [--pool ] [--image ] [--snap ] - [--no-progress] + usage: rbd snap rollback [--pool ] [--namespace ] + [--image ] [--snap ] [--no-progress] Rollback image to snapshot. Positional arguments snapshot specification - (example: [/]@) + (example: + [/[/]]@) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --snap arg snapshot name --no-progress disable progress output rbd help snap unprotect - usage: rbd snap unprotect [--pool ] [--image ] [--snap ] + usage: rbd snap unprotect [--pool ] [--namespace ] + [--image ] [--snap ] [--image-id ] @@ -1613,103 +1785,114 @@ Positional arguments snapshot specification - (example: [/]@) + (example: + [/[/]]@) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --snap arg snapshot name --image-id arg image id rbd help status - usage: rbd status [--pool ] [--image ] [--format ] - [--pretty-format] + usage: rbd status [--pool ] [--namespace ] [--image ] + [--format ] [--pretty-format] Show the status of this image. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --format arg output format (plain, json, or xml) [default: plain] --pretty-format pretty formatting (json and xml) rbd help trash list - usage: rbd trash list [--pool ] [--all] [--long] [--format ] - [--pretty-format] - + usage: rbd trash list [--pool ] [--namespace ] [--all] + [--long] [--format ] [--pretty-format] + List trash images. Positional arguments pool name + namespace name Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name -a [ --all ] list images from all sources -l [ --long ] long listing format --format arg output format (plain, json, or xml) [default: plain] --pretty-format pretty formatting (json and xml) rbd help trash move - usage: rbd trash move [--pool ] [--image ] - [--expires-at ] + usage: rbd trash move [--pool ] [--namespace ] + [--image ] [--expires-at ] Move an image to the trash. Positional arguments image specification - (example: [/]) + (example: + [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name --expires-at arg (=now) set the expiration time of an image so it can be purged when it is stale rbd help trash purge - usage: rbd trash purge [--pool ] [--no-progress] - [--expired-before ] + usage: rbd trash purge [--pool ] [--namespace ] + [--no-progress] [--expired-before ] [--threshold ] - + Remove all expired images from trash. Positional arguments pool name + namespace name Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --no-progress disable progress output --expired-before date purges images that expired before the given date --threshold arg purges images until the current pool data usage is reduced to X%, value range: 0.0-1.0 rbd help trash remove - usage: rbd trash remove [--pool ] [--image-id ] - [--no-progress] [--force] + usage: rbd trash remove [--pool ] [--namespace ] + [--image-id ] [--no-progress] [--force] Remove an image from trash. Positional arguments image id - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image-id arg image id --no-progress disable progress output --force force remove of non-expired delayed images rbd help trash restore - usage: rbd trash restore [--pool ] [--image-id ] - [--image ] + usage: rbd trash restore [--pool ] [--namespace ] + [--image-id ] [--image ] Restore an image from trash. @@ -1720,20 +1903,22 @@ Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image-id arg image id --image arg image name rbd help watch - usage: rbd watch [--pool ] [--image ] + usage: rbd watch [--pool ] [--namespace ] [--image ] Watch events on image. Positional arguments image specification - (example: [/]) + (example: [/[/]]) Optional arguments -p [ --pool ] arg pool name + --namespace arg namespace name --image arg image name diff --git a/src/test/cli/rbd/invalid-snap-usage.t b/src/test/cli/rbd/invalid-snap-usage.t index 176092800e502..920c3c223efab 100644 --- a/src/test/cli/rbd/invalid-snap-usage.t +++ b/src/test/cli/rbd/invalid-snap-usage.t @@ -1,115 +1,115 @@ $ rbd create foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd flatten foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd resize foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd rm foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd import-diff /tmp/diff foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd mv foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd mv foo@snap bar - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd mv foo@snap bar@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd image-meta list foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd image-meta get foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd image-meta get foo@snap key - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd image-meta set foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd image-meta set foo@snap key - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd image-meta set foo@snap key val - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd image-meta remove foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd image-meta remove foo@snap key - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd snap ls foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd snap purge foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd watch foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd status foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd feature disable foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd feature disable foo@snap layering - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd feature enable foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd feature enable foo@snap layering - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd lock list foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd lock add foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd lock add foo@snap id - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd lock remove foo@snap - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd lock remove foo@snap id - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd lock remove foo@snap id client.1234 - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd bench foo@snap --io-type write - rbd: snapname specified for a command that doesn't use it + rbd: snapshot name specified for a command that doesn't use it [22] $ rbd clone foo@snap bar@snap - rbd: destination snapname specified for a command that doesn't use it + rbd: destination snapshot name specified for a command that doesn't use it [22] $ rbd import /bin/ls ls@snap - rbd: destination snapname specified for a command that doesn't use it + rbd: destination snapshot name specified for a command that doesn't use it [22] $ rbd cp foo bar@snap - rbd: destination snapname specified for a command that doesn't use it + rbd: destination snapshot name specified for a command that doesn't use it [22] $ rbd cp foo@snap bar@snap - rbd: destination snapname specified for a command that doesn't use it + rbd: destination snapshot name specified for a command that doesn't use it [22] $ rbd deep cp foo bar@snap - rbd: destination snapname specified for a command that doesn't use it + rbd: destination snapshot name specified for a command that doesn't use it [22] $ rbd deep cp foo@snap bar@snap - rbd: destination snapname specified for a command that doesn't use it + rbd: destination snapshot name specified for a command that doesn't use it [22] $ rbd mv foo bar@snap - rbd: destination snapname specified for a command that doesn't use it + rbd: destination snapshot name specified for a command that doesn't use it [22] diff --git a/src/test/cli/rbd/not-enough-args.t b/src/test/cli/rbd/not-enough-args.t index 2fb1df8059674..cc9078b83328a 100644 --- a/src/test/cli/rbd/not-enough-args.t +++ b/src/test/cli/rbd/not-enough-args.t @@ -8,22 +8,22 @@ rbd: image name was not specified [22] $ rbd clone foo - rbd: snap name was not specified + rbd: snapshot name was not specified [22] $ rbd clone foo@snap rbd: destination image name was not specified [22] $ rbd clone foo bar - rbd: snap name was not specified + rbd: snapshot name was not specified [22] $ rbd clone foo bar@snap - rbd: snap name was not specified + rbd: snapshot name was not specified [22] $ rbd children rbd: image name was not specified [22] $ rbd children foo - rbd: snap name was not specified + rbd: snapshot name was not specified [22] $ rbd flatten rbd: image name was not specified @@ -125,19 +125,19 @@ rbd: image name was not specified [22] $ rbd snap create foo - rbd: snap name was not specified + rbd: snapshot name was not specified [22] $ rbd snap rollback rbd: image name was not specified [22] $ rbd snap rollback foo - rbd: snap name was not specified + rbd: snapshot name was not specified [22] $ rbd snap rm rbd: image name was not specified [22] $ rbd snap rm foo - rbd: snap name was not specified + rbd: snapshot name was not specified [22] $ rbd snap purge rbd: image name was not specified @@ -146,13 +146,13 @@ rbd: image name was not specified [22] $ rbd snap protect foo - rbd: snap name was not specified + rbd: snapshot name was not specified [22] $ rbd snap unprotect rbd: image name was not specified [22] $ rbd snap unprotect foo - rbd: snap name was not specified + rbd: snapshot name was not specified [22] $ rbd watch rbd: image name was not specified diff --git a/src/tools/rbd/ArgumentTypes.cc b/src/tools/rbd/ArgumentTypes.cc index 1dfe6205851b1..ca87bfea0ef50 100644 --- a/src/tools/rbd/ArgumentTypes.cc +++ b/src/tools/rbd/ArgumentTypes.cc @@ -60,15 +60,6 @@ std::string get_description_prefix(ArgumentModifier modifier) { } } -void add_special_pool_option(po::options_description *opt, - const std::string &prefix) { - std::string name = prefix + "-" + POOL_NAME; - std::string description = prefix + " pool name"; - - opt->add_options() - (name.c_str(), po::value(), description.c_str()); -} - void add_pool_option(po::options_description *opt, ArgumentModifier modifier, const std::string &desc_suffix) { @@ -103,7 +94,7 @@ void add_namespace_option(boost::program_options::options_description *opt, description = "source " + description; break; case ARGUMENT_MODIFIER_DEST: - name = DEST_POOL_NAME; + name = DEST_NAMESPACE_NAME; description = "destination " + description; break; } @@ -147,29 +138,6 @@ void add_image_id_option(po::options_description *opt, (name.c_str(), po::value(), description.c_str()); } -void add_group_option(po::options_description *opt, - ArgumentModifier modifier, - const std::string &desc_suffix) { - std::string name = GROUP_NAME; - std::string description = "group name"; - switch (modifier) { - case ARGUMENT_MODIFIER_NONE: - break; - case ARGUMENT_MODIFIER_SOURCE: - description = "source " + description; - break; - case ARGUMENT_MODIFIER_DEST: - name = DEST_GROUP_NAME; - description = "destination " + description; - break; - } - description += desc_suffix; - - // TODO add validator - opt->add_options() - (name.c_str(), po::value(), description.c_str()); -} - void add_snap_option(po::options_description *opt, ArgumentModifier modifier) { @@ -197,29 +165,6 @@ void add_snap_id_option(po::options_description *opt) { (SNAPSHOT_ID.c_str(), po::value(), "snapshot id"); } -void add_journal_option(po::options_description *opt, - ArgumentModifier modifier, - const std::string &desc_suffix) { - std::string name = JOURNAL_NAME; - std::string description = "journal name"; - switch (modifier) { - case ARGUMENT_MODIFIER_NONE: - break; - case ARGUMENT_MODIFIER_SOURCE: - description = "source " + description; - break; - case ARGUMENT_MODIFIER_DEST: - name = DEST_JOURNAL_NAME; - description = "destination " + description; - break; - } - description += desc_suffix; - - // TODO add validator - opt->add_options() - (name.c_str(), po::value(), description.c_str()); -} - void add_pool_options(boost::program_options::options_description *pos, boost::program_options::options_description *opt) { pos->add_options() @@ -230,8 +175,10 @@ void add_pool_options(boost::program_options::options_description *pos, void add_namespace_options(boost::program_options::options_description *pos, boost::program_options::options_description *opt) { - pos->add_options() - ("namespace-name", "namespace name"); + if (pos != nullptr) { + pos->add_options() + ("namespace-name", "namespace name"); + } add_namespace_option(opt, ARGUMENT_MODIFIER_NONE); } @@ -241,39 +188,21 @@ void add_image_spec_options(po::options_description *pos, pos->add_options() ((get_name_prefix(modifier) + IMAGE_SPEC).c_str(), (get_description_prefix(modifier) + "image specification\n" + - "(example: [/])").c_str()); + "(example: [/[/]])").c_str()); add_pool_option(opt, modifier); + add_namespace_option(opt, modifier); add_image_option(opt, modifier); } -void add_group_spec_options(po::options_description *pos, - po::options_description *opt, - ArgumentModifier modifier, - bool snap) { - add_pool_option(opt, modifier); - add_group_option(opt, modifier); - if (!snap) { - pos->add_options() - ((get_name_prefix(modifier) + GROUP_SPEC).c_str(), - (get_description_prefix(modifier) + "group specification\n" + - "(example: [/])").c_str()); - } else { - add_snap_option(opt, modifier); - pos->add_options() - ((get_name_prefix(modifier) + GROUP_SNAP_SPEC).c_str(), - (get_description_prefix(modifier) + "group specification\n" + - "(example: [/]@)").c_str()); - } -} - void add_snap_spec_options(po::options_description *pos, po::options_description *opt, ArgumentModifier modifier) { pos->add_options() ((get_name_prefix(modifier) + SNAPSHOT_SPEC).c_str(), (get_description_prefix(modifier) + "snapshot specification\n" + - "(example: [/]@)").c_str()); + "(example: [/[/]]@)").c_str()); add_pool_option(opt, modifier); + add_namespace_option(opt, modifier); add_image_option(opt, modifier); add_snap_option(opt, modifier); } @@ -284,25 +213,13 @@ void add_image_or_snap_spec_options(po::options_description *pos, pos->add_options() ((get_name_prefix(modifier) + IMAGE_OR_SNAPSHOT_SPEC).c_str(), (get_description_prefix(modifier) + "image or snapshot specification\n" + - "(example: [/][@])").c_str()); + "(example: [/[/]][@])").c_str()); add_pool_option(opt, modifier); + add_namespace_option(opt, modifier); add_image_option(opt, modifier); add_snap_option(opt, modifier); } -void add_journal_spec_options(po::options_description *pos, - po::options_description *opt, - ArgumentModifier modifier) { - - pos->add_options() - ((get_name_prefix(modifier) + JOURNAL_SPEC).c_str(), - (get_description_prefix(modifier) + "journal specification\n" + - "(example: [/])").c_str()); - add_pool_option(opt, modifier); - add_image_option(opt, modifier); - add_journal_option(opt, modifier); -} - void add_create_image_options(po::options_description *opt, bool include_format) { // TODO get default image format from conf @@ -487,7 +404,7 @@ void validate(boost::any& v, const std::vector& values, ImageObjectSize *target_type, int dummy) { po::validators::check_first_occurrence(v); const std::string &s = po::validators::get_single_string(values); - + std::string parse_error; uint64_t objectsize = strict_iecstrtoll(s.c_str(), &parse_error); if (!parse_error.empty()) { diff --git a/src/tools/rbd/ArgumentTypes.h b/src/tools/rbd/ArgumentTypes.h index f9e44d588893c..12de0341e68ea 100644 --- a/src/tools/rbd/ArgumentTypes.h +++ b/src/tools/rbd/ArgumentTypes.h @@ -36,11 +36,8 @@ static const std::string DEST_PREFIX("dest-"); static const std::string POSITIONAL_COMMAND_SPEC("positional-command-spec"); static const std::string POSITIONAL_ARGUMENTS("positional-arguments"); static const std::string IMAGE_SPEC("image-spec"); -static const std::string GROUP_SPEC("group-spec"); -static const std::string GROUP_SNAP_SPEC("group-snap-spec"); static const std::string SNAPSHOT_SPEC("snap-spec"); static const std::string IMAGE_OR_SNAPSHOT_SPEC("image-or-snap-spec"); -static const std::string JOURNAL_SPEC("journal-spec"); static const std::string PATH_NAME("path-name"); static const std::string IMAGE_ID("image-id"); @@ -48,19 +45,16 @@ static const std::string IMAGE_ID("image-id"); static const std::string CONFIG_PATH("conf"); static const std::string POOL_NAME("pool"); static const std::string DEST_POOL_NAME("dest-pool"); +static const std::string NAMESPACE_NAME("namespace"); +static const std::string DEST_NAMESPACE_NAME("dest-namespace"); static const std::string IMAGE_NAME("image"); static const std::string DEST_IMAGE_NAME("dest"); -static const std::string GROUP_NAME("group"); -static const std::string DEST_GROUP_NAME("dest-group"); static const std::string SNAPSHOT_NAME("snap"); static const std::string SNAPSHOT_ID("snap-id"); static const std::string DEST_SNAPSHOT_NAME("dest-snap"); -static const std::string JOURNAL_NAME("journal"); -static const std::string DEST_JOURNAL_NAME("dest-journal"); static const std::string PATH("path"); static const std::string FROM_SNAPSHOT_NAME("from-snap"); static const std::string WHOLE_OBJECT("whole-object"); -static const std::string NAMESPACE_NAME("namespace"); static const std::string IMAGE_FORMAT("image-format"); static const std::string IMAGE_NEW_FORMAT("new-format"); @@ -128,10 +122,6 @@ void add_export_format_option(boost::program_options::options_description *opt); std::string get_name_prefix(ArgumentModifier modifier); std::string get_description_prefix(ArgumentModifier modifier); - -void add_special_pool_option(boost::program_options::options_description *opt, - const std::string &prefix); - void add_all_option(boost::program_options::options_description *opt, std::string description); @@ -148,18 +138,10 @@ void add_image_option(boost::program_options::options_description *opt, void add_image_id_option(boost::program_options::options_description *opt, const std::string &desc_suffix = ""); -void add_group_option(boost::program_options::options_description *opt, - ArgumentModifier modifier, - const std::string &desc_suffix = ""); - void add_snap_option(boost::program_options::options_description *opt, ArgumentModifier modifier); void add_snap_id_option(boost::program_options::options_description *opt); -void add_journal_option(boost::program_options::options_description *opt, - ArgumentModifier modifier, - const std::string &desc_suffix = ""); - void add_pool_options(boost::program_options::options_description *pos, boost::program_options::options_description *opt); void add_namespace_options(boost::program_options::options_description *pos, @@ -169,10 +151,6 @@ void add_image_spec_options(boost::program_options::options_description *pos, boost::program_options::options_description *opt, ArgumentModifier modifier); -void add_group_spec_options(boost::program_options::options_description *pos, - boost::program_options::options_description *opt, - ArgumentModifier modifier, bool snap); - void add_snap_spec_options(boost::program_options::options_description *pos, boost::program_options::options_description *opt, ArgumentModifier modifier); @@ -182,11 +160,6 @@ void add_image_or_snap_spec_options( boost::program_options::options_description *opt, ArgumentModifier modifier); -void add_journal_spec_options( - boost::program_options::options_description *pos, - boost::program_options::options_description *opt, - ArgumentModifier modifier); - void add_create_image_options(boost::program_options::options_description *opt, bool include_format); diff --git a/src/tools/rbd/Utils.cc b/src/tools/rbd/Utils.cc index d368d5ab11bac..3515e28255205 100644 --- a/src/tools/rbd/Utils.cc +++ b/src/tools/rbd/Utils.cc @@ -82,8 +82,8 @@ int read_string(int fd, unsigned max, std::string *out) { } int extract_spec(const std::string &spec, std::string *pool_name, - std::string *image_name, std::string *snap_name, - SpecValidation spec_validation) { + std::string *namespace_name, std::string *name, + std::string *snap_name, SpecValidation spec_validation) { if (!g_ceph_context->_conf->get_val("rbd_validate_names")) { spec_validation = SPEC_VALIDATION_NONE; } @@ -91,17 +91,17 @@ int extract_spec(const std::string &spec, std::string *pool_name, std::regex pattern; switch (spec_validation) { case SPEC_VALIDATION_FULL: - // disallow "/" and "@" in image and snap name - pattern = "^(?:([^/@]+)/)?([^/@]+)(?:@([^/@]+))?$"; + // disallow "/" and "@" in all names + pattern = "^(?:([^/@]+)/(?:([^/@]+)/)?)?([^/@]+)(?:@([^/@]+))?$"; break; case SPEC_VALIDATION_SNAP: // disallow "/" and "@" in snap name - pattern = "^(?:([^/]+)/)?([^@]+)(?:@([^/@]+))?$"; + pattern = "^(?:([^/]+)/(?:([^/@]+)/)?)?([^@]+)(?:@([^/@]+))?$"; break; case SPEC_VALIDATION_NONE: - // relaxed pattern assumes pool is before first "/" and snap - // name is after first "@" - pattern = "^(?:([^/]+)/)?([^@]+)(?:@(.+))?$"; + // relaxed pattern assumes pool is before first "/", + // namespace is before second "/", and snap name is after first "@" + pattern = "^(?:([^/]+)/(?:([^/@]+)/)?)?([^@]+)(?:@(.+))?$"; break; default: ceph_abort(); @@ -114,66 +114,39 @@ int extract_spec(const std::string &spec, std::string *pool_name, return -EINVAL; } - if (pool_name != nullptr && match[1].matched) { - *pool_name = match[1]; - } - if (image_name != nullptr) { - *image_name = match[2]; - } - if (snap_name != nullptr && match[3].matched) { - *snap_name = match[3]; - } - return 0; -} - -int extract_group_spec(const std::string &spec, - std::string *pool_name, - std::string *group_name, - std::string *snap_name) { - std::regex pattern; - if (snap_name == nullptr) { - pattern = "^(?:([^/@]+)/)?([^/@]+)?$"; - } else { - pattern = "^(?:([^/@]+)/)?([^/@]+)(?:@([^/@]+))?$"; + if (match[1].matched) { + if (pool_name != nullptr) { + *pool_name = match[1]; + } else { + std::cerr << "rbd: pool name specified for a command that doesn't use it" + << std::endl; + return -EINVAL; + } } - std::smatch match; - if (!std::regex_match(spec, match, pattern)) { - std::cerr << "rbd: invalid spec '" << spec << "'" << std::endl; - return -EINVAL; + if (match[2].matched) { + if (namespace_name != nullptr) { + *namespace_name = match[2]; + } else { + std::cerr << "rbd: namespace name specified for a command that doesn't " + << "use it" << std::endl; + return -EINVAL; + } } - if (pool_name != nullptr && match[1].matched) { - *pool_name = match[1]; - } - if (group_name != nullptr) { - *group_name = match[2]; - } - if (snap_name != nullptr && match[3].matched) { - *snap_name = match[3]; + if (name != nullptr) { + *name = match[3]; } - return 0; -} - -int extract_image_id_spec(const std::string &spec, std::string *pool_name, - std::string *image_id) { - std::regex pattern; - pattern = "^(?:([^/]+)/)?(.+)?$"; - - std::smatch match; - if (!std::regex_match(spec, match, pattern)) { - std::cerr << "rbd: invalid spec '" << spec << "'" << std::endl; - return -EINVAL; - } - - if (pool_name != nullptr && match[1].matched) { - *pool_name = match[1]; - } - if (image_id != nullptr) { - *image_id = match[2]; + if (match[4].matched) { + if (snap_name != nullptr) { + *snap_name = match[4]; + } else { + std::cerr << "rbd: snapshot name specified for a command that doesn't " + << "use it" << std::endl; + return -EINVAL; + } } - return 0; } @@ -217,7 +190,7 @@ std::string get_namespace_name(const boost::program_options::variables_map &vm, std::string namespace_name; if (vm.count(at::NAMESPACE_NAME)) { namespace_name = vm[at::NAMESPACE_NAME].as(); - } else { + } else if (arg_index != nullptr) { namespace_name = get_positional_argument(vm, *arg_index); if (!namespace_name.empty()) { ++(*arg_index); @@ -227,109 +200,18 @@ std::string get_namespace_name(const boost::program_options::variables_map &vm, return namespace_name; } -int get_special_pool_group_names(const po::variables_map &vm, - size_t *arg_index, - std::string *group_pool_name, - std::string *group_name) { - if (nullptr == group_pool_name) return -EINVAL; - if (nullptr == group_name) return -EINVAL; - std::string pool_key = at::POOL_NAME; - - std::string group_pool_key = "group-" + at::POOL_NAME; - std::string group_key = at::GROUP_NAME; - - if (vm.count(group_pool_key)) { - *group_pool_name = vm[group_pool_key].as(); - } - - if (vm.count(group_key)) { - *group_name = vm[group_key].as(); - } - - int r; - if (group_name->empty()) { - std::string spec = utils::get_positional_argument(vm, (*arg_index)++); - if (!spec.empty()) { - r = extract_group_spec(spec, group_pool_name, group_name, nullptr); - if (r < 0) { - return r; - } - } - } - - if (group_pool_name->empty() && vm.count(pool_key)) { - *group_pool_name = vm[pool_key].as(); - } - - if (group_pool_name->empty()) { - *group_pool_name = get_default_pool_name(); - } - - if (group_name->empty()) { - std::cerr << "rbd: group name was not specified" << std::endl; - return -EINVAL; - } - - return 0; -} - -int get_special_pool_image_names(const po::variables_map &vm, - size_t *arg_index, - std::string *image_pool_name, - std::string *image_name) { - if (nullptr == image_pool_name) return -EINVAL; - if (nullptr == image_name) return -EINVAL; - - std::string pool_key = at::POOL_NAME; - - std::string image_pool_key = "image-" + at::POOL_NAME; - std::string image_key = at::IMAGE_NAME; - - if (vm.count(image_pool_key)) { - *image_pool_name = vm[image_pool_key].as(); - } - - if (vm.count(image_key)) { - *image_name = vm[image_key].as(); - } - - int r; - if (image_name->empty()) { - std::string spec = utils::get_positional_argument(vm, (*arg_index)++); - if (!spec.empty()) { - r = utils::extract_spec(spec, image_pool_name, - image_name, nullptr, - utils::SPEC_VALIDATION_NONE); - if (r < 0) { - return r; - } - } - } - - if (image_pool_name->empty() && vm.count(pool_key)) { - *image_pool_name = vm[pool_key].as(); - } - - if (image_pool_name->empty()) { - *image_pool_name = get_default_pool_name(); - } - - if (image_name->empty()) { - std::cerr << "rbd: image name was not specified" << std::endl; - return -EINVAL; - } - - return 0; -} - int get_pool_image_id(const po::variables_map &vm, - size_t *spec_arg_index, - std::string *pool_name, - std::string *image_id) { + size_t *spec_arg_index, + std::string *pool_name, + std::string *namespace_name, + std::string *image_id) { if (vm.count(at::POOL_NAME) && pool_name != nullptr) { *pool_name = vm[at::POOL_NAME].as(); } + if (vm.count(at::NAMESPACE_NAME) && namespace_name != nullptr) { + *namespace_name = vm[at::NAMESPACE_NAME].as(); + } if (vm.count(at::IMAGE_ID) && image_id != nullptr) { *image_id = vm[at::IMAGE_ID].as(); } @@ -338,7 +220,8 @@ int get_pool_image_id(const po::variables_map &vm, if (image_id != nullptr && spec_arg_index != nullptr && image_id->empty()) { std::string spec = get_positional_argument(vm, (*spec_arg_index)++); if (!spec.empty()) { - r = extract_image_id_spec(spec, pool_name, image_id); + r = extract_spec(spec, pool_name, namespace_name, image_id, nullptr, + SPEC_VALIDATION_FULL); if (r < 0) { return r; } @@ -357,103 +240,77 @@ int get_pool_image_id(const po::variables_map &vm, return 0; } -int get_pool_group_names(const po::variables_map &vm, - at::ArgumentModifier mod, - size_t *spec_arg_index, - std::string *pool_name, - std::string *group_name, - std::string *snap_name) { - std::string pool_key = (mod == at::ARGUMENT_MODIFIER_DEST ? - at::DEST_POOL_NAME : at::POOL_NAME); - std::string group_key = (mod == at::ARGUMENT_MODIFIER_DEST ? - at::DEST_GROUP_NAME : at::GROUP_NAME); - - if (vm.count(pool_key) && pool_name != nullptr) { - *pool_name = vm[pool_key].as(); - } - if (vm.count(group_key) && group_name != nullptr) { - *group_name = vm[group_key].as(); - } - - if (vm.count(at::SNAPSHOT_NAME) && snap_name != nullptr) { - *snap_name = vm[at::SNAPSHOT_NAME].as(); - } - - int r; - if (group_name != nullptr && spec_arg_index != nullptr && - group_name->empty()) { - std::string spec = get_positional_argument(vm, (*spec_arg_index)++); - if (!spec.empty()) { - r = extract_group_spec(spec, pool_name, group_name, snap_name); - if (r < 0) { - return r; - } - } - } - - if (pool_name != nullptr && pool_name->empty()) { - *pool_name = get_default_pool_name(); - } - - if (group_name != nullptr && group_name->empty()) { - std::string prefix = at::get_description_prefix(mod); - std::cerr << "rbd: " - << (mod == at::ARGUMENT_MODIFIER_DEST ? prefix : std::string()) - << "group name was not specified" << std::endl; - return -EINVAL; - } - - if (snap_name != nullptr && snap_name->empty()) { - std::cerr << "rbd: snapshot name was not specified" << std::endl; - return -EINVAL; - } - - return 0; -} - int get_pool_image_snapshot_names(const po::variables_map &vm, at::ArgumentModifier mod, size_t *spec_arg_index, std::string *pool_name, + std::string *namespace_name, std::string *image_name, std::string *snap_name, + bool image_name_required, SnapshotPresence snapshot_presence, - SpecValidation spec_validation, - bool image_required) { + SpecValidation spec_validation) { std::string pool_key = (mod == at::ARGUMENT_MODIFIER_DEST ? at::DEST_POOL_NAME : at::POOL_NAME); std::string image_key = (mod == at::ARGUMENT_MODIFIER_DEST ? at::DEST_IMAGE_NAME : at::IMAGE_NAME); + return get_pool_generic_snapshot_names(vm, mod, spec_arg_index, pool_key, + pool_name, namespace_name, image_key, + "image", image_name, snap_name, + image_name_required, snapshot_presence, + spec_validation); +} + +int get_pool_generic_snapshot_names(const po::variables_map &vm, + at::ArgumentModifier mod, + size_t *spec_arg_index, + const std::string& pool_key, + std::string *pool_name, + std::string *namespace_name, + const std::string& generic_key, + const std::string& generic_key_desc, + std::string *generic_name, + std::string *snap_name, + bool generic_name_required, + SnapshotPresence snapshot_presence, + SpecValidation spec_validation) { + std::string namespace_key = (mod == at::ARGUMENT_MODIFIER_DEST ? + at::DEST_NAMESPACE_NAME : at::NAMESPACE_NAME); std::string snap_key = (mod == at::ARGUMENT_MODIFIER_DEST ? - at::DEST_SNAPSHOT_NAME : at::SNAPSHOT_NAME); + at::DEST_SNAPSHOT_NAME : at::SNAPSHOT_NAME); if (vm.count(pool_key) && pool_name != nullptr) { *pool_name = vm[pool_key].as(); } - if (vm.count(image_key) && image_name != nullptr) { - *image_name = vm[image_key].as(); + if (vm.count(namespace_key) && namespace_name != nullptr) { + *namespace_name = vm[namespace_key].as(); + } + if (vm.count(generic_key) && generic_name != nullptr) { + *generic_name = vm[generic_key].as(); } if (vm.count(snap_key) && snap_name != nullptr) { - *snap_name = vm[snap_key].as(); + *snap_name = vm[snap_key].as(); } int r; - if (image_name != nullptr && !image_name->empty()) { + if ((generic_key == at::IMAGE_NAME || generic_key == at::DEST_IMAGE_NAME) && + generic_name != nullptr && !generic_name->empty()) { // despite the separate pool and snapshot name options, // we can also specify them via the image option - std::string image_name_copy(*image_name); - r = extract_spec(image_name_copy, pool_name, image_name, snap_name, - spec_validation); + std::string image_name_copy(*generic_name); + r = extract_spec(image_name_copy, pool_name, namespace_name, generic_name, + snap_name, spec_validation); if (r < 0) { return r; } } - if (image_name != nullptr && spec_arg_index != nullptr && - image_name->empty()) { + if (generic_name != nullptr && spec_arg_index != nullptr && + generic_name->empty()) { std::string spec = get_positional_argument(vm, (*spec_arg_index)++); if (!spec.empty()) { - r = extract_spec(spec, pool_name, image_name, snap_name, spec_validation); + r = extract_spec(spec, pool_name, namespace_name, generic_name, snap_name, + spec_validation); if (r < 0) { return r; } @@ -464,164 +321,38 @@ int get_pool_image_snapshot_names(const po::variables_map &vm, *pool_name = get_default_pool_name(); } - if (image_name != nullptr && image_required && image_name->empty()) { + if (generic_name != nullptr && generic_name_required && + generic_name->empty()) { std::string prefix = at::get_description_prefix(mod); std::cerr << "rbd: " << (mod == at::ARGUMENT_MODIFIER_DEST ? prefix : std::string()) - << "image name was not specified" << std::endl; + << generic_key_desc << " name was not specified" << std::endl; return -EINVAL; } - //Validate pool name while creating/renaming/copying/cloning/importing/etc + std::regex pattern("^[^@/]+?$"); if (spec_validation == SPEC_VALIDATION_FULL) { - std::regex pattern("^[^@/]+?$"); + // validate pool name while creating/renaming/copying/cloning/importing/etc if ((pool_name != nullptr) && !std::regex_match (*pool_name, pattern)) { std::cerr << "rbd: invalid pool name '" << *pool_name << "'" << std::endl; return -EINVAL; } } - if (snap_name != nullptr) { - r = validate_snapshot_name(mod, *snap_name, snapshot_presence, - spec_validation); - if (r < 0) { - return r; - } - } - return 0; -} - -int get_pool_snapshot_names(const po::variables_map &vm, - at::ArgumentModifier mod, - size_t *spec_arg_index, - std::string *pool_name, - std::string *snap_name, - SnapshotPresence snapshot_presence, - SpecValidation spec_validation) { - std::string pool_key = (mod == at::ARGUMENT_MODIFIER_DEST ? - at::DEST_POOL_NAME : at::POOL_NAME); - std::string snap_key = (mod == at::ARGUMENT_MODIFIER_DEST ? - at::DEST_SNAPSHOT_NAME : at::SNAPSHOT_NAME); - - if (vm.count(pool_key) && pool_name != nullptr) { - *pool_name = vm[pool_key].as(); - } - if (vm.count(snap_key) && snap_name != nullptr) { - *snap_name = vm[snap_key].as(); - } - - if (pool_name != nullptr && pool_name->empty()) { - *pool_name = get_default_pool_name(); + if (namespace_name != nullptr && !namespace_name->empty() && + !std::regex_match (*namespace_name, pattern)) { + std::cerr << "rbd: invalid namespace name '" << *namespace_name << "'" + << std::endl; + return -EINVAL; } if (snap_name != nullptr) { - int r = validate_snapshot_name(mod, *snap_name, snapshot_presence, - spec_validation); - if (r < 0) { - return r; - } - } - return 0; -} - -int get_pool_journal_names(const po::variables_map &vm, - at::ArgumentModifier mod, - size_t *spec_arg_index, - std::string *pool_name, - std::string *journal_name) { - std::string pool_key = (mod == at::ARGUMENT_MODIFIER_DEST ? - at::DEST_POOL_NAME : at::POOL_NAME); - std::string image_key = (mod == at::ARGUMENT_MODIFIER_DEST ? - at::DEST_IMAGE_NAME : at::IMAGE_NAME); - std::string journal_key = (mod == at::ARGUMENT_MODIFIER_DEST ? - at::DEST_JOURNAL_NAME : at::JOURNAL_NAME); - - if (vm.count(pool_key) && pool_name != nullptr) { - *pool_name = vm[pool_key].as(); - } - if (vm.count(journal_key) && journal_name != nullptr) { - *journal_name = vm[journal_key].as(); - } - - std::string image_name; - if (vm.count(image_key)) { - image_name = vm[image_key].as(); - } - - int r; - if (journal_name != nullptr && !journal_name->empty()) { - // despite the separate pool option, - // we can also specify them via the journal option - std::string journal_name_copy(*journal_name); - r = extract_spec(journal_name_copy, pool_name, journal_name, nullptr, - SPEC_VALIDATION_FULL); - if (r < 0) { - return r; - } - } - - if (!image_name.empty()) { - // despite the separate pool option, - // we can also specify them via the image option - std::string image_name_copy(image_name); - r = extract_spec(image_name_copy, pool_name, &image_name, nullptr, - SPEC_VALIDATION_NONE); - if (r < 0) { - return r; - } - } - - if (journal_name != nullptr && spec_arg_index != nullptr && - journal_name->empty()) { - std::string spec = get_positional_argument(vm, (*spec_arg_index)++); - if (!spec.empty()) { - r = extract_spec(spec, pool_name, journal_name, nullptr, - SPEC_VALIDATION_FULL); - if (r < 0) { - return r; - } - } - } - - if (pool_name != nullptr && pool_name->empty()) { - *pool_name = get_default_pool_name(); - } - - if (pool_name != nullptr && journal_name != nullptr && - journal_name->empty() && !image_name.empty()) { - // Try to get journal name from image info. - librados::Rados rados; - librados::IoCtx io_ctx; - librbd::Image image; - int r = init_and_open_image(*pool_name, image_name, "", "", true, &rados, - &io_ctx, &image); - if (r < 0) { - std::cerr << "rbd: failed to open image " << image_name - << " to get journal name: " << cpp_strerror(r) << std::endl; - return r; - } - - uint64_t features; - r = image.features(&features); + r = validate_snapshot_name(mod, *snap_name, snapshot_presence, + spec_validation); if (r < 0) { return r; } - if ((features & RBD_FEATURE_JOURNALING) == 0) { - std::cerr << "rbd: journaling is not enabled for image " << image_name - << std::endl; - return -EINVAL; - } - *journal_name = image_id(image); } - - if (journal_name != nullptr && journal_name->empty()) { - std::string prefix = at::get_description_prefix(mod); - std::cerr << "rbd: " - << (mod == at::ARGUMENT_MODIFIER_DEST ? prefix : std::string()) - << "journal was not specified" << std::endl; - return -EINVAL; - } - return 0; } @@ -637,7 +368,7 @@ int validate_snapshot_name(at::ArgumentModifier mod, if (!snap_name.empty()) { std::cerr << "rbd: " << (mod == at::ARGUMENT_MODIFIER_DEST ? prefix : std::string()) - << "snapname specified for a command that doesn't use it" + << "snapshot name specified for a command that doesn't use it" << std::endl; return -EINVAL; } @@ -646,7 +377,7 @@ int validate_snapshot_name(at::ArgumentModifier mod, if (snap_name.empty()) { std::cerr << "rbd: " << (mod == at::ARGUMENT_MODIFIER_DEST ? prefix : std::string()) - << "snap name was not specified" << std::endl; + << "snapshot name was not specified" << std::endl; return -EINVAL; } break; @@ -895,8 +626,8 @@ void init_context() { common_init_finish(g_ceph_context); } -int init(const std::string &pool_name, librados::Rados *rados, - librados::IoCtx *io_ctx) { +int init(const std::string &pool_name, const std::string& namespace_name, + librados::Rados *rados, librados::IoCtx *io_ctx) { init_context(); int r = rados->init_with_context(g_ceph_context); @@ -911,7 +642,7 @@ int init(const std::string &pool_name, librados::Rados *rados, return r; } - r = init_io_ctx(*rados, pool_name, io_ctx); + r = init_io_ctx(*rados, pool_name, namespace_name, io_ctx); if (r < 0) { return r; } @@ -919,7 +650,7 @@ int init(const std::string &pool_name, librados::Rados *rados, } int init_io_ctx(librados::Rados &rados, const std::string &pool_name, - librados::IoCtx *io_ctx) { + const std::string& namespace_name, librados::IoCtx *io_ctx) { int r = rados.ioctx_create(pool_name.c_str(), *io_ctx); if (r < 0) { if (r == -ENOENT && pool_name == get_default_pool_name()) { @@ -933,6 +664,8 @@ int init_io_ctx(librados::Rados &rados, const std::string &pool_name, } return r; } + + io_ctx->set_namespace(namespace_name); return 0; } @@ -977,12 +710,13 @@ int open_image_by_id(librados::IoCtx &io_ctx, const std::string &image_id, } int init_and_open_image(const std::string &pool_name, + const std::string &namespace_name, const std::string &image_name, const std::string &image_id, const std::string &snap_name, bool read_only, librados::Rados *rados, librados::IoCtx *io_ctx, librbd::Image *image) { - int r = init(pool_name, rados, io_ctx); + int r = init(pool_name, namespace_name, rados, io_ctx); if (r < 0) { return r; } @@ -1114,24 +848,6 @@ uint64_t get_rbd_default_features(CephContext* cct) { return boost::lexical_cast(features); } -bool check_if_image_spec_present(const po::variables_map &vm, - at::ArgumentModifier mod, - size_t spec_arg_index) { - std::string image_key = (mod == at::ARGUMENT_MODIFIER_DEST ? - at::DEST_IMAGE_NAME : at::IMAGE_NAME); - - if (vm.count(image_key)) { - return true; - } - - std::string spec = get_positional_argument(vm, spec_arg_index); - if (!spec.empty()) { - return true; - } - - return false; -} - bool is_not_user_snap_namespace(librbd::Image* image, const librbd::snap_info_t &snap_info) { diff --git a/src/tools/rbd/Utils.h b/src/tools/rbd/Utils.h index 02aa3ce91f12c..4cf554fc42d1e 100644 --- a/src/tools/rbd/Utils.h +++ b/src/tools/rbd/Utils.h @@ -92,16 +92,8 @@ void aio_context_callback(librbd::completion_t completion, void *arg); int read_string(int fd, unsigned max, std::string *out); int extract_spec(const std::string &spec, std::string *pool_name, - std::string *image_name, std::string *snap_name, - SpecValidation spec_validation); - -int extract_group_spec(const std::string &spec, - std::string *pool_name, - std::string *group_name, - std::string *snap_name); - -int extract_image_id_spec(const std::string &spec, std::string *pool_name, - std::string *image_id); + std::string *namespace_name, std::string *name, + std::string *snap_name, SpecValidation spec_validation); std::string get_positional_argument( const boost::program_options::variables_map &vm, size_t index); @@ -115,42 +107,24 @@ std::string get_namespace_name(const boost::program_options::variables_map &vm, int get_pool_image_snapshot_names( const boost::program_options::variables_map &vm, argument_types::ArgumentModifier mod, size_t *spec_arg_index, - std::string *pool_name, std::string *image_name, std::string *snap_name, - SnapshotPresence snapshot_presence, SpecValidation spec_validation, - bool image_required = true); - -int get_pool_snapshot_names(const boost::program_options::variables_map &vm, - argument_types::ArgumentModifier mod, - size_t *spec_arg_index, std::string *pool_name, - std::string *snap_name, - SnapshotPresence snapshot_presence, - SpecValidation spec_validation); - -int get_special_pool_group_names(const boost::program_options::variables_map &vm, - size_t *arg_index, - std::string *group_pool_name, - std::string *group_name); - -int get_special_pool_image_names(const boost::program_options::variables_map &vm, - size_t *arg_index, - std::string *image_pool_name, - std::string *image_name); - -int get_pool_image_id(const boost::program_options::variables_map &vm, - size_t *arg_index, std::string *image_pool_name, - std::string *image_id); - -int get_pool_group_names(const boost::program_options::variables_map &vm, - argument_types::ArgumentModifier mod, - size_t *spec_arg_index, - std::string *pool_name, - std::string *group_name, - std::string *snap_name); + std::string *pool_name, std::string *namespace_name, + std::string *image_name, std::string *snap_name, bool image_name_required, + SnapshotPresence snapshot_presence, SpecValidation spec_validation); -int get_pool_journal_names( +int get_pool_generic_snapshot_names( const boost::program_options::variables_map &vm, argument_types::ArgumentModifier mod, size_t *spec_arg_index, - std::string *pool_name, std::string *journal_name); + const std::string& pool_key, std::string *pool_name, + std::string *namespace_name, const std::string& generic_key, + const std::string& generic_key_desc, std::string *generic_name, + std::string *snap_name, bool generic_name_required, + SnapshotPresence snapshot_presence, SpecValidation spec_validation); + +int get_pool_image_id(const boost::program_options::variables_map &vm, + size_t *spec_arg_index, + std::string *pool_name, + std::string *namespace_name, + std::string *image_id); int validate_snapshot_name(argument_types::ArgumentModifier mod, const std::string &snap_name, @@ -177,11 +151,10 @@ int get_formatter(const boost::program_options::variables_map &vm, void init_context(); -int init(const std::string &pool_name, librados::Rados *rados, - librados::IoCtx *io_ctx); - +int init(const std::string &pool_name, const std::string& namespace_name, + librados::Rados *rados, librados::IoCtx *io_ctx); int init_io_ctx(librados::Rados &rados, const std::string &pool_name, - librados::IoCtx *io_ctx); + const std::string& namespace_name, librados::IoCtx *io_ctx); void disable_cache(); @@ -192,6 +165,7 @@ int open_image_by_id(librados::IoCtx &io_ctx, const std::string &image_id, bool read_only, librbd::Image *image); int init_and_open_image(const std::string &pool_name, + const std::string &namespace_name, const std::string &image_name, const std::string &image_id, const std::string &snap_name, bool read_only, @@ -207,10 +181,6 @@ void calc_sparse_extent(const bufferptr &bp, size_t *write_length, bool *zeroed); -bool check_if_image_spec_present(const boost::program_options::variables_map &vm, - argument_types::ArgumentModifier mod, - size_t spec_arg_index); - bool is_not_user_snap_namespace(librbd::Image* image, const librbd::snap_info_t &snap_info); diff --git a/src/tools/rbd/action/Bench.cc b/src/tools/rbd/action/Bench.cc index 0fe1950426824..56fe12d17e5a2 100644 --- a/src/tools/rbd/action/Bench.cc +++ b/src/tools/rbd/action/Bench.cc @@ -391,6 +391,7 @@ void get_arguments_for_bench(po::options_description *positional, int bench_execute(const po::variables_map &vm, io_type_t bench_io_type) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; utils::SnapshotPresence snap_presence = utils::SNAPSHOT_PRESENCE_NONE; @@ -398,8 +399,8 @@ int bench_execute(const po::variables_map &vm, io_type_t bench_io_type) { snap_presence = utils::SNAPSHOT_PRESENCE_PERMITTED; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, snap_presence, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, snap_presence, utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -461,8 +462,8 @@ int bench_execute(const po::variables_map &vm, io_type_t bench_io_type) { librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, &rados, - &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Children.cc b/src/tools/rbd/action/Children.cc index d2ede539427f6..143337e32ceb0 100644 --- a/src/tools/rbd/action/Children.cc +++ b/src/tools/rbd/action/Children.cc @@ -85,11 +85,12 @@ int execute(const po::variables_map &vm, size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, snap_presence, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, snap_presence, utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -109,8 +110,8 @@ int execute(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", true, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + true, &rados, &io_ctx, &image); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Clone.cc b/src/tools/rbd/action/Clone.cc index 1a47bf0606759..e668590725b3a 100644 --- a/src/tools/rbd/action/Clone.cc +++ b/src/tools/rbd/action/Clone.cc @@ -33,21 +33,25 @@ int execute(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_REQUIRED, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_REQUIRED, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } std::string dst_pool_name; + std::string dst_namespace_name; std::string dst_image_name; std::string dst_snap_name; r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_DEST, &arg_index, &dst_pool_name, &dst_image_name, - &dst_snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); + vm, at::ARGUMENT_MODIFIER_DEST, &arg_index, &dst_pool_name, + &dst_namespace_name, &dst_image_name, &dst_snap_name, true, + utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } @@ -59,15 +63,21 @@ int execute(const po::variables_map &vm, } opts.set(RBD_IMAGE_OPTION_FORMAT, static_cast(2)); + // TODO clones across namespaces not yet supported + if (namespace_name != dst_namespace_name) { + std::cerr << "rbd: clones across namespaces is not supported." << std::endl; + return -EINVAL; + } + librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } librados::IoCtx dst_io_ctx; - r = utils::init_io_ctx(rados, dst_pool_name, &dst_io_ctx); + r = utils::init_io_ctx(rados, dst_pool_name, dst_namespace_name, &dst_io_ctx); if (r < 0) { return r; } @@ -83,7 +93,7 @@ int execute(const po::variables_map &vm, } Shell::Action action( - {"clone"}, {}, "Clone a snapshot into a COW child image.", + {"clone"}, {}, "Clone a snapshot into a CoW child image.", at::get_long_features_help(), &get_arguments, &execute); } // namespace clone diff --git a/src/tools/rbd/action/Copy.cc b/src/tools/rbd/action/Copy.cc index 96d63f2a31daf..9a24843710905 100644 --- a/src/tools/rbd/action/Copy.cc +++ b/src/tools/rbd/action/Copy.cc @@ -44,22 +44,25 @@ int execute(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED, + vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_PERMITTED, utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } std::string dst_pool_name; + std::string dst_namespace_name; std::string dst_image_name; std::string dst_snap_name; r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_DEST, &arg_index, &dst_pool_name, &dst_image_name, - &dst_snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); + vm, at::ARGUMENT_MODIFIER_DEST, &arg_index, &dst_pool_name, + &dst_namespace_name, &dst_image_name, &dst_snap_name, true, + utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } @@ -73,14 +76,14 @@ int execute(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", snap_name, true, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", + snap_name, true, &rados, &io_ctx, &image); if (r < 0) { return r; } librados::IoCtx dst_io_ctx; - r = utils::init_io_ctx(rados, dst_pool_name, &dst_io_ctx); + r = utils::init_io_ctx(rados, dst_pool_name, dst_namespace_name, &dst_io_ctx); if (r < 0) { return r; } @@ -130,22 +133,25 @@ int execute_deep(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED, + vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_PERMITTED, utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } std::string dst_pool_name; + std::string dst_namespace_name; std::string dst_image_name; std::string dst_snap_name; r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_DEST, &arg_index, &dst_pool_name, &dst_image_name, - &dst_snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); + vm, at::ARGUMENT_MODIFIER_DEST, &arg_index, &dst_pool_name, + &dst_namespace_name, &dst_image_name, &dst_snap_name, true, + utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } @@ -159,14 +165,14 @@ int execute_deep(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", snap_name, true, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", + snap_name, true, &rados, &io_ctx, &image); if (r < 0) { return r; } librados::IoCtx dst_io_ctx; - r = utils::init_io_ctx(rados, dst_pool_name, &dst_io_ctx); + r = utils::init_io_ctx(rados, dst_pool_name, dst_namespace_name, &dst_io_ctx); if (r < 0) { return r; } @@ -181,8 +187,8 @@ int execute_deep(const po::variables_map &vm, } Shell::Action action_deep( - {"deep", "copy"}, {"deep", "cp"}, "Deep copy src image to dest.", at::get_long_features_help(), - &get_arguments_deep, &execute_deep); + {"deep", "copy"}, {"deep", "cp"}, "Deep copy src image to dest.", + at::get_long_features_help(), &get_arguments_deep, &execute_deep); } // namespace copy } // namespace action diff --git a/src/tools/rbd/action/Create.cc b/src/tools/rbd/action/Create.cc index 028530b7026c1..daae502df9714 100644 --- a/src/tools/rbd/action/Create.cc +++ b/src/tools/rbd/action/Create.cc @@ -199,11 +199,13 @@ int execute(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } @@ -222,14 +224,19 @@ int execute(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } librbd::RBD rbd; r = do_create(rbd, io_ctx, image_name.c_str(), size, opts); - if (r < 0) { + if (!namespace_name.empty() && r == -ENOENT) { + std::cerr << "rbd: namespace not found - it must be created with " + << "'rbd namespace create' before creating an image." + << std::endl; + return r; + } else if (r < 0) { std::cerr << "rbd: create error: " << cpp_strerror(r) << std::endl; return r; } diff --git a/src/tools/rbd/action/Diff.cc b/src/tools/rbd/action/Diff.cc index 212a3def4bff7..a215e8a0121ee 100644 --- a/src/tools/rbd/action/Diff.cc +++ b/src/tools/rbd/action/Diff.cc @@ -90,11 +90,12 @@ int execute(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED, + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_PERMITTED, utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; @@ -116,8 +117,8 @@ int execute(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", snap_name, true, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", + snap_name, true, &rados, &io_ctx, &image); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/DiskUsage.cc b/src/tools/rbd/action/DiskUsage.cc index 14a9a30d14ba2..e2e6605379b7d 100644 --- a/src/tools/rbd/action/DiskUsage.cc +++ b/src/tools/rbd/action/DiskUsage.cc @@ -255,12 +255,13 @@ int execute(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED, - utils::SPEC_VALIDATION_NONE, vm.count(at::FROM_SNAPSHOT_NAME)); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, vm.count(at::FROM_SNAPSHOT_NAME), + utils::SNAPSHOT_PRESENCE_PERMITTED, utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -278,7 +279,7 @@ int execute(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Export.cc b/src/tools/rbd/action/Export.cc index 8c109e17dea80..53dfa9c6aafa5 100644 --- a/src/tools/rbd/action/Export.cc +++ b/src/tools/rbd/action/Export.cc @@ -265,11 +265,12 @@ int execute_diff(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED, + vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_PERMITTED, utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; @@ -289,8 +290,8 @@ int execute_diff(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", snap_name, true, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", + snap_name, true, &rados, &io_ctx, &image); if (r < 0) { return r; } @@ -605,11 +606,12 @@ int execute(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED, + vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_PERMITTED, utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; @@ -624,12 +626,12 @@ int execute(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", snap_name, true, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", + snap_name, true, &rados, &io_ctx, &image); if (r < 0) { return r; } - + int format = 1; if (vm.count("export-format")) format = vm["export-format"].as(); diff --git a/src/tools/rbd/action/Feature.cc b/src/tools/rbd/action/Feature.cc index af23f90fbfae1..13a7b6ea75ce8 100644 --- a/src/tools/rbd/action/Feature.cc +++ b/src/tools/rbd/action/Feature.cc @@ -41,11 +41,13 @@ void get_arguments_enable(po::options_description *positional, int execute(const po::variables_map &vm, bool enabled) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -77,8 +79,8 @@ int execute(const po::variables_map &vm, bool enabled) { librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Flatten.cc b/src/tools/rbd/action/Flatten.cc index 9f7ab18e37dae..ec4e837a87114 100644 --- a/src/tools/rbd/action/Flatten.cc +++ b/src/tools/rbd/action/Flatten.cc @@ -37,11 +37,13 @@ int execute(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -49,8 +51,8 @@ int execute(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Ggate.cc b/src/tools/rbd/action/Ggate.cc index 7757785a58d92..611ffc7db8167 100644 --- a/src/tools/rbd/action/Ggate.cc +++ b/src/tools/rbd/action/Ggate.cc @@ -57,9 +57,9 @@ int get_image_or_snap_spec(const po::variables_map &vm, std::string *spec) { std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED, - utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, nullptr, + &image_name, &snap_name, true, + utils::SNAPSHOT_PRESENCE_PERMITTED, utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Group.cc b/src/tools/rbd/action/Group.cc index aa11feebc868f..e4236c3aa517d 100644 --- a/src/tools/rbd/action/Group.cc +++ b/src/tools/rbd/action/Group.cc @@ -14,21 +14,89 @@ namespace rbd { namespace action { -namespace consgrp { +namespace group { namespace at = argument_types; namespace po = boost::program_options; +static const std::string GROUP_SPEC("group-spec"); +static const std::string GROUP_SNAP_SPEC("group-snap-spec"); + +static const std::string GROUP_NAME("group"); +static const std::string DEST_GROUP_NAME("dest-group"); + +static const std::string GROUP_POOL_NAME("group-" + at::POOL_NAME); +static const std::string IMAGE_POOL_NAME("image-" + at::POOL_NAME); + +void add_group_option(po::options_description *opt, + at::ArgumentModifier modifier) { + std::string name = GROUP_NAME; + std::string description = at::get_description_prefix(modifier) + "group name"; + switch (modifier) { + case at::ARGUMENT_MODIFIER_NONE: + case at::ARGUMENT_MODIFIER_SOURCE: + break; + case at::ARGUMENT_MODIFIER_DEST: + name = DEST_GROUP_NAME; + break; + } + + // TODO add validator + opt->add_options() + (name.c_str(), po::value(), description.c_str()); +} + +void add_prefixed_pool_option(po::options_description *opt, + const std::string &prefix) { + std::string name = prefix + "-" + at::POOL_NAME; + std::string description = prefix + " pool name"; + + opt->add_options() + (name.c_str(), po::value(), description.c_str()); +} + +void add_prefixed_namespace_option(po::options_description *opt, + const std::string &prefix) { + std::string name = prefix + "-" + at::NAMESPACE_NAME; + std::string description = prefix + " namespace name"; + + opt->add_options() + (name.c_str(), po::value(), description.c_str()); +} + +void add_group_spec_options(po::options_description *pos, + po::options_description *opt, + at::ArgumentModifier modifier, + bool snap) { + at::add_pool_option(opt, modifier); + at::add_namespace_option(opt, modifier); + add_group_option(opt, modifier); + if (!snap) { + pos->add_options() + ((get_name_prefix(modifier) + GROUP_SPEC).c_str(), + (get_description_prefix(modifier) + "group specification\n" + + "(example: [/[/]])").c_str()); + } else { + add_snap_option(opt, modifier); + pos->add_options() + ((get_name_prefix(modifier) + GROUP_SNAP_SPEC).c_str(), + (get_description_prefix(modifier) + "group specification\n" + + "(example: [/[/]]@)").c_str()); + } +} + int execute_create(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; - std::string group_name; std::string pool_name; + std::string namespace_name; + std::string group_name; - int r = utils::get_pool_group_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &group_name, - nullptr); + int r = utils::get_pool_generic_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, at::POOL_NAME, &pool_name, + &namespace_name, GROUP_NAME, "group", &group_name, nullptr, true, + utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } @@ -36,7 +104,7 @@ int execute_create(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -55,6 +123,7 @@ int execute_list(const po::variables_map &vm, size_t arg_index = 0; std::string pool_name = utils::get_pool_name(vm, &arg_index); + std::string namespace_name = utils::get_namespace_name(vm, nullptr); at::Format::Formatter formatter; int r = utils::get_formatter(vm, &formatter); @@ -65,7 +134,7 @@ int execute_list(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -96,12 +165,14 @@ int execute_remove(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; - std::string group_name; std::string pool_name; + std::string namespace_name; + std::string group_name; - int r = utils::get_pool_group_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &group_name, - nullptr); + int r = utils::get_pool_generic_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, at::POOL_NAME, &pool_name, + &namespace_name, GROUP_NAME, "group", &group_name, nullptr, true, + utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } @@ -109,7 +180,7 @@ int execute_remove(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -128,36 +199,47 @@ int execute_rename(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; - std::string group_name; std::string pool_name; + std::string namespace_name; + std::string group_name; - int r = utils::get_pool_group_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &group_name, - nullptr); + int r = utils::get_pool_generic_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, at::POOL_NAME, &pool_name, + &namespace_name, GROUP_NAME, "group", &group_name, nullptr, true, + utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } - std::string dest_group_name; std::string dest_pool_name; + std::string dest_namespace_name; + std::string dest_group_name; - r = utils::get_pool_group_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &dest_pool_name, - &dest_group_name, nullptr); + r = utils::get_pool_generic_snapshot_names( + vm, at::ARGUMENT_MODIFIER_DEST, &arg_index, at::DEST_POOL_NAME, + &dest_pool_name, &dest_namespace_name, DEST_GROUP_NAME, "group", + &dest_group_name, nullptr, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } if (pool_name != dest_pool_name) { std::cerr << "rbd: group rename across pools not supported" << std::endl - << "source pool: " << pool_name<< ", dest pool: " << dest_pool_name - << std::endl; + << "source pool: " << pool_name << ", dest pool: " + << dest_pool_name << std::endl; + return -EINVAL; + } else if (namespace_name != dest_namespace_name) { + std::cerr << "rbd: group rename across namespaces not supported" + << std::endl + << "source namespace: " << namespace_name << ", dest namespace: " + << dest_namespace_name << std::endl; return -EINVAL; } librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -179,39 +261,45 @@ int execute_add(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; // Parse group data. - std::string group_name; std::string group_pool_name; + std::string group_namespace_name; + std::string group_name; - int r = utils::get_special_pool_group_names(vm, &arg_index, - &group_pool_name, - &group_name); + int r = utils::get_pool_generic_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, GROUP_POOL_NAME, + &group_pool_name, &group_namespace_name, GROUP_NAME, "group", &group_name, + nullptr, true, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); if (r < 0) { - std::cerr << "rbd: image add error: " << cpp_strerror(r) << std::endl; return r; } - std::string image_name; std::string image_pool_name; + std::string image_namespace_name; + std::string image_name; - r = utils::get_special_pool_image_names(vm, &arg_index, - &image_pool_name, - &image_name); - + r = utils::get_pool_generic_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, IMAGE_POOL_NAME, + &image_pool_name, &image_namespace_name, at::IMAGE_NAME, "image", + &image_name, nullptr, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_FULL); if (r < 0) { - std::cerr << "rbd: image add error: " << cpp_strerror(r) << std::endl; return r; } - librados::Rados rados; + if (group_namespace_name != image_namespace_name) { + std::cerr << "rbd: group and image namespace must match." << std::endl; + return -EINVAL; + } + librados::Rados rados; librados::IoCtx cg_io_ctx; - r = utils::init(group_pool_name, &rados, &cg_io_ctx); + r = utils::init(group_pool_name, group_namespace_name, &rados, &cg_io_ctx); if (r < 0) { return r; } librados::IoCtx image_io_ctx; - r = utils::init(image_pool_name, &rados, &image_io_ctx); + r = utils::init(image_pool_name, group_namespace_name, &rados, &image_io_ctx); if (r < 0) { return r; } @@ -231,56 +319,54 @@ int execute_remove_image(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; - std::string group_name; std::string group_pool_name; + std::string group_namespace_name; + std::string group_name; - int r = utils::get_special_pool_group_names(vm, &arg_index, - &group_pool_name, - &group_name); + int r = utils::get_pool_generic_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, GROUP_POOL_NAME, + &group_pool_name, &group_namespace_name, GROUP_NAME, "group", &group_name, + nullptr, true, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); if (r < 0) { - std::cerr << "rbd: image remove error: " << cpp_strerror(r) << std::endl; return r; } - std::string image_name; std::string image_pool_name; + std::string image_namespace_name; + std::string image_name; std::string image_id; if (vm.count(at::IMAGE_ID)) { image_id = vm[at::IMAGE_ID].as(); } - bool has_image_spec = utils::check_if_image_spec_present( - vm, at::ARGUMENT_MODIFIER_NONE, arg_index); + r = utils::get_pool_generic_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, IMAGE_POOL_NAME, + &image_pool_name, &image_namespace_name, at::IMAGE_NAME, "image", + &image_name, nullptr, image_id.empty(), utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_FULL); + if (r < 0) { + return r; + } - if (!image_id.empty() && has_image_spec) { + if (group_namespace_name != image_namespace_name) { + std::cerr << "rbd: group and image namespace must match." << std::endl; + return -EINVAL; + } else if (!image_id.empty() && !image_name.empty()) { std::cerr << "rbd: trying to access image using both name and id. " << std::endl; return -EINVAL; } - if (image_id.empty()) { - r = utils::get_special_pool_image_names(vm, &arg_index, &image_pool_name, - &image_name); - } else { - image_pool_name = utils::get_pool_name(vm, &arg_index); - } - - if (r < 0) { - std::cerr << "rbd: image remove error: " << cpp_strerror(r) << std::endl; - return r; - } - librados::Rados rados; - librados::IoCtx cg_io_ctx; - r = utils::init(group_pool_name, &rados, &cg_io_ctx); + r = utils::init(group_pool_name, group_namespace_name, &rados, &cg_io_ctx); if (r < 0) { return r; } librados::IoCtx image_io_ctx; - r = utils::init(image_pool_name, &rados, &image_io_ctx); + r = utils::init(image_pool_name, group_namespace_name, &rados, &image_io_ctx); if (r < 0) { return r; } @@ -304,22 +390,18 @@ int execute_remove_image(const po::variables_map &vm, int execute_list_images(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; - std::string group_name; std::string pool_name; + std::string namespace_name; + std::string group_name; - int r = utils::get_pool_group_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &group_name, - nullptr); + int r = utils::get_pool_generic_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, at::POOL_NAME, &pool_name, + &namespace_name, GROUP_NAME, "group", &group_name, nullptr, true, + utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } - if (group_name.empty()) { - std::cerr << "rbd: " - << "group name was not specified" << std::endl; - return -EINVAL; - } - at::Format::Formatter formatter; r = utils::get_formatter(vm, &formatter); if (r < 0) { @@ -329,7 +411,7 @@ int execute_list_images(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -363,7 +445,7 @@ int execute_list_images(const po::variables_map &vm, librados::IoCtx pool_io_ctx; r = rados.ioctx_create2(image.pool, pool_io_ctx); if (r < 0) { - pool_name = ""; + pool_name = ""; } else { pool_name = pool_io_ctx.get_pool_name(); } @@ -372,10 +454,16 @@ int execute_list_images(const po::variables_map &vm, f->open_object_section("image"); f->dump_string("image", image_name); f->dump_string("pool", pool_name); + f->dump_string("namespace", io_ctx.get_namespace()); f->dump_int("state", state); f->close_section(); - } else - std::cout << pool_name << "/" << image_name << " " << state_string << std::endl; + } else { + std::cout << pool_name << "/"; + if (!io_ctx.get_namespace().empty()) { + std::cout << io_ctx.get_namespace() << "/"; + } + std::cout << image_name << " " << state_string << std::endl; + } } if (f) { @@ -390,13 +478,15 @@ int execute_group_snap_create(const po::variables_map &vm, const std::vector &global_args) { size_t arg_index = 0; - std::string group_name; std::string pool_name; + std::string namespace_name; + std::string group_name; std::string snap_name; - int r = utils::get_pool_group_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &group_name, - &snap_name); + int r = utils::get_pool_generic_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, at::POOL_NAME, &pool_name, + &namespace_name, GROUP_NAME, "group", &group_name, &snap_name, true, + utils::SNAPSHOT_PRESENCE_REQUIRED, utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } @@ -404,7 +494,7 @@ int execute_group_snap_create(const po::variables_map &vm, librados::IoCtx io_ctx; librados::Rados rados; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -418,17 +508,19 @@ int execute_group_snap_create(const po::variables_map &vm, return 0; } - int execute_group_snap_remove(const po::variables_map &vm, - const std::vector &global_args) { +int execute_group_snap_remove(const po::variables_map &vm, + const std::vector &global_args) { size_t arg_index = 0; - std::string group_name; std::string pool_name; + std::string namespace_name; + std::string group_name; std::string snap_name; - int r = utils::get_pool_group_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &group_name, - &snap_name); + int r = utils::get_pool_generic_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, at::POOL_NAME, &pool_name, + &namespace_name, GROUP_NAME, "group", &group_name, &snap_name, true, + utils::SNAPSHOT_PRESENCE_REQUIRED, utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } @@ -436,7 +528,7 @@ int execute_group_snap_create(const po::variables_map &vm, librados::IoCtx io_ctx; librados::Rados rados; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -456,13 +548,15 @@ int execute_group_snap_rename(const po::variables_map &vm, const std::vector &global_args) { size_t arg_index = 0; - std::string group_name; std::string pool_name; + std::string namespace_name; + std::string group_name; std::string source_snap_name; - int r = utils::get_pool_group_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &group_name, - &source_snap_name); + int r = utils::get_pool_generic_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, at::POOL_NAME, &pool_name, + &namespace_name, GROUP_NAME, "group", &group_name, &source_snap_name, true, + utils::SNAPSHOT_PRESENCE_REQUIRED, utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } @@ -490,7 +584,7 @@ int execute_group_snap_rename(const po::variables_map &vm, } librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -511,22 +605,18 @@ int execute_group_snap_rename(const po::variables_map &vm, int execute_group_snap_list(const po::variables_map &vm, const std::vector &ceph_global_args) { size_t arg_index = 0; - std::string group_name; std::string pool_name; + std::string namespace_name; + std::string group_name; - int r = utils::get_pool_group_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &group_name, - nullptr); + int r = utils::get_pool_generic_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, at::POOL_NAME, &pool_name, + &namespace_name, GROUP_NAME, "group", &group_name, nullptr, true, + utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } - if (group_name.empty()) { - std::cerr << "rbd: " - << "group name was not specified" << std::endl; - return -EINVAL; - } - at::Format::Formatter formatter; r = utils::get_formatter(vm, &formatter); if (r < 0) { @@ -536,7 +626,7 @@ int execute_group_snap_list(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -595,46 +685,49 @@ int execute_group_snap_list(const po::variables_map &vm, void get_create_arguments(po::options_description *positional, po::options_description *options) { - at::add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE, - false); + add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE, + false); } void get_remove_arguments(po::options_description *positional, po::options_description *options) { - at::add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE, - false); + add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE, + false); } void get_list_arguments(po::options_description *positional, po::options_description *options) { - add_pool_option(options, at::ARGUMENT_MODIFIER_NONE); + at::add_pool_option(options, at::ARGUMENT_MODIFIER_NONE); + at::add_namespace_options(nullptr, options); at::add_format_options(options); } void get_rename_arguments(po::options_description *positional, po::options_description *options) { - at::add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_SOURCE, - false); - at::add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_DEST, - false); + add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_SOURCE, + false); + add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_DEST, + false); } void get_add_arguments(po::options_description *positional, po::options_description *options) { positional->add_options() - (at::GROUP_SPEC.c_str(), + (GROUP_SPEC.c_str(), "group specification\n" - "(example: [/])"); + "(example: [/[/]])"); - at::add_special_pool_option(options, "group"); - at::add_group_option(options, at::ARGUMENT_MODIFIER_NONE); + add_prefixed_pool_option(options, "group"); + add_prefixed_namespace_option(options, "group"); + add_group_option(options, at::ARGUMENT_MODIFIER_NONE); positional->add_options() (at::IMAGE_SPEC.c_str(), "image specification\n" - "(example: [/])"); + "(example: [/[/]])"); - at::add_special_pool_option(options, "image"); + add_prefixed_pool_option(options, "image"); + add_prefixed_namespace_option(options, "image"); at::add_image_option(options, at::ARGUMENT_MODIFIER_NONE); at::add_pool_option(options, at::ARGUMENT_MODIFIER_NONE, @@ -644,19 +737,21 @@ void get_add_arguments(po::options_description *positional, void get_remove_image_arguments(po::options_description *positional, po::options_description *options) { positional->add_options() - (at::GROUP_SPEC.c_str(), + (GROUP_SPEC.c_str(), "group specification\n" - "(example: [/])"); + "(example: [/[/]])"); - at::add_special_pool_option(options, "group"); - at::add_group_option(options, at::ARGUMENT_MODIFIER_NONE); + add_prefixed_pool_option(options, "group"); + add_prefixed_namespace_option(options, "group"); + add_group_option(options, at::ARGUMENT_MODIFIER_NONE); positional->add_options() (at::IMAGE_SPEC.c_str(), "image specification\n" - "(example: [/])"); + "(example: [/[/]])"); - at::add_special_pool_option(options, "image"); + add_prefixed_pool_option(options, "image"); + add_prefixed_namespace_option(options, "image"); at::add_image_option(options, at::ARGUMENT_MODIFIER_NONE); at::add_pool_option(options, at::ARGUMENT_MODIFIER_NONE, @@ -667,26 +762,26 @@ void get_remove_image_arguments(po::options_description *positional, void get_list_images_arguments(po::options_description *positional, po::options_description *options) { at::add_format_options(options); - at::add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE, - false); + add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE, + false); } void get_group_snap_create_arguments(po::options_description *positional, po::options_description *options) { - at::add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE, - true); + add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE, + true); } void get_group_snap_remove_arguments(po::options_description *positional, po::options_description *options) { - at::add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE, - true); + add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE, + true); } void get_group_snap_rename_arguments(po::options_description *positional, po::options_description *options) { - at::add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE, - true); + add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE, + true); positional->add_options() (at::DEST_SNAPSHOT_NAME.c_str(), @@ -697,8 +792,8 @@ void get_group_snap_rename_arguments(po::options_description *positional, void get_group_snap_list_arguments(po::options_description *positional, po::options_description *options) { at::add_format_options(options); - at::add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE, - false); + add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE, + false); } Shell::Action action_create( @@ -738,6 +833,7 @@ Shell::Action action_group_snap_list( {"group", "snap", "list"}, {"group", "snap", "ls"}, "List snapshots of a group.", "", &get_group_snap_list_arguments, &execute_group_snap_list); + } // namespace group } // namespace action } // namespace rbd diff --git a/src/tools/rbd/action/ImageMeta.cc b/src/tools/rbd/action/ImageMeta.cc index c057eaeb67fee..f5804de726328 100644 --- a/src/tools/rbd/action/ImageMeta.cc +++ b/src/tools/rbd/action/ImageMeta.cc @@ -144,11 +144,13 @@ int execute_list(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -162,8 +164,8 @@ int execute_list(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } @@ -187,11 +189,13 @@ int execute_get(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -205,8 +209,8 @@ int execute_get(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } @@ -232,11 +236,13 @@ int execute_set(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -256,8 +262,8 @@ int execute_set(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } @@ -281,11 +287,13 @@ int execute_remove(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -299,8 +307,8 @@ int execute_remove(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Import.cc b/src/tools/rbd/action/Import.cc index e116cc0e88da7..6b8a29459cad8 100644 --- a/src/tools/rbd/action/Import.cc +++ b/src/tools/rbd/action/Import.cc @@ -489,11 +489,13 @@ int execute_diff(const po::variables_map &vm, } std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -506,8 +508,8 @@ int execute_diff(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } @@ -978,8 +980,8 @@ int execute(const po::variables_map &vm, std::string deprecated_snap_name; r = utils::extract_spec(deprecated_image_name, &deprecated_pool_name, - &deprecated_image_name, &deprecated_snap_name, - utils::SPEC_VALIDATION_FULL); + nullptr, &deprecated_image_name, + &deprecated_snap_name, utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } @@ -990,12 +992,13 @@ int execute(const po::variables_map &vm, } std::string pool_name = deprecated_pool_name; + std::string namespace_name; std::string image_name; std::string snap_name = deprecated_snap_name; r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_DEST, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL, - false); + vm, at::ARGUMENT_MODIFIER_DEST, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, false, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } @@ -1012,7 +1015,7 @@ int execute(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Info.cc b/src/tools/rbd/action/Info.cc index 79440bda8d8d9..db8de5778378d 100644 --- a/src/tools/rbd/action/Info.cc +++ b/src/tools/rbd/action/Info.cc @@ -180,7 +180,11 @@ static int do_show_info(librados::IoCtx &io_ctx, librbd::Image& image, group_pool = group_io_ctx.get_pool_name(); } - group_string = group_pool + "/" + group_info.name; + group_string = group_pool + "/"; + if (!io_ctx.get_namespace().empty()) { + group_string += io_ctx.get_namespace() + "/"; + } + group_string += group_info.name; } struct timespec create_timestamp; @@ -366,6 +370,7 @@ int execute(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; std::string image_id; @@ -374,32 +379,20 @@ int execute(const po::variables_map &vm, image_id = vm[at::IMAGE_ID].as(); } - bool has_image_spec = utils::check_if_image_spec_present( - vm, at::ARGUMENT_MODIFIER_NONE, arg_index); + int r = utils::get_pool_image_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, image_id.empty(), + utils::SNAPSHOT_PRESENCE_PERMITTED, utils::SPEC_VALIDATION_NONE); + if (r < 0) { + return r; + } - if (!image_id.empty() && has_image_spec) { + if (!image_id.empty() && !image_name.empty()) { std::cerr << "rbd: trying to access image using both name and id. " << std::endl; return -EINVAL; } - int r; - if (image_id.empty()) { - r = utils::get_pool_image_snapshot_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, - &image_name, &snap_name, - utils::SNAPSHOT_PRESENCE_PERMITTED, - utils::SPEC_VALIDATION_NONE); - } else { - r = utils::get_pool_snapshot_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &snap_name, - utils::SNAPSHOT_PRESENCE_PERMITTED, - utils::SPEC_VALIDATION_NONE); - } - if (r < 0) { - return r; - } - at::Format::Formatter formatter; r = utils::get_formatter(vm, &formatter); if (r < 0) { @@ -409,8 +402,9 @@ int execute(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, image_id, snap_name, - true, &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, + image_id, snap_name, true, &rados, &io_ctx, + &image); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Journal.cc b/src/tools/rbd/action/Journal.cc index 64883f5500b40..0b27d53405a24 100644 --- a/src/tools/rbd/action/Journal.cc +++ b/src/tools/rbd/action/Journal.cc @@ -30,6 +30,150 @@ namespace journal { namespace at = argument_types; namespace po = boost::program_options; +static const std::string JOURNAL_SPEC("journal-spec"); +static const std::string JOURNAL_NAME("journal"); +static const std::string DEST_JOURNAL_NAME("dest-journal"); + +void add_journal_option(po::options_description *opt, + at::ArgumentModifier modifier) { + std::string name = JOURNAL_NAME; + std::string description = at::get_description_prefix(modifier) + + "journal name"; + switch (modifier) { + case at::ARGUMENT_MODIFIER_NONE: + case at::ARGUMENT_MODIFIER_SOURCE: + break; + case at::ARGUMENT_MODIFIER_DEST: + name = DEST_JOURNAL_NAME; + break; + } + + // TODO add validator + opt->add_options() + (name.c_str(), po::value(), description.c_str()); +} + +void add_journal_spec_options(po::options_description *pos, + po::options_description *opt, + at::ArgumentModifier modifier) { + + pos->add_options() + ((get_name_prefix(modifier) + JOURNAL_SPEC).c_str(), + (get_description_prefix(modifier) + "journal specification\n" + + "(example: [/[/]])").c_str()); + add_pool_option(opt, modifier); + add_namespace_option(opt, modifier); + add_image_option(opt, modifier); + add_journal_option(opt, modifier); +} + +int get_pool_journal_names(const po::variables_map &vm, + at::ArgumentModifier mod, + size_t *spec_arg_index, + std::string *pool_name, + std::string *namespace_name, + std::string *journal_name) { + std::string pool_key = (mod == at::ARGUMENT_MODIFIER_DEST ? + at::DEST_POOL_NAME : at::POOL_NAME); + std::string namespace_key = (mod == at::ARGUMENT_MODIFIER_DEST ? + at::DEST_NAMESPACE_NAME : at::NAMESPACE_NAME); + std::string image_key = (mod == at::ARGUMENT_MODIFIER_DEST ? + at::DEST_IMAGE_NAME : at::IMAGE_NAME); + std::string journal_key = (mod == at::ARGUMENT_MODIFIER_DEST ? + DEST_JOURNAL_NAME : JOURNAL_NAME); + + if (vm.count(pool_key) && pool_name != nullptr) { + *pool_name = vm[pool_key].as(); + } + if (vm.count(namespace_key) && namespace_name != nullptr) { + *namespace_name = vm[namespace_key].as(); + } + if (vm.count(journal_key) && journal_name != nullptr) { + *journal_name = vm[journal_key].as(); + } + + std::string image_name; + if (vm.count(image_key)) { + image_name = vm[image_key].as(); + } + + int r; + if (journal_name != nullptr && !journal_name->empty()) { + // despite the separate pool option, + // we can also specify them via the journal option + std::string journal_name_copy(*journal_name); + r = extract_spec(journal_name_copy, pool_name, namespace_name, journal_name, + nullptr, utils::SPEC_VALIDATION_FULL); + if (r < 0) { + return r; + } + } + + if (!image_name.empty()) { + // despite the separate pool option, + // we can also specify them via the image option + std::string image_name_copy(image_name); + r = extract_spec(image_name_copy, pool_name, namespace_name, &image_name, + nullptr, utils::SPEC_VALIDATION_NONE); + if (r < 0) { + return r; + } + } + + if (journal_name != nullptr && spec_arg_index != nullptr && + journal_name->empty()) { + std::string spec = utils::get_positional_argument(vm, (*spec_arg_index)++); + if (!spec.empty()) { + r = extract_spec(spec, pool_name, namespace_name, journal_name, nullptr, + utils::SPEC_VALIDATION_FULL); + if (r < 0) { + return r; + } + } + } + + if (pool_name != nullptr && pool_name->empty()) { + *pool_name = utils::get_default_pool_name(); + } + + if (pool_name != nullptr && namespace_name != nullptr && + journal_name != nullptr && journal_name->empty() && !image_name.empty()) { + // Try to get journal name from image info. + librados::Rados rados; + librados::IoCtx io_ctx; + librbd::Image image; + int r = utils::init_and_open_image(*pool_name, *namespace_name, image_name, + "", "", true, &rados, &io_ctx, &image); + if (r < 0) { + std::cerr << "rbd: failed to open image " << image_name + << " to get journal name: " << cpp_strerror(r) << std::endl; + return r; + } + + uint64_t features; + r = image.features(&features); + if (r < 0) { + return r; + } + if ((features & RBD_FEATURE_JOURNALING) == 0) { + std::cerr << "rbd: journaling is not enabled for image " << image_name + << std::endl; + return -EINVAL; + } + *journal_name = utils::image_id(image); + } + + if (journal_name != nullptr && journal_name->empty()) { + std::string prefix = at::get_description_prefix(mod); + std::cerr << "rbd: " + << (mod == at::ARGUMENT_MODIFIER_DEST ? prefix : std::string()) + << "journal was not specified" << std::endl; + return -EINVAL; + } + + return 0; +} + static int do_show_journal_info(librados::Rados& rados, librados::IoCtx& io_ctx, const std::string& journal_id, Formatter *f) { @@ -806,7 +950,7 @@ static int do_import_journal(librados::IoCtx& io_ctx, void get_info_arguments(po::options_description *positional, po::options_description *options) { - at::add_journal_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); + add_journal_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); at::add_format_options(options); } @@ -814,9 +958,10 @@ int execute_info(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string journal_name; - int r = utils::get_pool_journal_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &journal_name); + int r = get_pool_journal_names(vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, + &pool_name, &namespace_name, &journal_name); if (r < 0) { return r; } @@ -829,7 +974,7 @@ int execute_info(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -845,7 +990,7 @@ int execute_info(const po::variables_map &vm, void get_status_arguments(po::options_description *positional, po::options_description *options) { - at::add_journal_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); + add_journal_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); at::add_format_options(options); } @@ -853,9 +998,10 @@ int execute_status(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string journal_name; - int r = utils::get_pool_journal_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &journal_name); + int r = get_pool_journal_names(vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, + &pool_name, &namespace_name, &journal_name); if (r < 0) { return r; } @@ -868,7 +1014,7 @@ int execute_status(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -883,23 +1029,24 @@ int execute_status(const po::variables_map &vm, void get_reset_arguments(po::options_description *positional, po::options_description *options) { - at::add_journal_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); + add_journal_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); } int execute_reset(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string journal_name; - int r = utils::get_pool_journal_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &journal_name); + int r = get_pool_journal_names(vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, + &pool_name, &namespace_name, &journal_name); if (r < 0) { return r; } librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -914,7 +1061,7 @@ int execute_reset(const po::variables_map &vm, void get_client_disconnect_arguments(po::options_description *positional, po::options_description *options) { - at::add_journal_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); + add_journal_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); options->add_options() ("client-id", po::value(), "client ID (or leave unspecified to disconnect all)"); @@ -924,9 +1071,10 @@ int execute_client_disconnect(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string journal_name; - int r = utils::get_pool_journal_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &journal_name); + int r = get_pool_journal_names(vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, + &pool_name, &namespace_name, &journal_name); if (r < 0) { return r; } @@ -938,7 +1086,7 @@ int execute_client_disconnect(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -954,7 +1102,7 @@ int execute_client_disconnect(const po::variables_map &vm, void get_inspect_arguments(po::options_description *positional, po::options_description *options) { - at::add_journal_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); + add_journal_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); at::add_verbose_option(options); } @@ -962,16 +1110,17 @@ int execute_inspect(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string journal_name; - int r = utils::get_pool_journal_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &journal_name); + int r = get_pool_journal_names(vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, + &pool_name, &namespace_name, &journal_name); if (r < 0) { return r; } librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -986,7 +1135,7 @@ int execute_inspect(const po::variables_map &vm, void get_export_arguments(po::options_description *positional, po::options_description *options) { - at::add_journal_spec_options(positional, options, + add_journal_spec_options(positional, options, at::ARGUMENT_MODIFIER_SOURCE); at::add_path_options(positional, options, "export file (or '-' for stdout)"); @@ -998,9 +1147,10 @@ int execute_export(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string journal_name; - int r = utils::get_pool_journal_names(vm, at::ARGUMENT_MODIFIER_SOURCE, - &arg_index, &pool_name, &journal_name); + int r = get_pool_journal_names(vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, + &pool_name, &namespace_name, &journal_name); if (r < 0) { return r; } @@ -1013,7 +1163,7 @@ int execute_export(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -1031,7 +1181,7 @@ void get_import_arguments(po::options_description *positional, po::options_description *options) { at::add_path_options(positional, options, "import file (or '-' for stdin)"); - at::add_journal_spec_options(positional, options, at::ARGUMENT_MODIFIER_DEST); + add_journal_spec_options(positional, options, at::ARGUMENT_MODIFIER_DEST); at::add_verbose_option(options); at::add_no_error_option(options); } @@ -1046,16 +1196,17 @@ int execute_import(const po::variables_map &vm, } std::string pool_name; + std::string namespace_name; std::string journal_name; - r = utils::get_pool_journal_names(vm, at::ARGUMENT_MODIFIER_DEST, - &arg_index, &pool_name, &journal_name); + r = get_pool_journal_names(vm, at::ARGUMENT_MODIFIER_DEST, &arg_index, + &pool_name, &namespace_name, &journal_name); if (r < 0) { return r; } librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Kernel.cc b/src/tools/rbd/action/Kernel.cc index 3e866e976f2af..7e01cf1dac832 100644 --- a/src/tools/rbd/action/Kernel.cc +++ b/src/tools/rbd/action/Kernel.cc @@ -246,7 +246,7 @@ static void print_error_description(const char *poolname, const char *imgname, if (maperrno == -ENOENT) goto done; - r = utils::init_and_open_image(poolname, imgname, "", snapname, + r = utils::init_and_open_image(poolname, "", imgname, "", snapname, true, &rados, &ioctx, &image); if (r < 0) goto done; @@ -414,8 +414,8 @@ int execute_map(const po::variables_map &vm, std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED, + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, nullptr, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_PERMITTED, utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; @@ -471,9 +471,9 @@ int execute_unmap(const po::variables_map &vm, int r; if (device_name.empty()) { r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED, - utils::SPEC_VALIDATION_NONE, false); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, nullptr, + &image_name, &snap_name, false, utils::SNAPSHOT_PRESENCE_PERMITTED, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/List.cc b/src/tools/rbd/action/List.cc index 22b7abce00461..65380f8987a27 100644 --- a/src/tools/rbd/action/List.cc +++ b/src/tools/rbd/action/List.cc @@ -144,7 +144,8 @@ int list_process_image(librados::Rados* rados, WorkerEntry* w, bool lflag, Forma return 0; } -int do_list(std::string &pool_name, bool lflag, int threads, Formatter *f) { +int do_list(const std::string &pool_name, const std::string& namespace_name, + bool lflag, int threads, Formatter *f) { std::vector workers; std::vector names; librados::Rados rados; @@ -158,7 +159,7 @@ int do_list(std::string &pool_name, bool lflag, int threads, Formatter *f) { threads = 32; } - int r = utils::init(pool_name, &rados, &ioctx); + int r = utils::init(pool_name, namespace_name, &rados, &ioctx); if (r < 0) { return r; } @@ -279,6 +280,7 @@ void get_arguments(po::options_description *positional, options->add_options() ("long,l", po::bool_switch(), "long listing format"); at::add_pool_options(positional, options); + at::add_namespace_options(positional, options); at::add_format_options(options); } @@ -286,6 +288,7 @@ int execute(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name = utils::get_pool_name(vm, &arg_index); + std::string namespace_name = utils::get_namespace_name(vm, nullptr); at::Format::Formatter formatter; int r = utils::get_formatter(vm, &formatter); @@ -293,7 +296,7 @@ int execute(const po::variables_map &vm, return r; } - r = do_list(pool_name, vm["long"].as(), + r = do_list(pool_name, namespace_name, vm["long"].as(), g_conf->get_val("rbd_concurrent_management_ops"), formatter.get()); if (r < 0) { diff --git a/src/tools/rbd/action/Lock.cc b/src/tools/rbd/action/Lock.cc index 22190f89b38d1..4ede924508021 100644 --- a/src/tools/rbd/action/Lock.cc +++ b/src/tools/rbd/action/Lock.cc @@ -114,11 +114,13 @@ int execute_list(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -132,8 +134,8 @@ int execute_list(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", true, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + true, &rados, &io_ctx, &image); if (r < 0) { return r; } @@ -158,11 +160,13 @@ int execute_add(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -181,8 +185,8 @@ int execute_add(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } @@ -217,11 +221,13 @@ int execute_remove(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -241,8 +247,8 @@ int execute_remove(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/MirrorImage.cc b/src/tools/rbd/action/MirrorImage.cc index 4410263512761..046760278a0eb 100644 --- a/src/tools/rbd/action/MirrorImage.cc +++ b/src/tools/rbd/action/MirrorImage.cc @@ -69,16 +69,18 @@ int execute_enable_disable(const po::variables_map &vm, bool enable, std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, nullptr, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } + // TODO support namespaces librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, + r = utils::init_and_open_image(pool_name, "", image_name, "", "", false, &rados, &io_ctx, &image); if (r < 0) { return r; @@ -119,18 +121,20 @@ int execute_promote(const po::variables_map &vm, std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, nullptr, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } bool force = vm["force"].as(); + // TODO support namespaces librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, + r = utils::init_and_open_image(pool_name, "", image_name, "", "", false, &rados, &io_ctx, &image); if (r < 0) { return r; @@ -158,16 +162,18 @@ int execute_demote(const po::variables_map &vm, std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, nullptr, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } + // TODO support namespaces librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, + r = utils::init_and_open_image(pool_name, "", image_name, "", "", false, &rados, &io_ctx, &image); if (r < 0) { return r; @@ -195,16 +201,18 @@ int execute_resync(const po::variables_map &vm, std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, nullptr, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } + // TODO support namespaces librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, + r = utils::init_and_open_image(pool_name, "", image_name, "", "", false, &rados, &io_ctx, &image); if (r < 0) { return r; @@ -244,16 +252,18 @@ int execute_status(const po::variables_map &vm, std::string image_name; std::string snap_name; r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, nullptr, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } + // TODO support namespaces librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, + r = utils::init_and_open_image(pool_name, "", image_name, "", "", false, &rados, &io_ctx, &image); if (r < 0) { return r; diff --git a/src/tools/rbd/action/MirrorPool.cc b/src/tools/rbd/action/MirrorPool.cc index e4312bf6181b8..01f1c990517f6 100644 --- a/src/tools/rbd/action/MirrorPool.cc +++ b/src/tools/rbd/action/MirrorPool.cc @@ -546,9 +546,10 @@ int execute_peer_add(const po::variables_map &vm, config_path = vm[at::CONFIG_PATH].as(); } + // TODO support namespaces librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, "", &rados, &io_ctx); if (r < 0) { return r; } @@ -600,9 +601,10 @@ int execute_peer_remove(const po::variables_map &vm, return r; } + // TODO support namespaces librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, "", &rados, &io_ctx); if (r < 0) { return r; } @@ -652,9 +654,10 @@ int execute_peer_set(const po::variables_map &vm, std::cerr << "rbd: must specify new " << key << " value." << std::endl; } + // TODO support namespaces librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, "", &rados, &io_ctx); if (r < 0) { return r; } @@ -695,7 +698,8 @@ int execute_enable_disable(const std::string &pool_name, librados::IoCtx io_ctx; rbd_mirror_mode_t current_mirror_mode; - int r = utils::init(pool_name, &rados, &io_ctx); + // TODO support namespaces + int r = utils::init(pool_name, "", &rados, &io_ctx); if (r < 0) { return r; } @@ -783,9 +787,10 @@ int execute_info(const po::variables_map &vm, config_path = vm[at::CONFIG_PATH].as(); } + // TODO support namespaces librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, "", &rados, &io_ctx); if (r < 0) { return r; } @@ -861,9 +866,10 @@ int execute_status(const po::variables_map &vm, config_path = vm[at::CONFIG_PATH].as(); } + // TODO support namespaces librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, "", &rados, &io_ctx); if (r < 0) { return r; } @@ -960,9 +966,10 @@ int execute_promote(const po::variables_map &vm, size_t arg_index = 0; std::string pool_name = utils::get_pool_name(vm, &arg_index); + // TODO support namespaces librados::Rados rados; librados::IoCtx io_ctx; - int r = utils::init(pool_name, &rados, &io_ctx); + int r = utils::init(pool_name, "", &rados, &io_ctx); if (r < 0) { return r; } @@ -993,9 +1000,10 @@ int execute_demote(const po::variables_map &vm, size_t arg_index = 0; std::string pool_name = utils::get_pool_name(vm, &arg_index); + // TODO support namespaces librados::Rados rados; librados::IoCtx io_ctx; - int r = utils::init(pool_name, &rados, &io_ctx); + int r = utils::init(pool_name, "", &rados, &io_ctx); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Namespace.cc b/src/tools/rbd/action/Namespace.cc index 92224c08942f6..c1971fa1785c9 100644 --- a/src/tools/rbd/action/Namespace.cc +++ b/src/tools/rbd/action/Namespace.cc @@ -39,7 +39,7 @@ int execute_create(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - int r = utils::init(pool_name, &rados, &io_ctx); + int r = utils::init(pool_name, "", &rados, &io_ctx); if (r < 0) { return r; } @@ -74,7 +74,7 @@ int execute_remove(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - int r = utils::init(pool_name, &rados, &io_ctx); + int r = utils::init(pool_name, "", &rados, &io_ctx); if (r < 0) { return r; } @@ -100,7 +100,6 @@ int execute_remove(const po::variables_map &vm, void get_list_arguments(po::options_description *positional, po::options_description *options) { at::add_pool_options(positional, options); - at::add_namespace_options(positional, options); at::add_format_options(options); } @@ -117,7 +116,7 @@ int execute_list(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, "", &rados, &io_ctx); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Nbd.cc b/src/tools/rbd/action/Nbd.cc index 7889181ff122e..dfe7a9f25fd0e 100644 --- a/src/tools/rbd/action/Nbd.cc +++ b/src/tools/rbd/action/Nbd.cc @@ -61,8 +61,8 @@ int get_image_or_snap_spec(const po::variables_map &vm, std::string *spec) { std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED, + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, nullptr, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_PERMITTED, utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; diff --git a/src/tools/rbd/action/ObjectMap.cc b/src/tools/rbd/action/ObjectMap.cc index c3fba097f0c47..40ee2d472f2c4 100644 --- a/src/tools/rbd/action/ObjectMap.cc +++ b/src/tools/rbd/action/ObjectMap.cc @@ -38,11 +38,12 @@ int execute_rebuild(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED, + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_PERMITTED, utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; @@ -51,8 +52,8 @@ int execute_rebuild(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", snap_name, false, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", + snap_name, false, &rados, &io_ctx, &image); if (r < 0) { return r; } @@ -89,11 +90,12 @@ int execute_check(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_PERMITTED, + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_PERMITTED, utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; @@ -102,8 +104,8 @@ int execute_check(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", snap_name, false, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", + snap_name, false, &rados, &io_ctx, &image); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Pool.cc b/src/tools/rbd/action/Pool.cc index 4e2dbca77e33d..52080a4ba8cc8 100644 --- a/src/tools/rbd/action/Pool.cc +++ b/src/tools/rbd/action/Pool.cc @@ -32,7 +32,7 @@ int execute_init(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - int r = utils::init(pool_name, &rados, &io_ctx); + int r = utils::init(pool_name, "", &rados, &io_ctx); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Remove.cc b/src/tools/rbd/action/Remove.cc index c19696d719920..337d42be610e5 100644 --- a/src/tools/rbd/action/Remove.cc +++ b/src/tools/rbd/action/Remove.cc @@ -59,18 +59,20 @@ int execute(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -126,12 +128,16 @@ int execute(const po::variables_map &vm, librados::IoCtx pool_io_ctx; image_r = rados.ioctx_create2(group_info.pool, pool_io_ctx); if (image_r < 0) { - pool_name = ""; + pool_name = ""; } else { pool_name = pool_io_ctx.get_pool_name(); } std::cerr << "rbd: error: image belongs to a group " - << pool_name << "/" << group_info.name; + << pool_name << "/"; + if (!io_ctx.get_namespace().empty()) { + std::cerr << io_ctx.get_namespace() << "/"; + } + std::cerr << group_info.name; } else std::cerr << "rbd: error: image belongs to a group"; diff --git a/src/tools/rbd/action/Rename.cc b/src/tools/rbd/action/Rename.cc index a223a815f5990..b4954bcbb90af 100644 --- a/src/tools/rbd/action/Rename.cc +++ b/src/tools/rbd/action/Rename.cc @@ -34,11 +34,13 @@ int execute(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -46,23 +48,30 @@ int execute(const po::variables_map &vm, std::string dst_image_name; std::string dst_snap_name; std::string dst_pool_name = pool_name; + std::string dst_namespace_name = namespace_name; r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_DEST, &arg_index, &dst_pool_name, &dst_image_name, - &dst_snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); + vm, at::ARGUMENT_MODIFIER_DEST, &arg_index, &dst_pool_name, + &dst_namespace_name, &dst_image_name, &dst_snap_name, true, + utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_FULL); if (r < 0) { return r; } if (pool_name != dst_pool_name) { std::cerr << "rbd: mv/rename across pools not supported" << std::endl - << "source pool: " << pool_name<< " dest pool: " << dst_pool_name + << "source pool: " << pool_name << " dest pool: " << dst_pool_name << std::endl; return -EINVAL; + } else if (namespace_name != dst_namespace_name) { + std::cerr << "rbd: mv/rename across namespaces not supported" << std::endl + << "source namespace: " << namespace_name << " dest namespace: " + << dst_namespace_name << std::endl; + return -EINVAL; } librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Resize.cc b/src/tools/rbd/action/Resize.cc index aed5fdad13752..361f03d953dab 100644 --- a/src/tools/rbd/action/Resize.cc +++ b/src/tools/rbd/action/Resize.cc @@ -40,11 +40,13 @@ int execute(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -58,8 +60,8 @@ int execute(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", snap_name, false, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", + snap_name, false, &rados, &io_ctx, &image); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Snap.cc b/src/tools/rbd/action/Snap.cc index d35ed5aa62341..74a346b875756 100644 --- a/src/tools/rbd/action/Snap.cc +++ b/src/tools/rbd/action/Snap.cc @@ -278,6 +278,7 @@ int execute_list(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; std::string image_id; @@ -286,32 +287,20 @@ int execute_list(const po::variables_map &vm, image_id = vm[at::IMAGE_ID].as(); } - bool has_image_spec = utils::check_if_image_spec_present( - vm, at::ARGUMENT_MODIFIER_NONE, arg_index); + int r = utils::get_pool_image_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, image_id.empty(), + utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + if (r < 0) { + return r; + } - if (!image_id.empty() && has_image_spec) { + if (!image_id.empty() && !image_name.empty()) { std::cerr << "rbd: trying to access image using both name and id. " << std::endl; return -EINVAL; } - int r; - if (image_id.empty()) { - r = utils::get_pool_image_snapshot_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, - &image_name, &snap_name, - utils::SNAPSHOT_PRESENCE_NONE, - utils::SPEC_VALIDATION_NONE); - } else { - r = utils::get_pool_snapshot_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &snap_name, - utils::SNAPSHOT_PRESENCE_NONE, - utils::SPEC_VALIDATION_NONE); - } - if (r < 0) { - return r; - } - at::Format::Formatter formatter; r = utils::get_formatter(vm, &formatter); if (r < 0) { @@ -321,8 +310,8 @@ int execute_list(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, image_id, "", true, - &rados, &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, + image_id, "", true, &rados, &io_ctx, &image); if (r < 0) { return r; } @@ -346,11 +335,13 @@ int execute_create(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_REQUIRED, utils::SPEC_VALIDATION_SNAP); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_REQUIRED, + utils::SPEC_VALIDATION_SNAP); if (r < 0) { return r; } @@ -358,8 +349,8 @@ int execute_create(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, &rados, - &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } @@ -387,6 +378,7 @@ int execute_remove(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; std::string image_id; @@ -396,36 +388,24 @@ int execute_remove(const po::variables_map &vm, image_id = vm[at::IMAGE_ID].as(); } - bool has_image_spec = utils::check_if_image_spec_present( - vm, at::ARGUMENT_MODIFIER_NONE, arg_index); + int r = utils::get_pool_image_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, image_id.empty(), + utils::SNAPSHOT_PRESENCE_REQUIRED, utils::SPEC_VALIDATION_NONE); + if (r < 0) { + return r; + } - if (!image_id.empty() && has_image_spec) { + if (!image_id.empty() && !image_name.empty()) { std::cerr << "rbd: trying to access image using both name and id. " << std::endl; return -EINVAL; } - int r; - if (image_id.empty()) { - r = utils::get_pool_image_snapshot_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, - &image_name, &snap_name, - utils::SNAPSHOT_PRESENCE_REQUIRED, - utils::SPEC_VALIDATION_NONE); - } else { - r = utils::get_pool_snapshot_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &snap_name, - utils::SNAPSHOT_PRESENCE_REQUIRED, - utils::SPEC_VALIDATION_NONE); - } - if (r < 0) { - return r; - } - librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -465,6 +445,7 @@ int execute_purge(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; std::string image_id; @@ -473,36 +454,24 @@ int execute_purge(const po::variables_map &vm, image_id = vm[at::IMAGE_ID].as(); } - bool has_image_spec = utils::check_if_image_spec_present( - vm, at::ARGUMENT_MODIFIER_NONE, arg_index); + int r = utils::get_pool_image_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, image_id.empty(), + utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + if (r < 0) { + return r; + } - if (!image_id.empty() && has_image_spec) { + if (!image_id.empty() && !image_name.empty()) { std::cerr << "rbd: trying to access image using both name and id. " << std::endl; return -EINVAL; } - int r; - if (image_id.empty()) { - r = utils::get_pool_image_snapshot_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, - &image_name, &snap_name, - utils::SNAPSHOT_PRESENCE_NONE, - utils::SPEC_VALIDATION_NONE); - } else { - r = utils::get_pool_snapshot_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &snap_name, - utils::SNAPSHOT_PRESENCE_NONE, - utils::SPEC_VALIDATION_NONE); - } - if (r < 0) { - return r; - } - librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -538,11 +507,13 @@ int execute_rollback(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_REQUIRED, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_REQUIRED, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -550,8 +521,8 @@ int execute_rollback(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, &rados, - &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } @@ -574,11 +545,13 @@ int execute_protect(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_REQUIRED, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_REQUIRED, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -586,8 +559,8 @@ int execute_protect(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, &rados, - &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } @@ -622,6 +595,7 @@ int execute_unprotect(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; std::string image_id; @@ -630,36 +604,24 @@ int execute_unprotect(const po::variables_map &vm, image_id = vm[at::IMAGE_ID].as(); } - bool has_image_spec = utils::check_if_image_spec_present( - vm, at::ARGUMENT_MODIFIER_NONE, arg_index); + int r = utils::get_pool_image_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, image_id.empty(), + utils::SNAPSHOT_PRESENCE_REQUIRED, utils::SPEC_VALIDATION_NONE); + if (r < 0) { + return r; + } - if (!image_id.empty() && has_image_spec) { + if (!image_id.empty() && !image_name.empty()) { std::cerr << "rbd: trying to access image using both name and id. " << std::endl; return -EINVAL; } - int r; - if (image_id.empty()) { - r = utils::get_pool_image_snapshot_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, - &image_name, &snap_name, - utils::SNAPSHOT_PRESENCE_REQUIRED, - utils::SPEC_VALIDATION_NONE); - } else { - r = utils::get_pool_snapshot_names(vm, at::ARGUMENT_MODIFIER_NONE, - &arg_index, &pool_name, &snap_name, - utils::SNAPSHOT_PRESENCE_REQUIRED, - utils::SPEC_VALIDATION_NONE); - } - if (r < 0) { - return r; - } - librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -704,13 +666,15 @@ int execute_set_limit(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; uint64_t limit; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -725,8 +689,8 @@ int execute_set_limit(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, &rados, - &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } @@ -749,12 +713,14 @@ int execute_clear_limit(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -762,8 +728,8 @@ int execute_clear_limit(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, &rados, - &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } @@ -787,23 +753,25 @@ int execute_rename(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string src_snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &image_name, - &src_snap_name, utils::SNAPSHOT_PRESENCE_REQUIRED, + vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &namespace_name, + &image_name, &src_snap_name, true, utils::SNAPSHOT_PRESENCE_REQUIRED, utils::SPEC_VALIDATION_NONE); if (r < 0) { return -r; } std::string dest_pool_name(pool_name); + std::string dest_namespace_name(namespace_name); std::string dest_image_name; std::string dest_snap_name; r = utils::get_pool_image_snapshot_names( vm, at::ARGUMENT_MODIFIER_DEST, &arg_index, &dest_pool_name, - &dest_image_name, &dest_snap_name, utils::SNAPSHOT_PRESENCE_REQUIRED, - utils::SPEC_VALIDATION_SNAP); + &dest_namespace_name, &dest_image_name, &dest_snap_name, true, + utils::SNAPSHOT_PRESENCE_REQUIRED, utils::SPEC_VALIDATION_SNAP); if (r < 0) { return -r; } @@ -812,17 +780,20 @@ int execute_rename(const po::variables_map &vm, std::cerr << "rbd: source and destination pool must be the same" << std::endl; return -EINVAL; + } else if (namespace_name != dest_namespace_name) { + std::cerr << "rbd: source and destination namespace must be the same" + << std::endl; } else if (image_name != dest_image_name) { std::cerr << "rbd: source and destination image name must be the same" << std::endl; return -EINVAL; } - + librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", false, &rados, - &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Status.cc b/src/tools/rbd/action/Status.cc index 4eb623f94697c..43b8b9b7286aa 100644 --- a/src/tools/rbd/action/Status.cc +++ b/src/tools/rbd/action/Status.cc @@ -68,11 +68,13 @@ int execute(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -86,8 +88,8 @@ int execute(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", true, &rados, - &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + true, &rados, &io_ctx, &image); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Trash.cc b/src/tools/rbd/action/Trash.cc index c0780416cad58..a96f2e584627a 100644 --- a/src/tools/rbd/action/Trash.cc +++ b/src/tools/rbd/action/Trash.cc @@ -54,19 +54,21 @@ int execute_move(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -104,8 +106,9 @@ int execute_move(const po::variables_map &vm, void get_remove_arguments(po::options_description *positional, po::options_description *options) { positional->add_options() - (at::IMAGE_ID.c_str(), "image id\n(example: [/])"); + (at::IMAGE_ID.c_str(), "image id\n(example: [/[/]])"); at::add_pool_option(options, at::ARGUMENT_MODIFIER_NONE); + at::add_namespace_option(options, at::ARGUMENT_MODIFIER_NONE); at::add_image_id_option(options); at::add_no_progress_option(options); @@ -143,15 +146,17 @@ int execute_remove(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_id; - int r = utils::get_pool_image_id(vm, &arg_index, &pool_name, &image_id); + int r = utils::get_pool_image_id(vm, &arg_index, &pool_name, &namespace_name, + &image_id); if (r < 0) { return r; } librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -163,7 +168,7 @@ int execute_remove(const po::variables_map &vm, r = rbd.trash_remove_with_progress(io_ctx, image_id.c_str(), vm["force"].as(), pc); if (r < 0) { - remove_error_check(r); + remove_error_check(r); pc.fail(); return r; } @@ -321,6 +326,7 @@ int do_list(librbd::RBD &rbd, librados::IoCtx& io_ctx, bool long_flag, void get_list_arguments(po::options_description *positional, po::options_description *options) { at::add_pool_options(positional, options); + at::add_namespace_options(positional, options); options->add_options() ("all,a", po::bool_switch(), "list images from all sources"); options->add_options() @@ -332,6 +338,7 @@ int execute_list(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name = utils::get_pool_name(vm, &arg_index); + std::string namespace_name = utils::get_namespace_name(vm, nullptr); at::Format::Formatter formatter; int r = utils::get_formatter(vm, &formatter); @@ -341,7 +348,7 @@ int execute_list(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -362,13 +369,14 @@ int execute_list(const po::variables_map &vm, void get_purge_arguments(po::options_description *positional, po::options_description *options) { at::add_pool_options(positional, options); + at::add_namespace_options(positional, options); at::add_no_progress_option(options); - + options->add_options() - (EXPIRED_BEFORE.c_str(), po::value()->value_name("date"), + (EXPIRED_BEFORE.c_str(), po::value()->value_name("date"), "purges images that expired before the given date"); options->add_options() - (THRESHOLD.c_str(), po::value(), + (THRESHOLD.c_str(), po::value(), "purges images until the current pool data usage is reduced to X%, " "value range: 0.0-1.0"); } @@ -378,10 +386,11 @@ int execute_purge (const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name = utils::get_pool_name(vm, &arg_index); + std::string namespace_name = utils::get_namespace_name(vm, nullptr); librados::Rados rados; librados::IoCtx io_ctx; - int r = utils::init(pool_name, &rados, &io_ctx); + int r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } @@ -390,10 +399,10 @@ int execute_purge (const po::variables_map &vm, io_ctx.set_osdmap_full_try(); librbd::RBD rbd; - + std::vector trash_entries; r = rbd.trash_list(io_ctx, trash_entries); - if (r < 0) { + if (r < 0) { return r; } @@ -417,7 +426,6 @@ int execute_purge (const po::variables_map &vm, librados::bufferlist outbl; rados.mon_command("{\"prefix\": \"df\", \"format\": \"json\"}", inbl, &outbl, NULL); - json_spirit::mValue json; if(!json_spirit::read(outbl.to_str(), json)) { @@ -476,15 +484,15 @@ int execute_purge (const po::variables_map &vm, pool_total_bytes = stats["max_avail"].get_uint64() + stats["bytes_used"].get_uint64(); - - auto bytes_threshold = (uint64_t)(pool_total_bytes * + + auto bytes_threshold = (uint64_t)(pool_total_bytes * (pool_percent_used - threshold)); - + librbd::Image curr_img; for(const auto &it : img->second){ r = utils::open_image_by_id(io_ctx, it, true, &curr_img); if(r < 0) continue; - + uint64_t img_size; curr_img.size(&img_size); r = curr_img.diff_iterate2(nullptr, 0, img_size, false, true, [](uint64_t offset, size_t len, int exists, void *arg) { @@ -511,7 +519,7 @@ int execute_purge (const po::variables_map &vm, clock_gettime(CLOCK_REALTIME, &now); time_t expire_ts = now.tv_sec; - if (vm.find(EXPIRED_BEFORE) != vm.end()) { + if (vm.find(EXPIRED_BEFORE) != vm.end()) { utime_t new_time; r = utime_t::invoke_date(vm[EXPIRED_BEFORE].as(), &new_time); if (r < 0) { @@ -522,7 +530,7 @@ int execute_purge (const po::variables_map &vm, expire_ts = new_time.sec(); } - for(const auto &entry : trash_entries) { + for(const auto &entry : trash_entries) { if (expire_ts >= entry.deferment_end_time) { to_be_removed.push_back(entry.id.c_str()); } @@ -534,7 +542,8 @@ int execute_purge (const po::variables_map &vm, if(list_size == 0) { std::cout << "rbd: nothing to remove" << std::endl; } else { - utils::ProgressContext pc("Removing images", vm[at::NO_PROGRESS].as()); + utils::ProgressContext pc("Removing images", + vm[at::NO_PROGRESS].as()); for(const auto &entry_id : to_be_removed) { r = rbd.trash_remove(io_ctx, entry_id, true); if (r < 0) { @@ -555,6 +564,7 @@ void get_restore_arguments(po::options_description *positional, positional->add_options() (at::IMAGE_ID.c_str(), "image id\n(example: [/])"); at::add_pool_option(options, at::ARGUMENT_MODIFIER_NONE); + at::add_namespace_option(options, at::ARGUMENT_MODIFIER_NONE); at::add_image_id_option(options); at::add_image_option(options, at::ARGUMENT_MODIFIER_NONE, ""); } @@ -563,15 +573,17 @@ int execute_restore(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_id; - int r = utils::get_pool_image_id(vm, &arg_index, &pool_name, &image_id); + int r = utils::get_pool_image_id(vm, &arg_index, &pool_name, &namespace_name, + &image_id); if (r < 0) { return r; } librados::Rados rados; librados::IoCtx io_ctx; - r = utils::init(pool_name, &rados, &io_ctx); + r = utils::init(pool_name, namespace_name, &rados, &io_ctx); if (r < 0) { return r; } diff --git a/src/tools/rbd/action/Watch.cc b/src/tools/rbd/action/Watch.cc index 6957dae415174..65f0f93dfc4a3 100644 --- a/src/tools/rbd/action/Watch.cc +++ b/src/tools/rbd/action/Watch.cc @@ -113,11 +113,13 @@ int execute(const po::variables_map &vm, const std::vector &ceph_global_init_args) { size_t arg_index = 0; std::string pool_name; + std::string namespace_name; std::string image_name; std::string snap_name; int r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name, + &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE, + utils::SPEC_VALIDATION_NONE); if (r < 0) { return r; } @@ -125,8 +127,8 @@ int execute(const po::variables_map &vm, librados::Rados rados; librados::IoCtx io_ctx; librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", "", true, &rados, - &io_ctx, &image); + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + true, &rados, &io_ctx, &image); if (r < 0) { return r; } -- 2.39.5