]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: alow to specify options for created journal 6665/head
authorMykola Golub <mgolub@mirantis.com>
Tue, 17 Nov 2015 07:56:17 +0000 (09:56 +0200)
committerMykola Golub <mgolub@mirantis.com>
Fri, 4 Dec 2015 11:18:30 +0000 (13:18 +0200)
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
qa/workunits/rbd/journal.sh
src/test/cli/rbd/help.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/Clone.cc
src/tools/rbd/action/Copy.cc
src/tools/rbd/action/Create.cc
src/tools/rbd/action/Feature.cc
src/tools/rbd/action/Import.cc

index 99c647b3ddaf4962625d634d4e7e1d26970547b4..022a882482630b900aad0b8f251b5809d57447c8 100755 (executable)
@@ -99,7 +99,126 @@ test_rbd_journal()
     rbd remove ${image}
 }
 
+
+rbd_assert_eq() {
+    local image=$1
+    local cmd=$2
+    local param=$3
+    local expected_val=$4
+
+    local val=$(rbd --format xml ${cmd} --image ${image} |
+                      $XMLSTARLET sel -t -v "${param}")
+    test "${val}" = "${expected_val}"
+}
+
+test_rbd_create()
+{
+    local image=testrbdcreate$$
+
+    rbd create --image-feature exclusive-lock --image-feature journaling \
+       --journal-pool rbd \
+       --journal-object-size 20M \
+       --journal-splay-width 6 \
+       --size 256 ${image}
+
+    rbd_assert_eq ${image} 'journal info' '//journal/order' 25
+    rbd_assert_eq ${image} 'journal info' '//journal/splay_width' 6
+    rbd_assert_eq ${image} 'journal info' '//journal/object_pool' rbd
+
+    rbd remove ${image}
+}
+
+test_rbd_copy()
+{
+    local src=testrbdcopys$$
+    rbd create --size 256 ${src}
+
+    local image=testrbdcopy$$
+    rbd copy --image-feature exclusive-lock --image-feature journaling \
+       --journal-pool rbd \
+       --journal-object-size 20M \
+       --journal-splay-width 6 \
+       ${src} ${image}
+
+    rbd remove ${src}
+
+    rbd_assert_eq ${image} 'journal info' '//journal/order' 25
+    rbd_assert_eq ${image} 'journal info' '//journal/splay_width' 6
+    rbd_assert_eq ${image} 'journal info' '//journal/object_pool' rbd
+
+    rbd remove ${image}
+}
+
+test_rbd_clone()
+{
+    local parent=testrbdclonep$$
+    rbd create --image-feature layering --size 256 ${parent}
+    rbd snap create ${parent}@snap
+    rbd snap protect ${parent}@snap
+
+    local image=testrbdclone$$
+    rbd clone --image-feature layering --image-feature exclusive-lock --image-feature journaling \
+       --journal-pool rbd \
+       --journal-object-size 20M \
+       --journal-splay-width 6 \
+       ${parent}@snap ${image}
+
+    rbd_assert_eq ${image} 'journal info' '//journal/order' 25
+    rbd_assert_eq ${image} 'journal info' '//journal/splay_width' 6
+    rbd_assert_eq ${image} 'journal info' '//journal/object_pool' rbd
+
+    rbd remove ${image}
+    rbd snap unprotect ${parent}@snap
+    rbd snap purge ${parent}
+    rbd remove ${parent}
+}
+
+test_rbd_import()
+{
+    local src=testrbdimports$$
+    rbd create --size 256 ${src}
+
+    rbd export ${src} $TMPDIR/${src}.export
+    rbd remove ${src}
+
+    local image=testrbdimport$$
+    rbd import --image-feature exclusive-lock --image-feature journaling \
+       --journal-pool rbd \
+       --journal-object-size 20M \
+       --journal-splay-width 6 \
+       $TMPDIR/${src}.export ${image}
+
+    rbd_assert_eq ${image} 'journal info' '//journal/order' 25
+    rbd_assert_eq ${image} 'journal info' '//journal/splay_width' 6
+    rbd_assert_eq ${image} 'journal info' '//journal/object_pool' rbd
+
+    rbd remove ${image}
+}
+
+test_rbd_feature()
+{
+    local image=testrbdfeature$$
+
+    rbd create --image-feature exclusive-lock --size 256 ${image}
+
+    rbd feature enable ${image} journaling \
+       --journal-pool rbd \
+       --journal-object-size 20M \
+       --journal-splay-width 6
+
+    rbd_assert_eq ${image} 'journal info' '//journal/order' 25
+    rbd_assert_eq ${image} 'journal info' '//journal/splay_width' 6
+    rbd_assert_eq ${image} 'journal info' '//journal/object_pool' rbd
+
+    rbd remove ${image}
+}
+
 TESTS+=" rbd_journal"
+TESTS+=" rbd_create"
+TESTS+=" rbd_copy"
+TESTS+=" rbd_clone"
+TESTS+=" rbd_import"
+TESTS+=" rbd_feature"
 
 #
 # "main" follows
