]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: add support for namespaces 22673/head
authorJason Dillaman <dillaman@redhat.com>
Thu, 21 Jun 2018 19:23:59 +0000 (15:23 -0400)
committerJason Dillaman <dillaman@redhat.com>
Fri, 22 Jun 2018 14:43:51 +0000 (10:43 -0400)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
41 files changed:
doc/man/8/rbd.rst
qa/workunits/rbd/cli_generic.sh
src/test/cli/rbd/help.t
src/test/cli/rbd/invalid-snap-usage.t
src/test/cli/rbd/not-enough-args.t
src/tools/rbd/ArgumentTypes.cc
src/tools/rbd/ArgumentTypes.h
src/tools/rbd/Utils.cc
src/tools/rbd/Utils.h
src/tools/rbd/action/Bench.cc
src/tools/rbd/action/Children.cc
src/tools/rbd/action/Clone.cc
src/tools/rbd/action/Copy.cc
src/tools/rbd/action/Create.cc
src/tools/rbd/action/Diff.cc
src/tools/rbd/action/DiskUsage.cc
src/tools/rbd/action/Export.cc
src/tools/rbd/action/Feature.cc
src/tools/rbd/action/Flatten.cc
src/tools/rbd/action/Ggate.cc
src/tools/rbd/action/Group.cc
src/tools/rbd/action/ImageMeta.cc
src/tools/rbd/action/Import.cc
src/tools/rbd/action/Info.cc
src/tools/rbd/action/Journal.cc
src/tools/rbd/action/Kernel.cc
src/tools/rbd/action/List.cc
src/tools/rbd/action/Lock.cc
src/tools/rbd/action/MirrorImage.cc
src/tools/rbd/action/MirrorPool.cc
src/tools/rbd/action/Namespace.cc
src/tools/rbd/action/Nbd.cc
src/tools/rbd/action/ObjectMap.cc
src/tools/rbd/action/Pool.cc
src/tools/rbd/action/Remove.cc
src/tools/rbd/action/Rename.cc
src/tools/rbd/action/Resize.cc
src/tools/rbd/action/Snap.cc
src/tools/rbd/action/Status.cc
src/tools/rbd/action/Trash.cc
src/tools/rbd/action/Watch.cc

index b5b72ebd0eab50b2a5c96cfbc15c14a221f9fdc5..40f986ab9d5064a7710bf826c6e005aadeaf2868 100644 (file)
@@ -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
 ========
index 219186015055c2cdb64f1ccec8cf55fb5587526a..adb1ccf06f88733c69522a2fc5a20d37492477d0 100755 (executable)
@@ -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
 
index efc9e2ffc6d719eb4cc2fbb9545ecca8861c6445..2304409dcfde7965e7d99938c483beb6fd0b5db9 100644 (file)
@@ -7,7 +7,7 @@
     <command>
       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.
   See 'rbd help <command>' 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 <pool>] [--image <image>] [--io-size <io-size>] 
-                   [--io-threads <io-threads>] [--io-total <io-total>] 
-                   [--io-pattern <io-pattern>] 
+  usage: rbd bench [--pool <pool>] [--namespace <namespace>] [--image <image>] 
+                   [--io-size <io-size>] [--io-threads <io-threads>] 
+                   [--io-total <io-total>] [--io-pattern <io-pattern>] 
                    [--rw-mix-read <rw-mix-read>] --io-type <io-type> 
                    <image-spec> 
   
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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]
     --io-type arg        IO type (read , write, or readwrite(rw))
   
   rbd help children
-  usage: rbd children [--pool <pool>] [--image <image>] [--snap <snap>] 
-                      [--snap-id <snap-id>] [--all] [--format <format>] 
-                      [--pretty-format] 
+  usage: rbd children [--pool <pool>] [--namespace <namespace>] 
+                      [--image <image>] [--snap <snap>] [--snap-id <snap-id>] 
+                      [--all] [--format <format>] [--pretty-format] 
                       <snap-spec> 
   
   Display children of snapshot.
   
   Positional arguments
     <snap-spec>          snapshot specification
-                         (example: [<pool-name>/]<image-name>@<snapshot-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<image-name>@<snapshot-n
+                         ame>)
   
   Optional arguments
     -p [ --pool ] arg    pool name
+    --namespace arg      namespace name
     --image arg          image name
     --snap arg           snapshot name
     --snap-id arg        snapshot id
     --pretty-format      pretty formatting (json and xml)
   
   rbd help clone
-  usage: rbd clone [--pool <pool>] [--image <image>] [--snap <snap>] 
-                   [--dest-pool <dest-pool>] [--dest <dest>] [--order <order>] 
-                   [--object-size <object-size>] 
+  usage: rbd clone [--pool <pool>] [--namespace <namespace>] [--image <image>] 
+                   [--snap <snap>] [--dest-pool <dest-pool>] 
+                   [--dest-namespace <dest-namespace>] [--dest <dest>] 
+                   [--order <order>] [--object-size <object-size>] 
                    [--image-feature <image-feature>] [--image-shared] 
                    [--stripe-unit <stripe-unit>] [--stripe-count <stripe-count>] 
                    [--data-pool <data-pool>] 
                    [--journal-pool <journal-pool>] 
                    <source-snap-spec> <dest-image-spec> 
   
-  Clone a snapshot into a COW child image.
+  Clone a snapshot into a CoW child image.
   
   Positional arguments
     <source-snap-spec>        source snapshot specification
                               (example:
-                              [<pool-name>/]<image-name>@<snapshot-name>)
+                              [<pool-name>/[<namespace-name>/]]<image-name>@<snaps
+                              hot-name>)
     <dest-image-spec>         destination image specification
-                              (example: [<pool-name>/]<image-name>)
+                              (example:
+                              [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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]
     (+) enabled by default for new images if features not specified
   
   rbd help copy
-  usage: rbd copy [--pool <pool>] [--image <image>] [--snap <snap>] 
-                  [--dest-pool <dest-pool>] [--dest <dest>] [--order <order>] 
-                  [--object-size <object-size>] 
+  usage: rbd copy [--pool <pool>] [--namespace <namespace>] [--image <image>] 
+                  [--snap <snap>] [--dest-pool <dest-pool>] 
+                  [--dest-namespace <dest-namespace>] [--dest <dest>] 
+                  [--order <order>] [--object-size <object-size>] 
                   [--image-feature <image-feature>] [--image-shared] 
                   [--stripe-unit <stripe-unit>] [--stripe-count <stripe-count>] 
                   [--data-pool <data-pool>] 
   Positional arguments
     <source-image-or-snap-spec>  source image or snapshot specification
                                  (example:
-                                 [<pool-name>/]<image-name>[@<snap-name>])
+                                 [<pool-name>/[<namespace-name>/]]<image-name>[@<s
+                                 nap-name>])
     <dest-image-spec>            destination image specification
