From be2cdc0bcf7a395d7ccf53c4c87aa7097deaa8f8 Mon Sep 17 00:00:00 2001 From: Mykola Golub Date: Tue, 29 Jan 2019 11:44:54 +0000 Subject: [PATCH] rbd: online re-sparsify of images Signed-off-by: Mykola Golub --- doc/man/8/rbd.rst | 6 +++ qa/workunits/rbd/cli_generic.sh | 3 ++ src/test/cli/rbd/help.t | 20 ++++++++ src/tools/rbd/CMakeLists.txt | 1 + src/tools/rbd/action/Sparsify.cc | 82 ++++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+) create mode 100644 src/tools/rbd/action/Sparsify.cc diff --git a/doc/man/8/rbd.rst b/doc/man/8/rbd.rst index 928dda028e5..22f78ad63d5 100644 --- a/doc/man/8/rbd.rst +++ b/doc/man/8/rbd.rst @@ -607,6 +607,12 @@ Commands This requires image format 2. +:command:`sparsify` [--sparse-size *sparse-size*] *image-spec* + Reclaim space for zeroed image extents. The default sparse size is + 4096 bytes and can be changed via --sparse-size option with the + following restrictions: it should be power of two, not less than + 4096, and not larger image object size. + :command:`status` *image-spec* Show the status of the image, including which clients have it open. diff --git a/qa/workunits/rbd/cli_generic.sh b/qa/workunits/rbd/cli_generic.sh index 8f2a25a8e95..97d64577fad 100755 --- a/qa/workunits/rbd/cli_generic.sh +++ b/qa/workunits/rbd/cli_generic.sh @@ -125,6 +125,9 @@ test_others() { rbd info --snap=snap1 testimg1 2>&1 | grep 'error setting snapshot context: (2) No such file or directory' rbd info --snap=snap1 testimg-diff1 2>&1 | grep 'error setting snapshot context: (2) No such file or directory' + # sparsify + rbd sparsify testimg1 + remove_images rm -f $TMP_FILES } diff --git a/src/test/cli/rbd/help.t b/src/test/cli/rbd/help.t index 233891d9086..76ea32829e1 100644 --- a/src/test/cli/rbd/help.t +++ b/src/test/cli/rbd/help.t @@ -123,6 +123,7 @@ snap rename Rename a snapshot. snap rollback (snap revert) Rollback image to snapshot. snap unprotect Allow a snapshot to be deleted. + sparsify Reclaim space for zeroed image extents. status Show the status of this image. trash list (trash ls) List trash images. trash move (trash mv) Move an image to the trash. @@ -2165,6 +2166,25 @@ --snap arg snapshot name --image-id arg image id + rbd help sparsify + usage: rbd sparsify [--pool ] [--namespace ] + [--image ] [--no-progress] + [--sparse-size ] + + + Reclaim space for zeroed image extents. + + Positional arguments + image specification + (example: [/[/]]) + + Optional arguments + -p [ --pool ] arg pool name + --namespace arg namespace name + --image arg image name + --no-progress disable progress output + --sparse-size arg sparse size in B/K/M [default: 4K] + rbd help status usage: rbd status [--pool ] [--namespace ] [--image ] [--format ] [--pretty-format] diff --git a/src/tools/rbd/CMakeLists.txt b/src/tools/rbd/CMakeLists.txt index 6679769c0bf..eaebbc8f114 100644 --- a/src/tools/rbd/CMakeLists.txt +++ b/src/tools/rbd/CMakeLists.txt @@ -40,6 +40,7 @@ set(rbd_srcs action/Rename.cc action/Resize.cc action/Snap.cc + action/Sparsify.cc action/Status.cc action/Trash.cc action/Watch.cc) diff --git a/src/tools/rbd/action/Sparsify.cc b/src/tools/rbd/action/Sparsify.cc new file mode 100644 index 00000000000..a345f920b3e --- /dev/null +++ b/src/tools/rbd/action/Sparsify.cc @@ -0,0 +1,82 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "tools/rbd/ArgumentTypes.h" +#include "tools/rbd/Shell.h" +#include "tools/rbd/Utils.h" +#include "common/errno.h" +#include +#include + +namespace rbd { +namespace action { +namespace sparsify { + +namespace at = argument_types; +namespace po = boost::program_options; + +static int do_sparsify(librbd::Image& image, size_t sparse_size, + bool no_progress) +{ + utils::ProgressContext pc("Image sparsify", no_progress); + int r = image.sparsify_with_progress(sparse_size, pc); + if (r < 0) { + pc.fail(); + return r; + } + pc.finish(); + return 0; +} + +void get_arguments(po::options_description *positional, + po::options_description *options) { + at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); + at::add_no_progress_option(options); + at::add_sparse_size_option(options); +} + +int execute(const po::variables_map &vm, + const std::vector &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, &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; + librbd::Image image; + r = utils::init_and_open_image(pool_name, namespace_name, image_name, "", "", + false, &rados, &io_ctx, &image); + if (r < 0) { + return r; + } + + size_t sparse_size = utils::RBD_DEFAULT_SPARSE_SIZE; + if (vm.count(at::IMAGE_SPARSE_SIZE)) { + sparse_size = vm[at::IMAGE_SPARSE_SIZE].as(); + } + + r = do_sparsify(image, sparse_size, vm[at::NO_PROGRESS].as()); + if (r < 0) { + std::cerr << "rbd: sparsify error: " << cpp_strerror(r) << std::endl; + return r; + } + return 0; +} + +Shell::Action action( + {"sparsify"}, {}, + "Reclaim space for zeroed image extents.", "", + &get_arguments, &execute); + +} // namespace sparsify +} // namespace action +} // namespace rbd -- 2.39.5