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
[--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
(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) {
}
}
+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
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");
Formatter create_formatter(bool pretty) const;
};
+struct JournalObjectSize {};
+
std::string get_name_prefix(ArgumentModifier modifier);
std::string get_description_prefix(ArgumentModifier modifier);
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,
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);
}
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;
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);
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,
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;
}
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;
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;
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);
}
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;
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;
}
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
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;
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;
}
}
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;
#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 {
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) {
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());
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
};
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;
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
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));
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;
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;
}
}
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;