-                                 (example: [<pool-name>/]<image-name>)
+                                 (example:
+                                 [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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]
     (+) enabled by default for new images if features not specified
   
   rbd help create
-  usage: rbd create [--pool <pool>] [--image <image>] 
+  usage: rbd create [--pool <pool>] [--namespace <namespace>] [--image <image>] 
                     [--image-format <image-format>] [--new-format] 
                     [--order <order>] [--object-size <object-size>] 
                     [--image-feature <image-feature>] [--image-shared] 
   
   Positional arguments
     <image-spec>              image specification
-                              (example: [<pool-name>/]<image-name>)
+                              (example:
+                              [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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
     (+) enabled by default for new images if features not specified
   
   rbd help deep copy
-  usage: rbd deep copy [--pool <pool>] [--image <image>] [--snap <snap>] 
-                       [--dest-pool <dest-pool>] [--dest <dest>] 
+  usage: rbd deep copy [--pool <pool>] [--namespace <namespace>] 
+                       [--image <image>] [--snap <snap>] 
+                       [--dest-pool <dest-pool>] 
+                       [--dest-namespace <dest-namespace>] [--dest <dest>] 
                        [--order <order>] [--object-size <object-size>] 
                        [--image-feature <image-feature>] [--image-shared] 
                        [--stripe-unit <stripe-unit>] 
   Positional arguments
     <source-image-or-snap-spec>  source image or snapshot specification
                                  (example:
-                                 [<pool-name>/]<image-name>[@<snap-name>])
+                                 [<pool-name>/[<namespace-name>/]]<image-name>[@<s
+                                 nap-name>])
     <dest-image-spec>            destination image specification
-                                 (example: [<pool-name>/]<image-name>)
+                                 (example:
+                                 [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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]
   
   rbd help device map
   usage: rbd device map [--device-type <device-type>] [--pool <pool>] 
-                        [--image <image>] [--snap <snap>] [--read-only] 
-                        [--exclusive] [--options <options>] 
+                        [--namespace <namespace>] [--image <image>] 
+                        [--snap <snap>] [--read-only] [--exclusive] 
+                        [--options <options>] 
                         <image-or-snap-spec> 
   
   Map an image to a block device.
   
   Positional arguments
     <image-or-snap-spec>     image or snapshot specification
-                             (example: [<pool-name>/]<image-name>[@<snap-name>])
+                             (example:
+                             [<pool-name>/[<namespace-name>/]]<image-name>[@<snap-
+                             name>])
   
   Optional arguments
     -t [ --device-type ] arg device type [ggate, krbd (default), nbd]
     -p [ --pool ] arg        pool name
+    --namespace arg          namespace name
     --image arg              image name
     --snap arg               snapshot name
     --read-only              map read-only
     -o [ --options ] arg            device specific options
   
   rbd help diff
-  usage: rbd diff [--pool <pool>] [--image <image>] [--snap <snap>] 
-                  [--from-snap <from-snap>] [--whole-object] [--format <format>
-                  [--pretty-format] 
+  usage: rbd diff [--pool <pool>] [--namespace <namespace>] [--image <image>] 
+                  [--snap <snap>] [--from-snap <from-snap>] [--whole-object
+                  [--format <format>] [--pretty-format] 
                   <image-or-snap-spec> 
   
   Print extents that differ since a previous snap, or image creation.
   
   Positional arguments
     <image-or-snap-spec>  image or snapshot specification
-                          (example: [<pool-name>/]<image-name>[@<snap-name>])
+                          (example:
+                          [<pool-name>/[<namespace-name>/]]<image-name>[@<snap-nam
+                          e>])
   
   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
     --pretty-format       pretty formatting (json and xml)
   
   rbd help disk-usage
-  usage: rbd disk-usage [--pool <pool>] [--image <image>] [--snap <snap>] 
-                        [--format <format>] [--pretty-format
-                        [--from-snap <from-snap>] [--exact] 
+  usage: rbd disk-usage [--pool <pool>] [--namespace <namespace>] 
+                        [--image <image>] [--snap <snap>] [--format <format>
+                        [--pretty-format] [--from-snap <from-snap>] [--exact] 
                         <image-or-snap-spec> 
   
   Show disk usage stats for pool, image or snapshot.
   
   Positional arguments
     <image-or-snap-spec>  image or snapshot specification
-                          (example: [<pool-name>/]<image-name>[@<snap-name>])
+                          (example:
+                          [<pool-name>/[<namespace-name>/]]<image-name>[@<snap-nam
+                          e>])
   
   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]
     --exact               compute exact disk usage (slow)
   
   rbd help export
-  usage: rbd export [--pool <pool>] [--image <image>] [--snap <snap>] 
-                    [--path <path>] [--no-progress] 
+  usage: rbd export [--pool <pool>] [--namespace <namespace>] [--image <image>] 
+                    [--snap <snap>] [--path <path>] [--no-progress] 
                     [--export-format <export-format>] 
                     <source-image-or-snap-spec> <path-name> 
   
   Positional arguments
     <source-image-or-snap-spec>  source image or snapshot specification
                                  (example:
-                                 [<pool-name>/]<image-name>[@<snap-name>])
+                                 [<pool-name>/[<namespace-name>/]]<image-name>[@<s
+                                 nap-name>])
     <path-name>                  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)
     --export-format arg          format of image file
   
   rbd help export-diff
-  usage: rbd export-diff [--pool <pool>] [--image <image>] [--snap <snap>] 
-                         [--path <path>] [--from-snap <from-snap>] 
-                         [--whole-object] [--no-progress] 
+  usage: rbd export-diff [--pool <pool>] [--namespace <namespace>] 
+                         [--image <image>] [--snap <snap>] [--path <path>] 
+                         [--from-snap <from-snap>] [--whole-object] 
+                         [--no-progress] 
                          <source-image-or-snap-spec> <path-name> 
   
   Export incremental diff to file.
   Positional arguments
     <source-image-or-snap-spec>  source image or snapshot specification
                                  (example:
-                                 [<pool-name>/]<image-name>[@<snap-name>])
+                                 [<pool-name>/[<namespace-name>/]]<image-name>[@<s
+                                 nap-name>])
     <path-name>                  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)
     --no-progress                disable progress output
   
   rbd help feature disable
-  usage: rbd feature disable [--pool <pool>] [--image <image>] 
+  usage: rbd feature disable [--pool <pool>] [--namespace <namespace>] 
+                             [--image <image>] 
                              <image-spec> <features> [<features> ...]
   
   Disable the specified image feature.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
     <features>           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 <pool>] [--image <image>] 
+  usage: rbd feature enable [--pool <pool>] [--namespace <namespace>] 
+                            [--image <image>] 
                             [--journal-splay-width <journal-splay-width>] 
                             [--journal-object-size <journal-object-size>] 
                             [--journal-pool <journal-pool>] 
   
   Positional arguments
     <image-spec>              image specification
-                              (example: [<pool-name>/]<image-name>)
+                              (example:
+                              [<pool-name>/[<namespace-name>/]]<image-name>)
     <features>                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 <pool>] [--image <image>] [--no-progress] 