index b459056ca7aaa574333487fb156552a03b82f3e9..8e4a36c5b5e6b994fa73954e2a041317fb5ac6da 100644 (file)
                    [--dest-pool <dest-pool>] [--dest <dest>] [--order <order>] 
                    [--image-feature <image-feature>] [--image-shared] 
                    [--stripe-unit <stripe-unit>] [--stripe-count <stripe-count>] 
+                   [--journal-splay-width <journal-splay-width>] 
+                   [--journal-object-size <journal-object-size>] 
+                   [--journal-pool <journal-pool>] 
                    <source-snap-spec> <dest-image-spec> 
   
   Clone a snapshot into a COW child image.
   
   Positional arguments
-    <source-snap-spec>   source snapshot specification
-                         (example: [<pool-name>/]<image-name>@<snapshot-name>)
-    <dest-image-spec>    destination image specification
-                         (example: [<pool-name>/]<image-name>)
+    <source-snap-spec>        source snapshot specification
+                              (example:
+                              [<pool-name>/]<image-name>@<snapshot-name>)
+    <dest-image-spec>         destination image specification
+                              (example: [<pool-name>/]<image-name>)
   
   Optional arguments
-    -p [ --pool ] arg    source pool name
-    --image arg          source image name
-    --snap arg           source snapshot name
-    --dest-pool arg      destination pool name
-    --dest arg           destination image name
-    --order arg          object order [12 <= order <= 25]
-    --image-feature arg  image features
-                         [layering(+), striping(+), exclusive-lock(*),
-                         object-map(*), fast-diff(*), deep-flatten, journaling(*)]
-    --image-shared       shared image
-    --stripe-unit arg    stripe unit
-    --stripe-count arg   stripe count
+    -p [ --pool ] arg         source pool name
+    --image arg               source image name
+    --snap arg                source snapshot name
+    --dest-pool arg           destination pool name
+    --dest arg                destination image name
+    --order arg               object order [12 <= order <= 25]
+    --image-feature arg       image features
+                              [layering(+), striping(+), exclusive-lock(*),
+                              object-map(*), fast-diff(*), deep-flatten,
+                              journaling(*)]
+    --image-shared            shared image
+    --stripe-unit arg         stripe unit
+    --stripe-count arg        stripe count
+    --journal-splay-width arg number of active journal objects
+    --journal-object-size arg size of journal objects
+    --journal-pool arg        pool for journal objects
   
   Image Features:
     (*) supports enabling/disabling on existing images
   
   rbd help copy
   usage: rbd copy [--pool <pool>] [--image <image>] [--snap <snap>] 
-                  [--dest-pool <dest-pool>] [--dest <dest>] [--no-progress] 
+                  [--dest-pool <dest-pool>] [--dest <dest>] [--order <order>] 
+                  [--image-feature <image-feature>] [--image-shared] 
+                  [--stripe-unit <stripe-unit>] [--stripe-count <stripe-count>] 
+                  [--journal-splay-width <journal-splay-width>] 
+                  [--journal-object-size <journal-object-size>] 
+                  [--journal-pool <journal-pool>] [--no-progress] 
                   <source-image-or-snap-spec> <dest-image-spec> 
   
   Copy src image to dest.
     --snap arg                   source snapshot name
     --dest-pool arg              destination pool name
     --dest arg                   destination image name
+    --order arg                  object order [12 <= order <= 25]
+    --image-feature arg          image features
+                                 [layering(+), striping(+), exclusive-lock(*),
+                                 object-map(*), fast-diff(*), deep-flatten,
+                                 journaling(*)]
+    --image-shared               shared image
+    --stripe-unit arg            stripe unit
+    --stripe-count arg           stripe count
+    --journal-splay-width arg    number of active journal objects
+    --journal-object-size arg    size of journal objects
+    --journal-pool arg           pool for journal objects
     --no-progress                disable progress output
   
+  Image Features:
+    (*) supports enabling/disabling on existing images
+    (+) enabled by default for new images if features not specified
+  
   rbd help create
   usage: rbd create [--pool <pool>] [--image <image>] 
                     [--image-format <image-format>] [--new-format] 
                     [--order <order>] [--image-feature <image-feature>] 
                     [--image-shared] [--stripe-unit <stripe-unit>] 
-                    [--stripe-count <stripe-count>] --size <size> 
+                    [--stripe-count <stripe-count>] 
+                    [--journal-splay-width <journal-splay-width>] 
+                    [--journal-object-size <journal-object-size>] 
+                    [--journal-pool <journal-pool>] --size <size> 
                     <image-spec> 
   
   Create an empty image.
   
   Positional arguments
-    <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
+    <image-spec>              image specification
+                              (example: [<pool-name>/]<image-name>)
   
   Optional arguments
