]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: online re-sparsify of images 26226/head
authorMykola Golub <mgolub@suse.com>
Tue, 29 Jan 2019 11:44:54 +0000 (11:44 +0000)
committerMykola Golub <mgolub@suse.com>
Fri, 15 Feb 2019 11:12:00 +0000 (11:12 +0000)
Signed-off-by: Mykola Golub <mgolub@suse.com>
doc/man/8/rbd.rst
qa/workunits/rbd/cli_generic.sh
src/test/cli/rbd/help.t
src/tools/rbd/CMakeLists.txt
src/tools/rbd/action/Sparsify.cc [new file with mode: 0644]

index 928dda028e558c70478ee43f3304f5bd4233780a..22f78ad63d555889dc723c1713813db3a1375405 100644 (file)
@@ -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.
 
index 8f2a25a8e955105793b26c9d9aaed7136907a579..97d64577fad5b7219dd40ef60685fe77bece638f 100755 (executable)
@@ -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
 }
index 233891d908650d5ef6ae592b2bbdcf5966b42762..76ea32829e1bd789e4e4052a37f8502b7a91f01f 100644 (file)
       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.
     --snap arg           snapshot name
     --image-id arg       image id
   
+  rbd help sparsify
+  usage: rbd sparsify [--pool <pool>] [--namespace <namespace>] 
+                      [--image <image>] [--no-progress] 
+                      [--sparse-size <sparse-size>] 
+                      <image-spec> 
+  
+  Reclaim space for zeroed image extents.
+  
+  Positional arguments
+    <image-spec>         image specification
+                         (example: [<pool-name>/[<namespace-name>/]]<image-name>)
+  
+  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 <pool>] [--namespace <namespace>] [--image <image>] 
                     [--format <format>] [--pretty-format] 
index 6679769c0bf2b84481f9920e1c584052cb2a97f3..eaebbc8f114332189156af8ce9e5df38724cd09d 100644 (file)
@@ -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 (file)
index 0000000..a345f92
--- /dev/null
@@ -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 <iostream>
+#include <boost/program_options.hpp>
+
+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<std::string> &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<size_t>();
+  }
+
+  r = do_sparsify(image, sparse_size, vm[at::NO_PROGRESS].as<bool>());
+  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