+  usage: rbd flatten [--pool <pool>] [--namespace <namespace>] [--image <image>] 
+                     [--no-progress] 
                      <image-spec> 
   
   Fill clone with parent data (make it independent).
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--group <group>] 
+  usage: rbd group create [--pool <pool>] [--namespace <namespace>] 
+                          [--group <group>] 
                           <group-spec> 
   
   Create a group.
   
   Positional arguments
     <group-spec>         group specification
-                         (example: [<pool-name>/]<group-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<group-name>)
   
   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-pool>] [--group <group>] 
-                             [--image-pool <image-pool>] [--image <image>] 
-                             [--pool <pool>] 
+  usage: rbd group image add [--group-pool <group-pool>] 
+                             [--group-namespace <group-namespace>] 
+                             [--group <group>] [--image-pool <image-pool>] 
+                             [--image-namespace <image-namespace>] 
+                             [--image <image>] [--pool <pool>] 
                              <group-spec> <image-spec> 
   
   Add an image to a group.
   
   Positional arguments
-    <group-spec>         group specification
-                         (example: [<pool-name>/]<group-name>)
-    <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+    <group-spec>          group specification
+                          (example: [<pool-name>/[<namespace-name>/]]<group-name>)
+    <image-spec>          image specification
+                          (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <format>] [--pretty-format] 
-                              [--pool <pool>] [--group <group>] 
+                              [--pool <pool>] [--namespace <namespace>] 
+                              [--group <group>] 
                               <group-spec> 
   
   List images in a group.
   
   Positional arguments
     <group-spec>         group specification
-                         (example: [<pool-name>/]<group-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<group-name>)
   
   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-pool>] [--group <group>] 
-                                [--image-pool <image-pool>] [--image <image>] 
-                                [--pool <pool>] [--image-id <image-id>] 
+  usage: rbd group image remove [--group-pool <group-pool>] 
+                                [--group-namespace <group-namespace>] 
+                                [--group <group>] [--image-pool <image-pool>] 
+                                [--image-namespace <image-namespace>] 
+                                [--image <image>] [--pool <pool>] 
+                                [--image-id <image-id>] 
                                 <group-spec> <image-spec> 
   
   Remove an image from a group.
   
   Positional arguments
-    <group-spec>         group specification
-                         (example: [<pool-name>/]<group-name>)
-    <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+    <group-spec>          group specification
+                          (example: [<pool-name>/[<namespace-name>/]]<group-name>)
+    <image-spec>          image specification
+                          (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--format <format>] [--pretty-format] 
+  usage: rbd group list [--pool <pool>] [--namespace <namespace>] 
+                        [--format <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 <pool>] [--group <group>] 
+  usage: rbd group remove [--pool <pool>] [--namespace <namespace>] 
+                          [--group <group>] 
                           <group-spec> 
   
   Delete a group.
   
   Positional arguments
     <group-spec>         group specification
-                         (example: [<pool-name>/]<group-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<group-name>)
   
   Optional arguments
     -p [ --pool ] arg    pool name
+    --namespace arg      namespace name
     --group arg          group name
   
   rbd help group rename
-  usage: rbd group rename [--pool <pool>] [--group <group>] 
-                          [--dest-pool <dest-pool>] [--dest-group <dest-group>] 
+  usage: rbd group rename [--pool <pool>] [--namespace <namespace>] 
+                          [--group <group>] [--dest-pool <dest-pool>] 
+                          [--dest-namespace <dest-namespace>] 
+                          [--dest-group <dest-group>] 
                           <source-group-spec> <dest-group-spec> 
   
   Rename a group within pool.
   
   Positional arguments
     <source-group-spec>  source group specification
-                         (example: [<pool-name>/]<group-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<group-name>)
     <dest-group-spec>    destination group specification
-                         (example: [<pool-name>/]<group-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<group-name>)
   
   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 <pool>] [--group <group>] [--snap <snap>] 
+  usage: rbd group snap create [--pool <pool>] [--namespace <namespace>] 
+                               [--group <group>] [--snap <snap>] 
                                <group-snap-spec> 
   
   Make a snapshot of a group.
   
   Positional arguments
     <group-snap-spec>    group specification
-                         (example: [<pool-name>/]<group-name>@<snap-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<group-name>@<snap-name>
+                         )
   
   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 <format>] [--pretty-format] 
-                             [--pool <pool>] [--group <group>] 
+                             [--pool <pool>] [--namespace <namespace>] 
+                             [--group <group>] 
                              <group-spec> 
   
   List snapshots of a group.
   
   Positional arguments
     <group-spec>         group specification
-                         (example: [<pool-name>/]<group-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<group-name>)
   
   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 <pool>] [--group <group>] [--snap <snap>] 
+  usage: rbd group snap remove [--pool <pool>] [--namespace <namespace>] 
+                               [--group <group>] [--snap <snap>] 
                                <group-snap-spec> 
   
   Remove a snapshot from a group.
   
   Positional arguments
     <group-snap-spec>    group specification
-                         (example: [<pool-name>/]<group-name>@<snap-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<group-name>@<snap-name>
+                         )
   
   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 <pool>] [--group <group>] [--snap <snap>] 
+  usage: rbd group snap rename [--pool <pool>] [--namespace <namespace>] 
+                               [--group <group>] [--snap <snap>] 
                                [--dest-snap <dest-snap>] 
                                <group-snap-spec> <dest-snap> 
   
   
   Positional arguments
     <group-snap-spec>    group specification
-                         (example: [<pool-name>/]<group-name>@<snap-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<group-name>@<snap-name>
+                         )
     <dest-snap>          destination snapshot name
                          (example: <snapshot-name>)
   
   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 <pool>] [--image <image>] 
+  usage: rbd image-meta get [--pool <pool>] [--namespace <namespace>] 
+                            [--image <image>] 
                             <image-spec> <key> 
   
   Image metadata get the value associated with the key.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
     <key>                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 <pool>] [--image <image>] 
-                             [--format <format>] [--pretty-format] 
+  usage: rbd image-meta list [--pool <pool>] [--namespace <namespace>] 
+                             [--image <image>] [--format <format>] 
+                             [--pretty-format] 
                              <image-spec> 
   
   Image metadata list keys with values.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--image <image>] 
+  usage: rbd image-meta remove [--pool <pool>] [--namespace <namespace>] 
+                               [--image <image>] 
                                <image-spec> <key> 
   
   Image metadata remove the key and value associated.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
     <key>                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 <pool>] [--image <image>] 
+  usage: rbd image-meta set [--pool <pool>] [--namespace <namespace>] 
+                            [--image <image>] 
                             <image-spec> <key> <value> 
   
   Image metadata set key with value.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
     <key>                image meta key
     <value>              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 <path>] [--dest-pool <dest-pool>] [--dest <dest>] 
