From cad8952bed1d080d1e66fb52525da600d3c440db Mon Sep 17 00:00:00 2001 From: Ricardo Dias Date: Mon, 10 Apr 2017 14:32:46 +0100 Subject: [PATCH] rbd: Added image-id optional to Snap commands Signed-off-by: Ricardo Dias --- src/test/cli/rbd/help.t | 14 +++- src/tools/rbd/Utils.cc | 53 +++++++++++- src/tools/rbd/Utils.h | 10 +++ src/tools/rbd/action/Snap.cc | 152 ++++++++++++++++++++++++++++++----- 4 files changed, 206 insertions(+), 23 deletions(-) diff --git a/src/test/cli/rbd/help.t b/src/test/cli/rbd/help.t index 7cc9348cf1d1a..0eb9fa935f79d 100644 --- a/src/test/cli/rbd/help.t +++ b/src/test/cli/rbd/help.t @@ -1296,8 +1296,8 @@ --limit arg maximum allowed snapshot count rbd help snap list - usage: rbd snap list [--pool ] [--image ] [--format ] - [--pretty-format] + usage: rbd snap list [--pool ] [--image ] [--image-id ] + [--format ] [--pretty-format] Dump list of image snapshots. @@ -1309,6 +1309,7 @@ Optional arguments -p [ --pool ] arg pool name --image arg image name + --image-id arg image id --format arg output format [plain, json, or xml] --pretty-format pretty formatting (json and xml) @@ -1328,7 +1329,8 @@ --snap arg snapshot name rbd help snap purge - usage: rbd snap purge [--pool ] [--image ] [--no-progress] + usage: rbd snap purge [--pool ] [--image ] + [--image-id ] [--no-progress] Deletes all snapshots. @@ -1340,11 +1342,12 @@ Optional arguments -p [ --pool ] arg pool name --image arg image name + --image-id arg image id --no-progress disable progress output rbd help snap remove usage: rbd snap remove [--pool ] [--image ] [--snap ] - [--no-progress] [--force] + [--no-progress] [--image-id ] [--force] Deletes a snapshot. @@ -1358,6 +1361,7 @@ --image arg image name --snap arg snapshot name --no-progress disable progress output + --image-id arg image id --force flatten children and unprotect snapshot if needed. rbd help snap rename @@ -1401,6 +1405,7 @@ rbd help snap unprotect usage: rbd snap unprotect [--pool ] [--image ] [--snap ] + [--image-id ] Allow a snapshot to be deleted. @@ -1413,6 +1418,7 @@ -p [ --pool ] arg pool name --image arg image name --snap arg snapshot name + --image-id arg image id rbd help status usage: rbd status [--pool ] [--image ] [--format ] diff --git a/src/tools/rbd/Utils.cc b/src/tools/rbd/Utils.cc index 7e122485c2f7d..4dd4819c8ef83 100644 --- a/src/tools/rbd/Utils.cc +++ b/src/tools/rbd/Utils.cc @@ -400,7 +400,7 @@ int get_pool_image_snapshot_names(const po::variables_map &vm, } if (vm.count(snap_key) && snap_name != nullptr) { *snap_name = vm[snap_key].as(); - } + } int r; if (image_name != nullptr && !image_name->empty()) { @@ -456,6 +456,39 @@ int get_pool_image_snapshot_names(const po::variables_map &vm, return 0; } +int get_pool_snapshot_names(const po::variables_map &vm, + at::ArgumentModifier mod, + size_t *spec_arg_index, + std::string *pool_name, + std::string *snap_name, + SnapshotPresence snapshot_presence, + SpecValidation spec_validation) { + std::string pool_key = (mod == at::ARGUMENT_MODIFIER_DEST ? + at::DEST_POOL_NAME : at::POOL_NAME); + std::string snap_key = (mod == at::ARGUMENT_MODIFIER_DEST ? + at::DEST_SNAPSHOT_NAME : at::SNAPSHOT_NAME); + + if (vm.count(pool_key) && pool_name != nullptr) { + *pool_name = vm[pool_key].as(); + } + if (vm.count(snap_key) && snap_name != nullptr) { + *snap_name = vm[snap_key].as(); + } + + if (pool_name != nullptr && pool_name->empty()) { + *pool_name = at::DEFAULT_POOL_NAME; + } + + 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, @@ -859,6 +892,24 @@ int open_image(librados::IoCtx &io_ctx, const std::string &image_name, return 0; } +int open_image_by_id(librados::IoCtx &io_ctx, const std::string &image_id, + bool read_only, librbd::Image *image) { + int r; + librbd::RBD rbd; + if (read_only) { + r = rbd.open_by_id_read_only(io_ctx, *image, image_id.c_str(), NULL); + } else { + r = rbd.open_by_id(io_ctx, *image, image_id.c_str()); + } + + if (r < 0) { + std::cerr << "rbd: error opening image with id " << image_id << ": " + << cpp_strerror(r) << std::endl; + return r; + } + return 0; +} + int init_and_open_image(const std::string &pool_name, const std::string &image_name, const std::string &image_id, diff --git a/src/tools/rbd/Utils.h b/src/tools/rbd/Utils.h index e8e8c946cf1b3..c2b7f8c54b67a 100644 --- a/src/tools/rbd/Utils.h +++ b/src/tools/rbd/Utils.h @@ -112,6 +112,13 @@ int get_pool_image_snapshot_names( 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, @@ -168,6 +175,9 @@ int init_io_ctx(librados::Rados &rados, const std::string &pool_name, int open_image(librados::IoCtx &io_ctx, const std::string &image_name, bool read_only, librbd::Image *image); +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 &image_name, const std::string &image_id, diff --git a/src/tools/rbd/action/Snap.cc b/src/tools/rbd/action/Snap.cc index 17c7c180db2b8..6324e8023914c 100644 --- a/src/tools/rbd/action/Snap.cc +++ b/src/tools/rbd/action/Snap.cc @@ -180,6 +180,7 @@ int do_clear_limit(librbd::Image& image) void get_list_arguments(po::options_description *positional, po::options_description *options) { at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); + at::add_image_id_option(options); at::add_format_options(options); } @@ -188,9 +189,34 @@ int execute_list(const po::variables_map &vm) { std::string pool_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); + std::string image_id; + + if (vm.count(at::IMAGE_ID)) { + image_id = vm[at::IMAGE_ID].as(); + } + + bool has_image_spec = utils::check_if_image_spec_present( + vm, at::ARGUMENT_MODIFIER_NONE, arg_index); + + if (!image_id.empty() && has_image_spec) { + 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; } @@ -204,7 +230,7 @@ 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, + r = utils::init_and_open_image(pool_name, image_name, image_id, "", true, &rados, &io_ctx, &image); if (r < 0) { return r; @@ -258,7 +284,8 @@ void get_remove_arguments(po::options_description *positional, po::options_description *options) { at::add_snap_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); at::add_no_progress_option(options); - + at::add_image_id_option(options); + options->add_options() ("force", po::bool_switch(), "flatten children and unprotect snapshot if needed."); } @@ -268,10 +295,35 @@ int execute_remove(const po::variables_map &vm) { std::string pool_name; std::string image_name; std::string snap_name; + std::string image_id; bool force = vm["force"].as(); - 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); + + if (vm.count(at::IMAGE_ID)) { + image_id = vm[at::IMAGE_ID].as(); + } + + bool has_image_spec = utils::check_if_image_spec_present( + vm, at::ARGUMENT_MODIFIER_NONE, arg_index); + + if (!image_id.empty() && has_image_spec) { + 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; } @@ -285,7 +337,11 @@ int execute_remove(const po::variables_map &vm) { } io_ctx.set_osdmap_full_try(); - r = utils::open_image(io_ctx, image_name, false, &image); + if (image_id.empty()) { + r = utils::open_image(io_ctx, image_name, false, &image); + } else { + r = utils::open_image_by_id(io_ctx, image_id, false, &image); + } if (r < 0) { return r; } @@ -307,6 +363,7 @@ int execute_remove(const po::variables_map &vm) { void get_purge_arguments(po::options_description *positional, po::options_description *options) { at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); + at::add_image_id_option(options); at::add_no_progress_option(options); } @@ -315,9 +372,34 @@ int execute_purge(const po::variables_map &vm) { std::string pool_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); + std::string image_id; + + if (vm.count(at::IMAGE_ID)) { + image_id = vm[at::IMAGE_ID].as(); + } + + bool has_image_spec = utils::check_if_image_spec_present( + vm, at::ARGUMENT_MODIFIER_NONE, arg_index); + + if (!image_id.empty() && has_image_spec) { + 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; } @@ -331,7 +413,11 @@ int execute_purge(const po::variables_map &vm) { } io_ctx.set_osdmap_full_try(); - r = utils::open_image(io_ctx, image_name, false, &image); + if (image_id.empty()) { + r = utils::open_image(io_ctx, image_name, false, &image); + } else { + r = utils::open_image_by_id(io_ctx, image_id, false, &image); + } if (r < 0) { return r; } @@ -432,6 +518,7 @@ int execute_protect(const po::variables_map &vm) { void get_unprotect_arguments(po::options_description *positional, po::options_description *options) { at::add_snap_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); + at::add_image_id_option(options); } int execute_unprotect(const po::variables_map &vm) { @@ -439,9 +526,34 @@ int execute_unprotect(const po::variables_map &vm) { std::string pool_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); + std::string image_id; + + if (vm.count(at::IMAGE_ID)) { + image_id = vm[at::IMAGE_ID].as(); + } + + bool has_image_spec = utils::check_if_image_spec_present( + vm, at::ARGUMENT_MODIFIER_NONE, arg_index); + + if (!image_id.empty() && has_image_spec) { + 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; } @@ -455,11 +567,15 @@ int execute_unprotect(const po::variables_map &vm) { } io_ctx.set_osdmap_full_try(); - r = utils::open_image(io_ctx, image_name, false, &image); + if (image_id.empty()) { + r = utils::open_image(io_ctx, image_name, false, &image); + } else { + r = utils::open_image_by_id(io_ctx, image_id, false, &image); + } if (r < 0) { return r; } - + bool is_protected = false; r = image.snap_is_protected(snap_name.c_str(), &is_protected); if (r < 0) { -- 2.39.5