-    -p [ --pool ] arg    pool name
-    --image arg          image name
-    --image-format arg   image format [1 or 2]
-    --new-format         use image format 2
-                         (deprecated)
-    --order arg          object order [12 <= order <= 25]
-    --image-feature arg  image features
-                         [layering(+), striping(+), exclusive-lock(*),
-                         object-map(*), fast-diff(*), deep-flatten, journaling(*)]
-    --image-shared       shared image
-    --stripe-unit arg    stripe unit
-    --stripe-count arg   stripe count
-    -s [ --size ] arg    image size (in M/G/T)
+    -p [ --pool ] arg         pool name
+    --image arg               image name
+    --image-format arg        image format [1 or 2]
+    --new-format              use image format 2
+                              (deprecated)
+    --order arg               object order [12 <= order <= 25]
+    --image-feature arg       image features
+                              [layering(+), striping(+), exclusive-lock(*),
+                              object-map(*), fast-diff(*), deep-flatten,
+                              journaling(*)]
+    --image-shared            shared image
+    --stripe-unit arg         stripe unit
+    --stripe-count arg        stripe count
+    --journal-splay-width arg number of active journal objects
+    --journal-object-size arg size of journal objects
+    --journal-pool arg        pool for journal objects
+    -s [ --size ] arg         image size (in M/G/T)
   
   Image Features:
     (*) supports enabling/disabling on existing images
   
   rbd help feature enable
   usage: rbd feature enable [--pool <pool>] [--image <image>] 
+                            [--journal-splay-width <journal-splay-width>] 
+                            [--journal-object-size <journal-object-size>] 
+                            [--journal-pool <journal-pool>] 
                             <image-spec> <features> [<features> ...]
   
   Enable the specified image feature.
   
   Positional arguments
-    <image-spec>         image specification
-                         (example: [<pool-name>/]<image-name>)
-    <features>           image features
-                         [layering, striping, exclusive-lock, object-map,
-                         fast-diff, deep-flatten, journaling]
+    <image-spec>              image specification
+                              (example: [<pool-name>/]<image-name>)
+    <features>                image features
+                              [layering, striping, exclusive-lock, object-map,
+                              fast-diff, deep-flatten, journaling]
   
   Optional arguments
-    -p [ --pool ] arg    pool name
-    --image arg          image name
+    -p [ --pool ] arg         pool 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] 
                     [--image-format <image-format>] [--new-format] 
                     [--order <order>] [--image-feature <image-feature>] 
                     [--image-shared] [--stripe-unit <stripe-unit>] 
-                    [--stripe-count <stripe-count>] [--no-progress] 
+                    [--stripe-count <stripe-count>] 
+                    [--journal-splay-width <journal-splay-width>] 
+                    [--journal-object-size <journal-object-size>] 
+                    [--journal-pool <journal-pool>] [--no-progress] 
                     [--pool <pool>] [--image <image>] 
                     <path-name> <dest-image-spec> 
   
   Import image from file.
   
   Positional arguments
-    <path-name>          import file (or '-' for stdin)
-    <dest-image-spec>    destination image specification
-                         (example: [<pool-name>/]<image-name>)
+    <path-name>               import file (or '-' for stdin)
+    <dest-image-spec>         destination image specification
+                              (example: [<pool-name>/]<image-name>)
   
   Optional arguments
-    --path arg           import file (or '-' for stdin)
-    --dest-pool arg      destination pool name
-    --dest arg           destination image name
-    --image-format arg   image format [1 or 2]
-    --new-format         use image format 2
-                         (deprecated)
-    --order arg          object order [12 <= order <= 25]
-    --image-feature arg  image features
-                         [layering(+), striping(+), exclusive-lock(*),
-                         object-map(*), fast-diff(*), deep-flatten, journaling(*)]
-    --image-shared       shared image
-    --stripe-unit arg    stripe unit
-    --stripe-count arg   stripe count
-    --no-progress        disable progress output
-    -p [ --pool ] arg    pool name (deprecated)
-    --image arg          image name (deprecated)
+    --path arg                import file (or '-' for stdin)
+    --dest-pool arg           destination pool name
+    --dest arg                destination image name
+    --image-format arg        image format [1 or 2]
+    --new-format              use image format 2
+                              (deprecated)
+    --order arg               object order [12 <= order <= 25]
+    --image-feature arg       image features
+                              [layering(+), striping(+), exclusive-lock(*),
+                              object-map(*), fast-diff(*), deep-flatten,
+                              journaling(*)]
+    --image-shared            shared image
+    --stripe-unit arg         stripe unit
+    --stripe-count arg        stripe count
+    --journal-splay-width arg number of active journal objects
+    --journal-object-size arg size of journal objects
+    --journal-pool arg        pool for journal objects
+    --no-progress             disable progress output
+    -p [ --pool ] arg         pool name (deprecated)
+    --image arg               image name (deprecated)
   
   Image Features:
     (*) supports enabling/disabling on existing images