+  usage: rbd import [--path <path>] [--dest-pool <dest-pool>] 
+                    [--dest-namespace <dest-namespace>] [--dest <dest>] 
                     [--image-format <image-format>] [--new-format] 
                     [--order <order>] [--object-size <object-size>] 
                     [--image-feature <image-feature>] [--image-shared] 
   Positional arguments
     <path-name>               import file (or '-' for stdin)
     <dest-image-spec>         destination image specification
-                              (example: [<pool-name>/]<image-name>)
+                              (example:
+                              [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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
     (+) enabled by default for new images if features not specified
   
   rbd help import-diff
-  usage: rbd import-diff [--path <path>] [--pool <pool>] [--image <image>] 
+  usage: rbd import-diff [--path <path>] [--pool <pool>] 
+                         [--namespace <namespace>] [--image <image>] 
                          [--sparse-size <sparse-size>] [--no-progress] 
                          <path-name> <image-spec> 
   
   Positional arguments
     <path-name>          import file (or '-' for stdin)
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--image <image>] [--snap <snap>] 
-                  [--image-id <image-id>] [--format <format>] [--pretty-format] 
+  usage: rbd info [--pool <pool>] [--namespace <namespace>] [--image <image>] 
+                  [--snap <snap>] [--image-id <image-id>] [--format <format>] 
+                  [--pretty-format] 
                   <image-or-snap-spec> 
   
   Show information about image size, striping, etc.
   
   Positional arguments
     <image-or-snap-spec>  image or snapshot specification
-                          (example: [<pool-name>/]<image-name>[@<snap-name>])
+                          (example:
+                          [<pool-name>/[<namespace-name>/]]<image-name>[@<snap-nam
+                          e>])
   
   Optional arguments
     -p [ --pool ] arg     pool name
+    --namespace arg       namespace name
     --image arg           image name
     --snap arg            snapshot name
     --image-id arg        image id
     --pretty-format       pretty formatting (json and xml)
   
   rbd help journal client disconnect
-  usage: rbd journal client disconnect [--pool <pool>] [--image <image>] 
-                                       [--journal <journal>] 
+  usage: rbd journal client disconnect [--pool <pool>] [--namespace <namespace>] 
+                                       [--image <image>] [--journal <journal>] 
                                        [--client-id <client-id>] 
                                        <journal-spec> 
   
   
   Positional arguments
     <journal-spec>       journal specification
-                         (example: [<pool-name>/]<journal-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<journal-name>)
   
   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 <pool>] [--image <image>] 
-                            [--journal <journal>] [--path <path>] [--verbose
-                            [--no-error] 
+  usage: rbd journal export [--pool <pool>] [--namespace <namespace>] 
+                            [--image <image>] [--journal <journal>
+                            [--path <path>] [--verbose] [--no-error] 
                             <source-journal-spec> <path-name> 
   
   Export image journal.
   
   Positional arguments
     <source-journal-spec>  source journal specification
-                           (example: [<pool-name>/]<journal-name>)
+                           (example:
+                           [<pool-name>/[<namespace-name>/]]<journal-name>)
     <path-name>            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)
   
   rbd help journal import
   usage: rbd journal import [--path <path>] [--dest-pool <dest-pool>] 
-                            [--dest <dest>] [--dest-journal <dest-journal>] 
-                            [--verbose] [--no-error] 
+                            [--dest-namespace <dest-namespace>] [--dest <dest>] 
+                            [--dest-journal <dest-journal>] [--verbose] 
+                            [--no-error] 
                             <path-name> <dest-journal-spec> 
   
   Import image journal.
   Positional arguments
     <path-name>          import file (or '-' for stdin)
     <dest-journal-spec>  destination journal specification
-                         (example: [<pool-name>/]<journal-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<journal-name>)
   
   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 <pool>] [--image <image>] 
-                          [--journal <journal>] [--format <format>] 
-                          [--pretty-format] 
+  usage: rbd journal info [--pool <pool>] [--namespace <namespace>] 
+                          [--image <image>] [--journal <journal>] 
+                          [--format <format>] [--pretty-format] 
                           <journal-spec> 
   
   Show information about image journal.
   
   Positional arguments
     <journal-spec>       journal specification
-                         (example: [<pool-name>/]<journal-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<journal-name>)
   
   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 <pool>] [--image <image>] 
-                             [--journal <journal>] [--verbose] 
+  usage: rbd journal inspect [--pool <pool>] [--namespace <namespace>] 
+                             [--image <image>] [--journal <journal>] [--verbose] 
                              <journal-spec> 
   
   Inspect image journal for structural errors.
   
   Positional arguments
     <journal-spec>       journal specification
-                         (example: [<pool-name>/]<journal-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<journal-name>)
   
   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 <pool>] [--image <image>] 
-                           [--journal <journal>] 
+  usage: rbd journal reset [--pool <pool>] [--namespace <namespace>] 
+                           [--image <image>] [--journal <journal>] 
                            <journal-spec> 
   
   Reset image journal.
   
   Positional arguments
     <journal-spec>       journal specification
-                         (example: [<pool-name>/]<journal-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<journal-name>)
   
   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 <pool>] [--image <image>] 
-                            [--journal <journal>] [--format <format>] 
-                            [--pretty-format] 
+  usage: rbd journal status [--pool <pool>] [--namespace <namespace>] 
+                            [--image <image>] [--journal <journal>] 
+                            [--format <format>] [--pretty-format] 
                             <journal-spec> 
   
   Show status of image journal.
   
   Positional arguments
     <journal-spec>       journal specification
-                         (example: [<pool-name>/]<journal-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<journal-name>)
   
   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 <pool>] [--format <format>] [--pretty-format] 
-                  <pool-name> 
+  usage: rbd list [--long] [--pool <pool>] [--namespace <namespace>] 
+                  [--format <format>] [--pretty-format] 
+                  <pool-name> <namespace-name> 
   
   List rbd images.
   
   Positional arguments
     <pool-name>          pool name
+    <namespace-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 <pool>] [--image <image>] [--shared <shared>] 
+  usage: rbd lock add [--pool <pool>] [--namespace <namespace>] 
+                      [--image <image>] [--shared <shared>] 
                       <image-spec> <lock-id> 
   
   Take a lock on an image.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
     <lock-id>            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 <pool>] [--image <image>] [--format <format>] 
-                       [--pretty-format] 
+  usage: rbd lock list [--pool <pool>] [--namespace <namespace>] 
+                       [--image <image>] [--format <format>] [--pretty-format] 
                        <image-spec> 
   
   Show locks held on an image.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--image <image>] 
+  usage: rbd lock remove [--pool <pool>] [--namespace <namespace>] 
+                         [--image <image>] 
                          <image-spec> <lock-id> <locker> 
   
   Release a lock on an image.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
     <lock-id>            unique lock id
     <locker>             locker client
   
   Optional arguments
     -p [ --pool ] arg    pool name
+    --namespace arg      namespace name
     --image arg          image name
   
   rbd help merge-diff
     --no-progress        disable progress output
   
   rbd help mirror image demote
