]> git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd/action/Resize.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / tools / rbd / action / Resize.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "tools/rbd/ArgumentTypes.h"
5 #include "tools/rbd/Shell.h"
6 #include "tools/rbd/Utils.h"
7 #include "common/errno.h"
8 #include <iostream>
9 #include <boost/program_options.hpp>
10
11 namespace rbd {
12 namespace action {
13 namespace resize {
14
15 namespace at = argument_types;
16 namespace po = boost::program_options;
17
18 static int do_resize(librbd::Image& image, uint64_t size, bool allow_shrink, bool no_progress)
19 {
20 utils::ProgressContext pc("Resizing image", no_progress);
21 int r = image.resize2(size, allow_shrink, pc);
22 if (r < 0) {
23 pc.fail();
24 return r;
25 }
26 pc.finish();
27 return 0;
28 }
29
30 void get_arguments(po::options_description *positional,
31 po::options_description *options) {
32 at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
33 at::add_size_option(options);
34 options->add_options()
35 ("allow-shrink", po::bool_switch(), "permit shrinking");
36 at::add_no_progress_option(options);
37 at::add_encryption_options(options);
38 }
39
40 int execute(const po::variables_map &vm,
41 const std::vector<std::string> &ceph_global_init_args) {
42 size_t arg_index = 0;
43 std::string pool_name;
44 std::string namespace_name;
45 std::string image_name;
46 std::string snap_name;
47 int r = utils::get_pool_image_snapshot_names(
48 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &namespace_name,
49 &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_NONE,
50 utils::SPEC_VALIDATION_NONE);
51 if (r < 0) {
52 return r;
53 }
54
55 uint64_t size;
56 r = utils::get_image_size(vm, &size);
57 if (r < 0) {
58 return r;
59 }
60
61 utils::EncryptionOptions encryption_options;
62 r = utils::get_encryption_options(vm, &encryption_options);
63 if (r < 0) {
64 return r;
65 }
66
67 librados::Rados rados;
68 librados::IoCtx io_ctx;
69 librbd::Image image;
70 r = utils::init_and_open_image(pool_name, namespace_name, image_name, "",
71 snap_name, false, &rados, &io_ctx, &image);
72 if (r < 0) {
73 return r;
74 }
75
76 if (!encryption_options.specs.empty()) {
77 r = image.encryption_load2(encryption_options.specs.data(),
78 encryption_options.specs.size());
79 if (r < 0) {
80 std::cerr << "rbd: encryption load failed: " << cpp_strerror(r)
81 << std::endl;
82 return r;
83 }
84 }
85
86 librbd::image_info_t info;
87 r = image.stat(info, sizeof(info));
88 if (r < 0) {
89 std::cerr << "rbd: resize error: " << cpp_strerror(r) << std::endl;
90 return r;
91 }
92
93 if (info.size == size) {
94 std::cerr << "rbd: new size is equal to original size " << std::endl;
95 return -EINVAL;
96 }
97
98 if (info.size > size && !vm["allow-shrink"].as<bool>()) {
99 r = -EINVAL;
100 } else {
101 r = do_resize(image, size, vm["allow-shrink"].as<bool>(), vm[at::NO_PROGRESS].as<bool>());
102 }
103
104 if (r < 0) {
105 if (r == -EINVAL && !vm["allow-shrink"].as<bool>()) {
106 std::cerr << "rbd: shrinking an image is only allowed with the "
107 << "--allow-shrink flag" << std::endl;
108 return r;
109 }
110 std::cerr << "rbd: resize error: " << cpp_strerror(r) << std::endl;
111 return r;
112 }
113 return 0;
114 }
115
116 Shell::SwitchArguments switched_arguments({"allow-shrink"});
117 Shell::Action action(
118 {"resize"}, {}, "Resize (expand or shrink) image.", "", &get_arguments,
119 &execute);
120
121 } // namespace resize
122 } // namespace action
123 } // namespace rbd