index 0c3dc5597f87e8cfbfb7ad0c00be3daaa2b70061..43bb80b0acdf89807265eb02ab36923c7386d5f8 100644 (file)
@@ -223,6 +223,18 @@ void add_create_image_options(po::options_description *opt,
     (IMAGE_SHARED.c_str(), po::bool_switch(), "shared image")
     (IMAGE_STRIPE_UNIT.c_str(), po::value<uint32_t>(), "stripe unit")
     (IMAGE_STRIPE_COUNT.c_str(), po::value<uint32_t>(), "stripe count");
+
+  add_create_journal_options(opt);
+}
+
+void add_create_journal_options(po::options_description *opt) {
+  opt->add_options()
+    (JOURNAL_SPLAY_WIDTH.c_str(), po::value<uint64_t>(),
+     "number of active journal objects")
+    (JOURNAL_OBJECT_SIZE.c_str(), po::value<JournalObjectSize>(),
+     "size of journal objects")
+    (JOURNAL_POOL.c_str(), po::value<std::string>(),
+     "pool for journal objects");
 }
 
 void add_size_option(boost::program_options::options_description *opt) {
@@ -393,5 +405,19 @@ void validate(boost::any& v, const std::vector<std::string>& values,
   }
 }
 
+void validate(boost::any& v, const std::vector<std::string>& values,
+              JournalObjectSize *target_type, int) {
+  po::validators::check_first_occurrence(v);
+  const std::string &s = po::validators::get_single_string(values);
+
+  std::string parse_error;
+  uint64_t size = strict_sistrtoll(s.c_str(), &parse_error);
+  if (parse_error.empty() && (size >= (1 << 12))) {
+    v = boost::any(size);
+    return;
+  }
+  throw po::validation_error(po::validation_error::invalid_option_value);
+}
+
 } // namespace argument_types
 } // namespace rbd
index e9240f27cb9453b253bce029a72ce09e45c6d901..56ae1a1510a03bf000233e63c5185bc733ed19f2 100644 (file)
@@ -65,6 +65,10 @@ static const std::string IMAGE_SIZE("size");
 static const std::string IMAGE_STRIPE_UNIT("stripe-unit");
 static const std::string IMAGE_STRIPE_COUNT("stripe-count");
 
+static const std::string JOURNAL_OBJECT_SIZE("journal-object-size");
+static const std::string JOURNAL_SPLAY_WIDTH("journal-splay-width");
+static const std::string JOURNAL_POOL("journal-pool");
+
 static const std::string NO_PROGRESS("no-progress");
 static const std::string FORMAT("format");
 static const std::string PRETTY_FORMAT("pretty-format");
@@ -99,6 +103,8 @@ struct Format : public TypedValue<std::string> {
   Formatter create_formatter(bool pretty) const;
 };
 
+struct JournalObjectSize {};
+
 std::string get_name_prefix(ArgumentModifier modifier);
 std::string get_description_prefix(ArgumentModifier modifier);
 