-  usage: rbd mirror image demote [--pool <pool>] [--image <image>] 
+  usage: rbd mirror image demote [--pool <pool>] [--namespace <namespace>] 
+                                 [--image <image>] 
                                  <image-spec> 
   
   Demote an image to non-primary for RBD mirroring.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--image <image>] 
+  usage: rbd mirror image disable [--force] [--pool <pool>] 
+                                  [--namespace <namespace>] [--image <image>] 
                                   <image-spec> 
   
   Disable RBD mirroring for an image.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--image <image>] 
+  usage: rbd mirror image enable [--pool <pool>] [--namespace <namespace>] 
+                                 [--image <image>] 
                                  <image-spec> 
   
   Enable RBD mirroring for an image.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--image <image>] 
+  usage: rbd mirror image promote [--force] [--pool <pool>] 
+                                  [--namespace <namespace>] [--image <image>] 
                                   <image-spec> 
   
   Promote an image to primary for RBD mirroring.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--image <image>] 
+  usage: rbd mirror image resync [--pool <pool>] [--namespace <namespace>] 
+                                 [--image <image>] 
                                  <image-spec> 
   
   Force resync to primary image for RBD mirroring.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--image <image>] 
-                                 [--format <format>] [--pretty-format] 
+  usage: rbd mirror image status [--pool <pool>] [--namespace <namespace>] 
+                                 [--image <image>] [--format <format>] 
+                                 [--pretty-format] 
                                  <image-spec> 
   
   Show RBD mirroring status for an image.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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)
     --namespace arg      namespace name
   
   rbd help namespace list
-  usage: rbd namespace list [--pool <pool>] [--namespace <namespace>] 
-                            [--format <format>] [--pretty-format] 
-                            <pool-name> <namespace-name> 
+  usage: rbd namespace list [--pool <pool>] [--format <format>] [--pretty-format] 
+                            <pool-name> 
   
   List RBD image namespaces.
   
   Positional arguments
     <pool-name>          pool name
-    <namespace-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)
   
     --namespace arg      namespace name
   
   rbd help object-map check
-  usage: rbd object-map check [--pool <pool>] [--image <image>] [--snap <snap>] 
-                              [--no-progress] 
+  usage: rbd object-map check [--pool <pool>] [--namespace <namespace>] 
+                              [--image <image>] [--snap <snap>] [--no-progress] 
                               <image-or-snap-spec> 
   
   Verify the object map is correct.
   
   Positional arguments
     <image-or-snap-spec>  image or snapshot specification
-                          (example: [<pool-name>/]<image-name>[@<snap-name>])
+                          (example:
+                          [<pool-name>/[<namespace-name>/]]<image-name>[@<snap-nam
+                          e>])
   
   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 <pool>] [--image <image>] 
-                                [--snap <snap>] [--no-progress] 
+  usage: rbd object-map rebuild [--pool <pool>] [--namespace <namespace>] 
+                                [--image <image>] [--snap <snap>] [--no-progress] 
                                 <image-or-snap-spec> 
   
   Rebuild an invalid object map.
   
   Positional arguments
     <image-or-snap-spec>  image or snapshot specification
-                          (example: [<pool-name>/]<image-name>[@<snap-name>])
+                          (example:
+                          [<pool-name>/[<namespace-name>/]]<image-name>[@<snap-nam
+                          e>])
   
   Optional arguments
     -p [ --pool ] arg     pool name
+    --namespace arg       namespace name
     --image arg           image name
     --snap arg            snapshot name
     --no-progress         disable progress output
                          another application
   
   rbd help remove
-  usage: rbd remove [--pool <pool>] [--image <image>] [--no-progress] 
+  usage: rbd remove [--pool <pool>] [--namespace <namespace>] [--image <image>] 
+                    [--no-progress] 
                     <image-spec> 
   
   Delete an image.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--image <image>] [--dest-pool <dest-pool>] 
-                    [--dest <dest>] 
+  usage: rbd rename [--pool <pool>] [--namespace <namespace>] [--image <image>] 
+                    [--dest-pool <dest-pool>] 
+                    [--dest-namespace <dest-namespace>] [--dest <dest>] 
                     <source-image-spec> <dest-image-spec> 
   
   Rename image within pool.
   
   Positional arguments
     <source-image-spec>  source image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
     <dest-image-spec>    destination image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--image <image>] --size <size> 
-                    [--allow-shrink] [--no-progress] 
+  usage: rbd resize [--pool <pool>] [--namespace <namespace>] 
+                    [--image <image>] --size <size> [--allow-shrink] 
+                    [--no-progress] 
                     <image-spec> 
   
   Resize (expand or shrink) image.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--image <image>] [--snap <snap>] 
+  usage: rbd snap create [--pool <pool>] [--namespace <namespace>] 
+                         [--image <image>] [--snap <snap>] 
                          <snap-spec> 
   
   Create a snapshot.
   
   Positional arguments
     <snap-spec>          snapshot specification
-                         (example: [<pool-name>/]<image-name>@<snapshot-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<image-name>@<snapshot-n
+                         ame>)
   
   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 <pool>] [--image <image>] 
+  usage: rbd snap limit clear [--pool <pool>] [--namespace <namespace>] 
+                              [--image <image>] 
                               <image-spec> 
   
   Remove snapshot limit.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--image <image>] [--limit <limit>] 
+  usage: rbd snap limit set [--pool <pool>] [--namespace <namespace>] 
+                            [--image <image>] [--limit <limit>] 
                             <image-spec> 
   
   Limit the number of snapshots.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--image <image>] [--image-id <image-id>] 
+  usage: rbd snap list [--pool <pool>] [--namespace <namespace>] 
+                       [--image <image>] [--image-id <image-id>] 
                        [--format <format>] [--pretty-format] [--all] 
                        <image-spec> 
   
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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]
     -a [ --all ]         list snapshots from all namespaces
   
   rbd help snap protect
-  usage: rbd snap protect [--pool <pool>] [--image <image>] [--snap <snap>] 
+  usage: rbd snap protect [--pool <pool>] [--namespace <namespace>] 
+                          [--image <image>] [--snap <snap>] 
                           <snap-spec> 
   
   Prevent a snapshot from being deleted.
   
   Positional arguments
     <snap-spec>          snapshot specification
-                         (example: [<pool-name>/]<image-name>@<snapshot-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<image-name>@<snapshot-n
+                         ame>)
   
   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 <pool>] [--image <image>] 
-                        [--image-id <image-id>] [--no-progress] 
+  usage: rbd snap purge [--pool <pool>] [--namespace <namespace>] 
+                        [--image <image>] [--image-id <image-id>] [--no-progress] 
                         <image-spec> 
   
   Delete all unprotected snapshots.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--image <image>] [--snap <snap>] 
-                         [--no-progress] [--image-id <image-id>] [--force] 
+  usage: rbd snap remove [--pool <pool>] [--namespace <namespace>] 
+                         [--image <image>] [--snap <snap>] [--no-progress] 
+                         [--image-id <image-id>] [--force] 
                          <snap-spec> 
   
   Delete a snapshot.
   
   Positional arguments
     <snap-spec>          snapshot specification
