diff --git a/doc/man/8/rbd.rst b/doc/man/8/rbd.rst index f2d0d92a3a6..a3471ffc10c 100644 --- a/doc/man/8/rbd.rst +++ b/doc/man/8/rbd.rst @@ -227,9 +227,9 @@ Commands :command:`export` [--export-format *format (1 or 2)*] (*image-spec* | *snap-spec*) [*dest-path*] Exports image to dest path (use - for stdout). The --export-format accepts '1' or '2' currently. Format 2 allow us to export not only the content - of image, but also the snapshots and other priorities, such as image_order, features. + of image, but also the snapshots and other properties, such as image_order, features. -:command:`import` [--import-format *format (1 or 2)*] [--image-format *format-id*] [--object-size *size-in-B/K/M*] [--stripe-unit *size-in-B/K/M* --stripe-count *num*] [--image-feature *feature-name*]... [--image-shared] *src-path* [*image-spec*] +:command:`import` [--export-format *format (1 or 2)*] [--image-format *format-id*] [--object-size *size-in-B/K/M*] [--stripe-unit *size-in-B/K/M* --stripe-count *num*] [--image-feature *feature-name*]... [--image-shared] *src-path* [*image-spec*] Creates a new image and imports its data from path (use - for stdin). The import operation will try to create sparse rbd images if possible. For import from stdin, the sparsification unit is @@ -238,8 +238,8 @@ Commands The --stripe-unit and --stripe-count arguments are optional, but must be used together. - The --import-format accepts '1' or '2' currently. Format 2 allow us to import not only the content - of image, but also the snapshots and other priorities, such as image_order, features. + The --export-format accepts '1' or '2' currently. Format 2 allow us to import not only the content + of image, but also the snapshots and other properties, such as image_order, features. :command:`export-diff` [--from-snap *snap-name*] [--whole-object] (*image-spec* | *snap-spec*) *dest-path* Exports an incremental diff for an image to dest path (use - for stdout). If diff --git a/src/tools/rbd/ArgumentTypes.cc b/src/tools/rbd/ArgumentTypes.cc index eff0726e5cc..0bb92f98453 100644 --- a/src/tools/rbd/ArgumentTypes.cc +++ b/src/tools/rbd/ArgumentTypes.cc @@ -331,6 +331,11 @@ void add_no_error_option(boost::program_options::options_description *opt) { (NO_ERROR.c_str(), po::bool_switch(), "continue after error"); } +void add_export_format_option(boost::program_options::options_description *opt) { + opt->add_options() + ("export-format", po::value(), "format of image file"); +} + std::string get_short_features_help(bool append_suffix) { std::ostringstream oss; bool first_feature = true; @@ -492,5 +497,19 @@ void validate(boost::any& v, const std::vector& values, throw po::validation_error(po::validation_error::invalid_option_value); } +void validate(boost::any& v, const std::vector& values, + ExportFormat *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 format = strict_sistrtoll(s.c_str(), &parse_error); + if (!parse_error.empty() || (format != 1 && format != 2)) { + throw po::validation_error(po::validation_error::invalid_option_value); + } + + v = boost::any(format); +} + } // namespace argument_types } // namespace rbd diff --git a/src/tools/rbd/ArgumentTypes.h b/src/tools/rbd/ArgumentTypes.h index 325b0418b65..c18ceb2ddb4 100644 --- a/src/tools/rbd/ArgumentTypes.h +++ b/src/tools/rbd/ArgumentTypes.h @@ -114,6 +114,13 @@ struct Format : public TypedValue { struct JournalObjectSize {}; +struct ExportFormat {}; + +void validate(boost::any& v, const std::vector& values, + ExportFormat *target_type, int); + +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); diff --git a/src/tools/rbd/action/Export.cc b/src/tools/rbd/action/Export.cc index 7fada5442ca..b7fa6a44d21 100644 --- a/src/tools/rbd/action/Export.cc +++ b/src/tools/rbd/action/Export.cc @@ -358,12 +358,6 @@ private: static int do_export(librbd::Image& image, const char *path, bool no_progress, int export_format) { - // check current supported formats. - if (export_format != 1 && export_format != 2) { - std::cerr << "rbd: wrong file format to import" << std::endl; - return -EINVAL; - } - librbd::image_info_t info; int64_t r = image.stat(info, sizeof(info)); if (r < 0) @@ -520,8 +514,7 @@ void get_arguments(po::options_description *positional, at::add_path_options(positional, options, "export file (or '-' for stdout)"); at::add_no_progress_option(options); - options->add_options() - ("export-format", po::value(), "format to export image"); + at::add_export_format_option(options); } int execute(const po::variables_map &vm) { diff --git a/src/tools/rbd/action/Import.cc b/src/tools/rbd/action/Import.cc index 453bf5e35de..342f43e14c1 100644 --- a/src/tools/rbd/action/Import.cc +++ b/src/tools/rbd/action/Import.cc @@ -294,12 +294,6 @@ static int do_import(librbd::RBD &rbd, librados::IoCtx& io_ctx, librbd::ImageOptions& opts, bool no_progress, int import_format) { - // check current supported formats. - if (import_format != 1 && import_format != 2) { - std::cerr << "rbd: wrong file format to import" << std::endl; - return -EINVAL; - } - int fd, r; struct stat stat_buf; utils::ProgressContext pc("Importing image", no_progress); @@ -569,8 +563,7 @@ void get_arguments(po::options_description *positional, at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_DEST); at::add_create_image_options(options, true); at::add_no_progress_option(options); - options->add_options() - ("import-format", po::value(), "format of the file to be imported"); + at::add_export_format_option(options); // TODO legacy rbd allowed import to accept both 'image'/'dest' and // 'pool'/'dest-pool'