@@ -141,6 +147,9 @@ void add_journal_spec_options(
 void add_create_image_options(boost::program_options::options_description *opt,
                               bool include_format);
 
+void add_create_journal_options(
+  boost::program_options::options_description *opt);
+
 void add_size_option(boost::program_options::options_description *opt);
 
 void add_path_options(boost::program_options::options_description *pos,
@@ -170,6 +179,8 @@ void validate(boost::any& v, const std::vector<std::string>& values,
               ImageFeatures *target_type, int);
 void validate(boost::any& v, const std::vector<std::string>& values,
               Format *target_type, int);
+void validate(boost::any& v, const std::vector<std::string>& values,
+              JournalObjectSize *target_type, int);
 
 std::ostream &operator<<(std::ostream &os, const ImageFeatures &features);
 
index cb71ebdf1e24c9a1445edeac593761992bc05df5..00d0e79ba1b2d9c9862352a9a0d20afe50d1a9ee 100644 (file)
@@ -316,89 +316,138 @@ int validate_snapshot_name(at::ArgumentModifier mod,
 }
 
 int get_image_options(const boost::program_options::variables_map &vm,
-                      int *order, uint32_t *format, uint64_t *features,
-                      uint32_t *stripe_unit, uint32_t *stripe_count) {
+                     bool get_format, librbd::ImageOptions *opts) {
+  uint64_t order, features, stripe_unit, stripe_count;
+  bool features_specified = false;
+
   if (vm.count(at::IMAGE_ORDER)) {
-    *order = vm[at::IMAGE_ORDER].as<uint32_t>();
+    order = vm[at::IMAGE_ORDER].as<uint64_t>();
   } else {
-    *order = 22;
+    order = 22;
   }
 
-  bool features_specified = false;
   if (vm.count(at::IMAGE_FEATURES)) {
-    *features = vm[at::IMAGE_FEATURES].as<uint64_t>();
+    features = vm[at::IMAGE_FEATURES].as<uint64_t>();
     features_specified = true;
   } else {
-    *features = g_conf->rbd_default_features;
+    features = g_conf->rbd_default_features;
   }
 
   if (vm.count(at::IMAGE_STRIPE_UNIT)) {
-    *stripe_unit = vm[at::IMAGE_STRIPE_UNIT].as<uint32_t>();
+    stripe_unit = vm[at::IMAGE_STRIPE_UNIT].as<uint64_t>();
   } else {
-    *stripe_unit = g_conf->rbd_default_stripe_unit;
+    stripe_unit = g_conf->rbd_default_stripe_unit;
   }
 
   if (vm.count(at::IMAGE_STRIPE_COUNT)) {
-    *stripe_count = vm[at::IMAGE_STRIPE_COUNT].as<uint32_t>();
+    stripe_count = vm[at::IMAGE_STRIPE_COUNT].as<uint64_t>();
   } else {
-    *stripe_count = g_conf->rbd_default_stripe_count;
+    stripe_count = g_conf->rbd_default_stripe_count;
   }
 
-  if ((*stripe_unit != 0 && *stripe_count == 0) ||
-      (*stripe_unit == 0 && *stripe_count != 0)) {
+  if ((stripe_unit != 0 && stripe_count == 0) ||
+      (stripe_unit == 0 && stripe_count != 0)) {
     std::cerr << "must specify both (or neither) of stripe-unit and stripe-count"
               << std::endl;
     return -EINVAL;
-  } else if ((*stripe_unit || *stripe_count) &&
-             (*stripe_unit != (1ll << *order) && *stripe_count != 1)) {
-    *features |= RBD_FEATURE_STRIPINGV2;
+  } else if ((stripe_unit || stripe_count) &&
+             (stripe_unit != (1ull << order) && stripe_count != 1)) {
+    features |= RBD_FEATURE_STRIPINGV2;
   } else {
-    *features &= ~RBD_FEATURE_STRIPINGV2;
+    features &= ~RBD_FEATURE_STRIPINGV2;
   }
 
   if (vm.count(at::IMAGE_SHARED) && vm[at::IMAGE_SHARED].as<bool>()) {
-    *features &= ~RBD_FEATURES_SINGLE_CLIENT;
+    features &= ~RBD_FEATURES_SINGLE_CLIENT;
   }
 
-  if (format != nullptr) {
+  if (get_format) {
+    uint64_t format;
     bool format_specified = false;
     if (vm.count(at::IMAGE_NEW_FORMAT)) {
-      *format = 2;
+      format = 2;
       format_specified = true;
     } else if (vm.count(at::IMAGE_FORMAT)) {
-      *format = vm[at::IMAGE_FORMAT].as<uint32_t>();
+      format = vm[at::IMAGE_FORMAT].as<uint32_t>();
       format_specified = true;
     } else {
-      *format = g_conf->rbd_default_format;
+      format = g_conf->rbd_default_format;
     }
 
-    if (features_specified && *features != 0) {
-      if (format_specified && *format == 1) {
+    if (features_specified && features != 0) {
+      if (format_specified && format == 1) {
         std::cerr << "rbd: features not allowed with format 1; "
                   << "use --image-format 2" << std::endl;
         return -EINVAL;
       } else {
-        *format = 2;
+        format = 2;
         format_specified = true;
       }
     }
 
-    if ((*stripe_unit || *stripe_count) &&
-        (*stripe_unit != (1ull << *order) && *stripe_count != 1)) {
-      if (format_specified && *format == 1) {
+    if ((stripe_unit || stripe_count) &&
+        (stripe_unit != (1ull << order) && stripe_count != 1)) {
+      if (format_specified && format == 1) {
         std::cerr << "rbd: non-default striping not allowed with format 1; "
                   << "use --image-format 2" << std::endl;
         return -EINVAL;
       } else {
-        *format = 2;
+        format = 2;
         format_specified = 2;
       }
     }
 
     if (format_specified) {
-      int r = g_conf->set_val("rbd_default_format", stringify(*format));
+      int r = g_conf->set_val("rbd_default_format", stringify(format));
       assert(r == 0);
     }
+
+    opts->set(RBD_IMAGE_OPTION_FORMAT, format);
+  }
+
+  opts->set(RBD_IMAGE_OPTION_ORDER, order);
+  opts->set(RBD_IMAGE_OPTION_FEATURES, features);
+  opts->set(RBD_IMAGE_OPTION_STRIPE_UNIT, stripe_unit);
+  opts->set(RBD_IMAGE_OPTION_STRIPE_COUNT, stripe_count);
+
+  int r = get_journal_options(vm, opts);
+  if (r < 0) {
+    return r;
+  }
+
+  return 0;
+}
+
+int get_journal_options(const boost::program_options::variables_map &vm,
+                       librbd::ImageOptions *opts) {
+
+  if (vm.count(at::JOURNAL_OBJECT_SIZE)) {
+    uint64_t size = vm[at::JOURNAL_OBJECT_SIZE].as<uint64_t>();
+    uint64_t order = 12;
+    while ((1ULL << order) < size) {
+      order++;
+    }
+    opts->set(RBD_IMAGE_OPTION_JOURNAL_ORDER, order);
+
+    int r = g_conf->set_val("rbd_journal_order", stringify(order));
+    assert(r == 0);
+  }
+  if (vm.count(at::JOURNAL_SPLAY_WIDTH)) {
+    opts->set(RBD_IMAGE_OPTION_JOURNAL_SPLAY_WIDTH,
+             vm[at::JOURNAL_SPLAY_WIDTH].as<uint64_t>());
+
+    int r = g_conf->set_val("rbd_journal_splay_width",
+                           stringify(
+                             vm[at::JOURNAL_SPLAY_WIDTH].as<uint64_t>()));
+    assert(r == 0);
+  }
+  if (vm.count(at::JOURNAL_POOL)) {
+    opts->set(RBD_IMAGE_OPTION_JOURNAL_POOL,
+             vm[at::JOURNAL_POOL].as<std::string>());
+
+    int r = g_conf->set_val("rbd_journal_pool",
+                           vm[at::JOURNAL_POOL].as<std::string>());
+    assert(r == 0);
   }
 
   return 0;
index 1e4ef6c001e38486de657ce5106ddd120a93b5b8..0f290df237db1716bcc22fb0576ab02caea30209 100644 (file)
@@ -65,8 +65,10 @@ int validate_snapshot_name(argument_types::ArgumentModifier mod,
                            SnapshotPresence snapshot_presence);
 
 int get_image_options(const boost::program_options::variables_map &vm,
-                      int *order, uint32_t *format, uint64_t *features,
-                      uint32_t *stripe_unit, uint32_t *stripe_count);
+                      bool get_format, librbd::ImageOptions* opts);
+
+int get_journal_options(const boost::program_options::variables_map &vm,
+                       librbd::ImageOptions *opts);
 
 int get_image_size(const boost::program_options::variables_map &vm,
                    uint64_t *size);
index 6c98433d7430a42edfb727a48ad9f06323a5191a..df24349befc038d4b5daa333fe461ec3546e26fe 100644 (file)
@@ -18,14 +18,16 @@ namespace po = boost::program_options;
 int do_clone(librbd::RBD &rbd, librados::IoCtx &p_ioctx,
              const char *p_name, const char *p_snapname,
              librados::IoCtx &c_ioctx, const char *c_name,
-             uint64_t features, int *c_order,
-             uint64_t stripe_unit, uint64_t stripe_count) {
+             librbd::ImageOptions& opts) {
+  uint64_t features;
+  int r = opts.get(RBD_IMAGE_OPTION_FEATURES, &features);
+  assert(r == 0);
+
   if ((features & RBD_FEATURE_LAYERING) != RBD_FEATURE_LAYERING) {
     return -EINVAL;
   }
 
-  return rbd.clone2(p_ioctx, p_name, p_snapname, c_ioctx, c_name, features,
-                    c_order, stripe_unit, stripe_count);
+  return rbd.clone3(p_ioctx, p_name, p_snapname, c_ioctx, c_name, opts);
 }
 
 void get_arguments(po::options_description *positional,
@@ -57,12 +59,8 @@ int execute(const po::variables_map &vm) {
     return r;
   }
 
-  int order;
-  uint64_t features;
-  uint32_t stripe_unit;
-  uint32_t stripe_count;
-  r = utils::get_image_options(vm, &order, nullptr, &features, &stripe_unit,
-                               &stripe_count);
+  librbd::ImageOptions opts;
+  r = utils::get_image_options(vm, false, &opts);
   if (r < 0) {
     return r;
   }
@@ -82,8 +80,7 @@ int execute(const po::variables_map &vm) {
 
   librbd::RBD rbd;
   r = do_clone(rbd, io_ctx, image_name.c_str(), snap_name.c_str(), dst_io_ctx,
-               dst_image_name.c_str(), features, &order, stripe_unit,
-               stripe_count);
+               dst_image_name.c_str(), opts);
   if (r < 0) {
     std::cerr << "rbd: clone error: " << cpp_strerror(r) << std::endl;
     return r;
index 9275e4b33f1e1bf9314e3a801e0faf6d49b07c65..7ab53aeb621298ba0ca2204dab74f7057921ffda 100644 (file)
@@ -16,10 +16,11 @@ namespace at = argument_types;
 namespace po = boost::program_options;
 
 static int do_copy(librbd::Image &src, librados::IoCtx& dest_pp,
-                   const char *destname, bool no_progress)
+                  const char *destname, librbd::ImageOptions& opts,
+                  bool no_progress)
 {
   utils::ProgressContext pc("Image copy", no_progress);
-  int r = src.copy_with_progress(dest_pp, destname, pc);
+  int r = src.copy_with_progress3(dest_pp, destname, opts, pc);
   if (r < 0){
     pc.fail();
     return r;
@@ -33,6 +34,7 @@ void get_arguments(po::options_description *positional,
   at::add_image_or_snap_spec_options(positional, options,
                                      at::ARGUMENT_MODIFIER_SOURCE);
   at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_DEST);
+  at::add_create_image_options(options, false);
   at::add_no_progress_option(options);
 }
 
@@ -58,6 +60,12 @@ int execute(const po::variables_map &vm) {
     return r;
   }
 
+  librbd::ImageOptions opts;
+  r = utils::get_image_options(vm, false, &opts);
+  if (r < 0) {
+    return r;
+  }
+
   librados::Rados rados;
   librados::IoCtx io_ctx;
   librbd::Image image;
@@ -73,7 +81,7 @@ int execute(const po::variables_map &vm) {
     return r;
   }
 
-  r = do_copy(image, dst_io_ctx, dst_image_name.c_str(),
+  r = do_copy(image, dst_io_ctx, dst_image_name.c_str(), opts,
               vm[at::NO_PROGRESS].as<bool>());
   if (r < 0) {
     std::cerr << "rbd: copy failed: " << cpp_strerror(r) << std::endl;
@@ -83,7 +91,8 @@ int execute(const po::variables_map &vm) {
 }
 
 Shell::Action action(
-  {"copy"}, {"cp"}, "Copy src image to dest.", "", &get_arguments, &execute);
+  {"copy"}, {"cp"}, "Copy src image to dest.", at::get_long_features_help(),
+  &get_arguments, &execute);
 
 } // namespace copy
 } // namespace action
index 49eedb6cc2a0db024b1a13a317c05cc8c751bfb3..58919392e365ae7c1f84552f9a3f9b33dd4c3979 100644 (file)
@@ -16,15 +16,20 @@ namespace at = argument_types;
 namespace po = boost::program_options;
 
 static int do_create(librbd::RBD &rbd, librados::IoCtx& io_ctx,
-                     const char *imgname, uint64_t size, int *order,
-                     int format, uint64_t features,
-                     uint64_t stripe_unit, uint64_t stripe_count) {
+                     const char *imgname, uint64_t size,
+                    librbd::ImageOptions& opts) {
   int r;
+  uint64_t format;
+  r = opts.get(RBD_IMAGE_OPTION_FORMAT, &format);
+  assert(r == 0);
   if (format == 1) {
-    r = rbd.create(io_ctx, imgname, size, order);
+    uint64_t order;
+    r = opts.get(RBD_IMAGE_OPTION_ORDER, &order);
+    assert(r == 0);
+    int order_ = order;
+    r = rbd.create(io_ctx, imgname, size, &order_);
   } else {
-    r = rbd.create3(io_ctx, imgname, size, features, order,
-                    stripe_unit, stripe_count);
+    r = rbd.create4(io_ctx, imgname, size, opts);
   }
   if (r < 0) {
     return r;
@@ -51,13 +56,8 @@ int execute(const po::variables_map &vm) {
     return r;
   }
 
-  int order;
-  uint32_t format;
-  uint64_t features;
-  uint32_t stripe_unit;
-  uint32_t stripe_count;
-  r = utils::get_image_options(vm, &order, &format, &features, &stripe_unit,
-                               &stripe_count);
+  librbd::ImageOptions opts;
+  r = utils::get_image_options(vm, true, &opts);
   if (r < 0) {
     return r;
   }
@@ -76,8 +76,7 @@ int execute(const po::variables_map &vm) {
   }
 
   librbd::RBD rbd;
-  r = do_create(rbd, io_ctx, image_name.c_str(), size, &order, format, features,
-                stripe_unit, stripe_count);
+  r = do_create(rbd, io_ctx, image_name.c_str(), size, opts);
   if (r < 0) {
     std::cerr << "rbd: create error: " << cpp_strerror(r) << std::endl;
     return r;
index 4bd61a6aa9a8146cb5da82dd86a5ab13f70d3d57..12d4dd8cf8cb3b6f8c214f45d323b7c3b12101b8 100644 (file)
@@ -4,8 +4,10 @@
 #include "tools/rbd/ArgumentTypes.h"
 #include "tools/rbd/Shell.h"
 #include "tools/rbd/Utils.h"
+#include "include/stringify.h"
 #include "common/errno.h"
 #include <iostream>
+#include <map>
 #include <boost/program_options.hpp>
 
 namespace rbd {
@@ -16,11 +18,24 @@ namespace at = argument_types;
 namespace po = boost::program_options;
 
 void get_arguments(po::options_description *positional,
-                   po::options_description *options) {
+                   po::options_description *options, bool enabled) {
   at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
   positional->add_options()
     ("features", po::value<at::ImageFeatures>()->multitoken(),
      ("image features\n" + at::get_short_features_help(false)).c_str());
+  if (enabled) {
+    at::add_create_journal_options(options);
+  }
+}
+
+void get_arguments_disable(po::options_description *positional,
+                          po::options_description *options) {
+  get_arguments(positional, options, false);
+}
+
+void get_arguments_enable(po::options_description *positional,
+                         po::options_description *options) {
+  get_arguments(positional, options, true);
 }
 
 int execute(const po::variables_map &vm, bool enabled) {
@@ -35,6 +50,12 @@ int execute(const po::variables_map &vm, bool enabled) {
     return r;
   }
 
+  librbd::ImageOptions opts;
+  r = utils::get_journal_options(vm, &opts);
+  if (r < 0) {
+    return r;
+  }
+
   const std::vector<std::string> &args = vm[at::POSITIONAL_ARGUMENTS]
     .as<std::vector<std::string> >();
   std::vector<std::string> feature_names(args.begin() + 1, args.end());
@@ -76,10 +97,10 @@ int execute_enable(const po::variables_map &vm) {
 
 Shell::Action action_disable(
   {"feature", "disable"}, {}, "Disable the specified image feature.", "",
-  &get_arguments, &execute_disable);
+  &get_arguments_disable, &execute_disable);
 Shell::Action action_enable(
   {"feature", "enable"}, {}, "Enable the specified image feature.", "",
-  &get_arguments, &execute_enable);
+  &get_arguments_enable, &execute_enable);
 
 } // namespace feature
 } // namespace action
index bb7cb7d86711fb781b5971678209a35b856f84c5..e7bf4d16c828ece5ee7e899333cc3a65e294d639 100644 (file)
@@ -64,10 +64,8 @@ private:
 };
 
 static int do_import(librbd::RBD &rbd, librados::IoCtx& io_ctx,
-                     const char *imgname, int *order, const char *path,
-                     int format, uint64_t features,
-                     uint64_t stripe_unit, uint64_t stripe_count,
-                     bool no_progress)
+                     const char *imgname, const char *path,
+                    librbd::ImageOptions& opts, bool no_progress)
 {
   int fd, r;
   struct stat stat_buf;
@@ -75,13 +73,13 @@ static int do_import(librbd::RBD &rbd, librados::IoCtx& io_ctx,
 
   assert(imgname);
 
-  // default order as usual
-  if (*order == 0)
-    *order = 22;
+  uint64_t order;
+  r = opts.get(RBD_IMAGE_OPTION_ORDER, &order);
+  assert(r == 0);
 
   // try to fill whole imgblklen blocks for sparsification
   uint64_t image_pos = 0;
-  size_t imgblklen = 1 << *order;
+  size_t imgblklen = 1 << order;
   char *p = new char[imgblklen];
   size_t reqlen = imgblklen;    // amount requested from read
   ssize_t readlen;              // amount received from one read
@@ -94,7 +92,7 @@ static int do_import(librbd::RBD &rbd, librados::IoCtx& io_ctx,
   if (from_stdin) {
     throttle.reset(new SimpleThrottle(1, false));
     fd = 0;
-    size = 1ULL << *order;
+    size = 1ULL << order;
   } else {
     throttle.reset(new SimpleThrottle(
       max(g_conf->rbd_concurrent_management_ops, 1), false));
@@ -132,18 +130,27 @@ static int do_import(librbd::RBD &rbd, librados::IoCtx& io_ctx,
     posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
   }
 
+  uint64_t format;
+  r = opts.get(RBD_IMAGE_OPTION_FORMAT, &format);
+  assert(r == 0);
   if (format == 1) {
+    uint64_t stripe_unit, stripe_count;
+    r = opts.get(RBD_IMAGE_OPTION_STRIPE_UNIT, &stripe_unit);
+    assert(r == 0);
+    r = opts.get(RBD_IMAGE_OPTION_STRIPE_COUNT, &stripe_count);
+    assert(r == 0);
+
     // weird striping not allowed with format 1!
     if ((stripe_unit || stripe_count) &&
-        (stripe_unit != (1ull << *order) && stripe_count != 1)) {
+        (stripe_unit != (1ull << order) && stripe_count != 1)) {
       std::cerr << "non-default striping not allowed with format 1; "
                 << "use --image-format 2" << std::endl;
       return -EINVAL;
     }
-    r = rbd.create(io_ctx, imgname, size, order);
+    int order_ = order;
+    r = rbd.create(io_ctx, imgname, size, &order_);
   } else {
-    r = rbd.create3(io_ctx, imgname, size, features, order,
-                    stripe_unit, stripe_count);
+    r = rbd.create4(io_ctx, imgname, size, opts);
   }
   if (r < 0) {
     std::cerr << "rbd: image creation failed" << std::endl;
@@ -280,13 +287,8 @@ int execute(const po::variables_map &vm) {
     image_name = deprecated_image_name;
   }
 
-  int order;
-  uint32_t format;
-  uint64_t features;
-  uint32_t stripe_unit;
-  uint32_t stripe_count;
-  r = utils::get_image_options(vm, &order, &format, &features, &stripe_unit,
-                               &stripe_count);
+  librbd::ImageOptions opts;
+  r = utils::get_image_options(vm, true, &opts);
   if (r < 0) {
     return r;
   }
@@ -299,9 +301,8 @@ int execute(const po::variables_map &vm) {
   }
 
   librbd::RBD rbd;
-  r = do_import(rbd, io_ctx, image_name.c_str(), &order, path.c_str(),
-                format, features, stripe_unit, stripe_count,
-                vm[at::NO_PROGRESS].as<bool>());
+  r = do_import(rbd, io_ctx, image_name.c_str(), path.c_str(),
+                opts, vm[at::NO_PROGRESS].as<bool>());
   if (r < 0) {
     std::cerr << "rbd: import failed: " << cpp_strerror(r) << std::endl;
     return r;