-                         (example: [<pool-name>/]<image-name>@<snapshot-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<image-name>@<snapshot-n
+                         ame>)
   
   Optional arguments
     -p [ --pool ] arg    pool name
+    --namespace arg      namespace name
     --image arg          image name
     --snap arg           snapshot name
     --no-progress        disable progress output
     --force              flatten children and unprotect snapshot if needed.
   
   rbd help snap rename
-  usage: rbd snap rename [--pool <pool>] [--image <image>] [--snap <snap>] 
-                         [--dest-pool <dest-pool>] [--dest <dest>] 
+  usage: rbd snap rename [--pool <pool>] [--namespace <namespace>] 
+                         [--image <image>] [--snap <snap>] 
+                         [--dest-pool <dest-pool>] 
+                         [--dest-namespace <dest-namespace>] [--dest <dest>] 
                          [--dest-snap <dest-snap>] 
                          <source-snap-spec> <dest-snap-spec> 
   
   
   Positional arguments
     <source-snap-spec>   source snapshot specification
-                         (example: [<pool-name>/]<image-name>@<snapshot-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<image-name>@<snapshot-n
+                         ame>)
     <dest-snap-spec>     destination snapshot specification
-                         (example: [<pool-name>/]<image-name>@<snapshot-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<image-name>@<snapshot-n
+                         ame>)
   
   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 <pool>] [--image <image>] [--snap <snap>] 
-                           [--no-progress] 
+  usage: rbd snap rollback [--pool <pool>] [--namespace <namespace>] 
+                           [--image <image>] [--snap <snap>] [--no-progress] 
                            <snap-spec> 
   
   Rollback image to snapshot.
   
   Positional arguments
     <snap-spec>          snapshot specification
-                         (example: [<pool-name>/]<image-name>@<snapshot-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<image-name>@<snapshot-n
+                         ame>)
   
   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 <pool>] [--image <image>] [--snap <snap>] 
+  usage: rbd snap unprotect [--pool <pool>] [--namespace <namespace>] 
+                            [--image <image>] [--snap <snap>] 
                             [--image-id <image-id>] 
                             <snap-spec> 
   
   
   Positional arguments
     <snap-spec>          snapshot specification
-                         (example: [<pool-name>/]<image-name>@<snapshot-name>)
+                         (example:
+                         [<pool-name>/[<namespace-name>/]]<image-name>@<snapshot-n
+                         ame>)
   
   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 <pool>] [--image <image>] [--format <format>] 
-                    [--pretty-format] 
+  usage: rbd status [--pool <pool>] [--namespace <namespace>] [--image <image>] 
+                    [--format <format>] [--pretty-format] 
                     <image-spec> 
   
   Show the status of this image.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--all] [--long] [--format <format>
-                        [--pretty-format] 
-                        <pool-name> 
+  usage: rbd trash list [--pool <pool>] [--namespace <namespace>] [--all
+                        [--long] [--format <format>] [--pretty-format] 
+                        <pool-name> <namespace-name> 
   
   List trash images.
   
   Positional arguments
     <pool-name>          pool name
+    <namespace-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 <pool>] [--image <image>] 
-                        [--expires-at <expires-at>] 
+  usage: rbd trash move [--pool <pool>] [--namespace <namespace>] 
+                        [--image <image>] [--expires-at <expires-at>] 
                         <image-spec> 
   
   Move an image to the trash.
   
   Positional arguments
     <image-spec>            image specification
-                            (example: [<pool-name>/]<image-name>)
+                            (example:
+                            [<pool-name>/[<namespace-name>/]]<image-name>)
   
   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 <pool>] [--no-progress
-                         [--expired-before <expired-before>] 
+  usage: rbd trash purge [--pool <pool>] [--namespace <namespace>
+                         [--no-progress] [--expired-before <expired-before>] 
                          [--threshold <threshold>] 
-                         <pool-name> 
+                         <pool-name> <namespace-name> 
   
   Remove all expired images from trash.
   
   Positional arguments
     <pool-name>           pool name
+    <namespace-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 <pool>] [--image-id <image-id>] 
-                          [--no-progress] [--force] 
+  usage: rbd trash remove [--pool <pool>] [--namespace <namespace>] 
+                          [--image-id <image-id>] [--no-progress] [--force] 
                           <image-id> 
   
   Remove an image from trash.
   
   Positional arguments
     <image-id>           image id
-                         (example: [<pool-name>/]<image-id>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-id>)
   
   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 <pool>] [--image-id <image-id>] 
-                           [--image <image>] 
+  usage: rbd trash restore [--pool <pool>] [--namespace <namespace>] 
+                           [--image-id <image-id>] [--image <image>] 
                            <image-id> 
   
   Restore an image from trash.
   
   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 <pool>] [--image <image>] 
+  usage: rbd watch [--pool <pool>] [--namespace <namespace>] [--image <image>] 
                    <image-spec> 
   
   Watch events on image.
   
   Positional arguments
     <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
   
   Optional arguments
     -p [ --pool ] arg    pool name
+    --namespace arg      namespace name
     --image arg          image name
   
index 176092800e5020e1a1d1a314fb8cb961dd5e4cf0..920c3c223efabb644c565daff890b7a8b97ba48f 100644 (file)
   $ 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]
index 2fb1df8059674190add2400a8b77c271e21676f9..cc9078b83328ad7ac35850a14bf55e05deb59d9c 100644 (file)
@@ -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
   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
   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
index 1dfe6205851b18f868d3fad3a8dde2a9980069c3..ca87bfea0ef5025313aa63a7e3d95325ab8b6160 100644 (file)
@@ -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<std::string>(), 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<std::string>(), 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<std::string>(), 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<uint64_t>(), "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<std::string>(), 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: [<pool-name>/]<image-name>)").c_str());
+      "(example: [<pool-name>/[<namespace-name>/]]<image-name>)").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: [<pool-name>/]<group-name>)").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: [<pool-name>/]<group-name>@<snap-name>)").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: [<pool-name>/]<image-name>@<snapshot-name>)").c_str());
+      "(example: [<pool-name>/[<namespace-name>/]]<image-name>@<snapshot-name>)").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: [<pool-name>/]<image-name>[@<snap-name>])").c_str());
+      "(example: [<pool-name>/[<namespace-name>/]]<image-name>[@<snap-name>])").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: [<pool-name>/]<journal-name>)").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<std::string>& 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()) {
index f9e44d588893cfe85ddca6f9658763090dfd1d50..12de0341e68ea9beddaa80d76c33a3b27267ccd5 100644 (file)
@@ -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);
 
index d368d5ab11bac229ab4b91df3d96d18f494a293a..3515e28255205fbc4b0b2f039785668a2b551a41 100644 (file)
@@ -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<bool>("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<std::string>();
-  } 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<std::string>();
-  }
-
-  if (vm.count(group_key)) {
-    *group_name = vm[group_key].as<std::string>();
-  }
-
-  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<std::string>();
-  }
-
-  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<std::string>();
-  }
-
-  if (vm.count(image_key)) {
-    *image_name = vm[image_key].as<std::string>();
-  }
-
-  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<std::string>();
-  }
-
-  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<std::string>();
   }
+  if (vm.count(at::NAMESPACE_NAME) && namespace_name != nullptr) {
+    *namespace_name = vm[at::NAMESPACE_NAME].as<std::string>();
+  }
   if (vm.count(at::IMAGE_ID) && image_id != nullptr) {
     *image_id = vm[at::IMAGE_ID].as<std::string>();
   }
@@ -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<std::string>();
-  }
-  if (vm.count(group_key) && group_name != nullptr) {
-    *group_name = vm[group_key].as<std::string>();
-  }
-
-  if (vm.count(at::SNAPSHOT_NAME) && snap_name != nullptr) {
-    *snap_name = vm[at::SNAPSHOT_NAME].as<std::string>();
-  }
-
-  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<std::string>();
   }
-  if (vm.count(image_key) && image_name != nullptr) {
-    *image_name = vm[image_key].as<std::string>();
+  if (vm.count(namespace_key) && namespace_name != nullptr) {
+    *namespace_name = vm[namespace_key].as<std::string>();
+  }
+  if (vm.count(generic_key) && generic_name != nullptr) {
+    *generic_name = vm[generic_key].as<std::string>();
   }
   if (vm.count(snap_key) && snap_name != nullptr) {
-     *snap_name = vm[snap_key].as<std::string>();
+    *snap_name = vm[snap_key].as<std::string>();
   }
 
   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<std::string>();
-  }
-  if (vm.count(snap_key) && snap_name != nullptr) {
-     *snap_name = vm[snap_key].as<std::string>();
-  }
-
-  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<std::string>();
-  }
-  if (vm.count(journal_key) && journal_name != nullptr) {
-    *journal_name = vm[journal_key].as<std::string>();
-  }
-
-  std::string image_name;
-  if (vm.count(image_key)) {
-    image_name = vm[image_key].as<std::string>();
-  }
-
-  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<uint64_t>(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)
 {
index 02aa3ce91f12c683a525cb594e58b2c3fa61e981..4cf554fc42d1e47a6bcaed3f3f4e655428088402 100644 (file)
@@ -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);
 
index 0fe1950426824f5a5f1e80ad59853061cc087d14..56fe12d17e5a21c7f945230aaaf10c41aade6360 100644 (file)
@@ -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;
   }
index d2ede539427f65d50be509a53c8cb4a5b6dd9aaf..143337e32ceb031562832a14149f40769e676138 100644 (file)
@@ -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;
   }
index 1a47bf0606759fbe5b39641c68059fdfd5687359..e668590725b3af719b0d0388ef9b163554b1367f 100644 (file)
@@ -33,21 +33,25 @@ int execute(const po::variables_map &vm,
             const std::vector<std::string> &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<uint64_t>(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
index 96d63f2a31dafd4cc19f9e5df15034a090ae9bf1..9a248437109057c7cde1a4a03401ebe4a39a63af 100644 (file)
@@ -44,22 +44,25 @@ int execute(const po::variables_map &vm,
             const std::vector<std::string> &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<std::string> &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
index 028530b7026c10bd7be9a846092bb93a2bd71a15..daae502df9714d81b08e24a3108b873956de86f4 100644 (file)
@@ -199,11 +199,13 @@ int execute(const po::variables_map &vm,
             const std::vector<std::string> &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;
   }
index 212a3def4bff743a3f6f2bfcfdb4aa1b12d458b4..a215e8a0121ee73e4d92667f0e30366cccee15fb 100644 (file)
@@ -90,11 +90,12 @@ int execute(const po::variables_map &vm,
             const std::vector<std::string> &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;
   }
index 14a9a30d14ba20b0da4a7cdb9299860a25166f07..e2e6605379b7d44e71a4b0addb7ea2f9143e2f98 100644 (file)
@@ -255,12 +255,13 @@ int execute(const po::variables_map &vm,
             const std::vector<std::string> &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;
   }
index 8c109e17dea80c372ad0688a91d0e15f3f910d5a..53dfa9c6aafa5dfde2bbfda5b78f9a1a27259b27 100644 (file)
@@ -265,11 +265,12 @@ int execute_diff(const po::variables_map &vm,
                  const std::vector<std::string> &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<std::string> &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<uint64_t>();
index af23f90fbfae11bd98ba20af81241418725cb82e..13a7b6ea75ce88e13a57355070d46c68b219e3a2 100644 (file)
@@ -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;
   }
index 9f7ab18e37dae4c658bfe414ec2689c39fe4e0dc..ec4e837a871141b0c8fa91336556b3ae6cff3fbf 100644 (file)
@@ -37,11 +37,13 @@ int execute(const po::variables_map &vm,
             const std::vector<std::string> &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;
   }
index 7757785a58d92743b3e0e68551b9eaa13d12d066..611ffc7db8167ec14960b743479b718894ea1111 100644 (file)
@@ -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;
   }
index aa11feebc868f7b8fb1ba4c4af5c1504d6cf12cf..e4236c3aa517d6f95721a34ee33900ae51871b8e 100644 (file)
 
 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<std::string>(), 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<std::string>(), 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<std::string>(), 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: [<pool-name>/[<namespace-name>/]]<group-name>)").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: [<pool-name>/[<namespace-name>/]]<group-name>@<snap-name>)").c_str());
+  }
+}
+
 int execute_create(const po::variables_map &vm,
                    const std::vector<std::string> &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<std::string> &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<std::string> &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<std::string> &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<std::string> &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<std::string>();
   }
 
-  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<std::string> &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 = "<missing data pool " + stringify(image.pool) + ">";
+      pool_name = "<missing image pool " + stringify(image.pool) + ">";
     } 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<std::string> &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<std::string> &global_args) {
+int execute_group_snap_remove(const po::variables_map &vm,
+                              const std::vector<std::string> &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<std::string> &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<std::string> &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: [<pool-name>/]<group-name>)");
+     "(example: [<pool-name>/[<namespace-name>/]]<group-name>)");
 
-  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: [<pool-name>/]<image-name>)");
+     "(example: [<pool-name>/[<namespace-name>/]]<image-name>)");
 
-  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: [<pool-name>/]<group-name>)");
+     "(example: [<pool-name>/[<namespace-name>/]]<group-name>)");
 
-  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: [<pool-name>/]<image-name>)");
+     "(example: [<pool-name>/[<namespace-name>/]]<image-name>)");
 
-  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
index c057eaeb67fee39c85118a3601d349be6d519b04..f5804de7263281634505d250e7eb6b3d3cde70c3 100644 (file)
@@ -144,11 +144,13 @@ int execute_list(const po::variables_map &vm,
                  const std::vector<std::string> &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<std::string> &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<std::string> &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<std::string> &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;
   }
index e116cc0e88da7b54f7d4ed75e2b361c712567daf..6b8a29459cad8c0f2865df50bad3a5da8b34427f 100644 (file)
@@ -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;
   }
index 79440bda8d8d9b8a36ce88f58a9ee16d2242674f..db8de5778378d69c350d558293cd329acf945380 100644 (file)
@@ -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<std::string> &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<std::string>();
   }
 
-  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;
   }
index 64883f5500b40948158ca7bfb0ee0d4ca46837cc..0b27d53405a24b5e203eb86b6d90227c3546d8ad 100644 (file)
@@ -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<std::string>(), 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: [<pool-name>/[<namespace-name>/]]<journal-name>)").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<std::string>();
+  }
+  if (vm.count(namespace_key) && namespace_name != nullptr) {
+    *namespace_name = vm[namespace_key].as<std::string>();
+  }
+  if (vm.count(journal_key) && journal_name != nullptr) {
+    *journal_name = vm[journal_key].as<std::string>();
+  }
+
+  std::string image_name;
+  if (vm.count(image_key)) {
+    image_name = vm[image_key].as<std::string>();
+  }
+
+  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<std::string> &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<std::string> &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<std::string> &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<std::string>(),
      "client ID (or leave unspecified to disconnect all)");
@@ -924,9 +1071,10 @@ int execute_client_disconnect(const po::variables_map &vm,
                               const std::vector<std::string> &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<std::string> &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<std::string> &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;
   }
index 3e866e976f2af3fc03790cc6fbd973d24b256e50..7e01cf1dac8324e47bc6e364ce71913e52a50192 100644 (file)
@@ -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;
     }
index 22b7abce0046119f1f4048787752ccc0340ab16d..65380f8987a27def77ae3969554fc59ce2aa983f 100644 (file)
@@ -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<WorkerEntry*> workers;
   std::vector<std::string> 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<std::string> &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<bool>(),
+  r = do_list(pool_name, namespace_name, vm["long"].as<bool>(),
               g_conf->get_val<int64_t>("rbd_concurrent_management_ops"),
               formatter.get());
   if (r < 0) {
index 22190f89b38d17f2e51720d68ac1dced82348946..4ede9245080219536a47523c21819222c30f482e 100644 (file)
@@ -114,11 +114,13 @@ int execute_list(const po::variables_map &vm,
                  const std::vector<std::string> &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<std::string> &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<std::string> &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;
   }
index 44102635127617db1b2ad552d2bbb1b94017bbec..046760278a0eb53664d1294a2271a05e7f22a951 100644 (file)
@@ -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<bool>();
 
+  // 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;
index e4312bf6181b851a7abcffc77139d52c9f2d9511..01f1c990517f6c473580027b927304ac1a3d814f 100644 (file)
@@ -546,9 +546,10 @@ int execute_peer_add(const po::variables_map &vm,
     config_path = vm[at::CONFIG_PATH].as<std::string>();
   }
 
+  // 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<std::string>();
   }
 
+  // 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<std::string>();
   }
 
+  // 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;
   }
index 92224c08942f6dfb4aa3ebe0d66bf7af8bbd7944..c1971fa1785c97d395b55254624efdca6b0ccb56 100644 (file)
@@ -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;
   }
index 7889181ff122e1fbb748cc19b69b8cc7a746b782..dfe7a9f25fd0ed9ea14f507b4185b5fd187c296f 100644 (file)
@@ -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;
index c3fba097f0c473566d8173bb5987e5da3d5049aa..40ee2d472f2c4647e60ca94ad0fab5710d453ee8 100644 (file)
@@ -38,11 +38,12 @@ int execute_rebuild(const po::variables_map &vm,
                     const std::vector<std::string> &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<std::string> &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;
   }
index 4e2dbca77e33deadb210ea5d713406fb822fa497..52080a4ba8cc84f554466085e4509255f57444c3 100644 (file)
@@ -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;
   }
index c19696d7199203efdc8e166cd1b911be2afb681a..337d42be610e585490c10a86b7c33ecb01189891 100644 (file)
@@ -59,18 +59,20 @@ int execute(const po::variables_map &vm,
             const std::vector<std::string> &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 = "<missing data pool " + stringify(group_info.pool) + ">";
+          pool_name = "<missing group pool " + stringify(group_info.pool) + ">";
         } 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";
 
index a223a815f599078aa578554489a2634b8771d303..b4954bcbb90af1d536d28fce543521df51325f95 100644 (file)
@@ -34,11 +34,13 @@ int execute(const po::variables_map &vm,
             const std::vector<std::string> &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;
   }
index aed5fdad137527dea4bf4f48ba22319b03d597e3..361f03d953dabb59bfeeb878f6dc5d4abcc6ce51 100644 (file)
@@ -40,11 +40,13 @@ int execute(const po::variables_map &vm,
             const std::vector<std::string> &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;
   }
index d35ed5aa623419dddea7b11be7164fae3da5ae64..74a346b875756709aa871aa04240931a356ed351 100644 (file)
@@ -278,6 +278,7 @@ int execute_list(const po::variables_map &vm,
                  const std::vector<std::string> &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<std::string>();
   }
 
-  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<std::string> &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<std::string> &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<std::string>();
   }
 
-  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<std::string> &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<std::string>();
   }
 
-  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<std::string> &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<std::string> &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<std::string> &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<std::string>();
   }
 
-  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<std::string> &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<std::string> &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<std::string> &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;
   }
index 4eb623f94697ca1c271b9e368adbc6dbda30268d..43b8b9b7286aad1653afe065e431dbe1dde0000e 100644 (file)
@@ -68,11 +68,13 @@ int execute(const po::variables_map &vm,
             const std::vector<std::string> &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;
   }
index c0780416cad5818ebcfa839828b9d533942bf8bd..a96f2e584627aa75c93425e01a11210aba189460 100644 (file)
@@ -54,19 +54,21 @@ int execute_move(const po::variables_map &vm,
                  const std::vector<std::string> &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: [<pool-name>/]<image-id>)");
+    (at::IMAGE_ID.c_str(), "image id\n(example: [<pool-name>/[<namespace-name>/]]<image-id>)");
   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<std::string> &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<bool>(), 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<std::string> &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<std::string>()->value_name("date"), 
+      (EXPIRED_BEFORE.c_str(), po::value<std::string>()->value_name("date"),
        "purges images that expired before the given date");
   options->add_options()
-      (THRESHOLD.c_str(), po::value<double>(), 
+      (THRESHOLD.c_str(), po::value<double>(),
        "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<std::string> &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<librbd::trash_image_info_t> 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<std::string>(), &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<bool>());
+    utils::ProgressContext pc("Removing images",
+                              vm[at::NO_PROGRESS].as<bool>());
     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: [<pool-name>/]<image-id>)");
   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<std::string> &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;
   }
index 6957dae4151742338a861b521066a974b1adfeea..65f0f93dfc4a367fb988e16e1fcc870490f69e4f 100644 (file)
@@ -113,11 +113,13 @@ int execute(const po::variables_map &vm,
             const std::vector<std::string> &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;
   }