]> git.proxmox.com Git - ceph.git/blame - ceph/src/tools/rbd/action/Group.cc
bump version to 12.1.2-pve1
[ceph.git] / ceph / src / tools / rbd / action / Group.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include <iostream>
5
6#include "tools/rbd/ArgumentTypes.h"
7#include "tools/rbd/Shell.h"
8#include "tools/rbd/Utils.h"
9#include "include/rbd_types.h"
10#include "cls/rbd/cls_rbd_types.h"
11#include "common/errno.h"
12#include "common/Formatter.h"
13
14namespace rbd {
15namespace action {
16namespace consgrp {
17
18namespace at = argument_types;
19namespace po = boost::program_options;
20
21int execute_create(const po::variables_map &vm) {
22 size_t arg_index = 0;
23
24 std::string group_name;
25 std::string pool_name;
26
27 int r = utils::get_pool_group_names(vm, at::ARGUMENT_MODIFIER_NONE,
28 &arg_index, &pool_name, &group_name);
29 if (r < 0) {
30 return r;
31 }
32
33 librados::Rados rados;
34 librados::IoCtx io_ctx;
35
36 r = utils::init(pool_name, &rados, &io_ctx);
37 if (r < 0) {
38 return r;
39 }
40 librbd::RBD rbd;
41 r = rbd.group_create(io_ctx, group_name.c_str());
42 if (r < 0) {
43 std::cerr << "rbd: create error: " << cpp_strerror(r) << std::endl;
44 return r;
45 }
46
47 return 0;
48}
49
50int execute_list(const po::variables_map &vm) {
51
52 size_t arg_index = 0;
53 std::string pool_name = utils::get_pool_name(vm, &arg_index);
54
55 at::Format::Formatter formatter;
56 int r = utils::get_formatter(vm, &formatter);
57 if (r < 0) {
58 return r;
59 }
60 Formatter *f = formatter.get();
61
62 librados::Rados rados;
63 librados::IoCtx io_ctx;
64 r = utils::init(pool_name, &rados, &io_ctx);
65 if (r < 0) {
66 return r;
67 }
68
69 librbd::RBD rbd;
70 std::vector<std::string> names;
71 r = rbd.group_list(io_ctx, &names);
7c673cae
FG
72 if (r < 0)
73 return r;
74
75 if (f)
76 f->open_array_section("consistency_groups");
77 for (auto i : names) {
78 if (f)
79 f->dump_string("name", i);
80 else
81 std::cout << i << std::endl;
82 }
83 if (f) {
84 f->close_section();
85 f->flush(std::cout);
86 }
87
88 return 0;
89}
90
91int execute_remove(const po::variables_map &vm) {
92 size_t arg_index = 0;
93
94 std::string group_name;
95 std::string pool_name;
96
97 int r = utils::get_pool_group_names(vm, at::ARGUMENT_MODIFIER_NONE,
98 &arg_index, &pool_name, &group_name);
99 if (r < 0) {
100 return r;
101 }
102
103 librados::Rados rados;
104 librados::IoCtx io_ctx;
105
106 r = utils::init(pool_name, &rados, &io_ctx);
107 if (r < 0) {
108 return r;
109 }
110 librbd::RBD rbd;
111
112 r = rbd.group_remove(io_ctx, group_name.c_str());
113 if (r < 0) {
114 std::cerr << "rbd: remove error: " << cpp_strerror(r) << std::endl;
115 return r;
116 }
117
118 return 0;
119}
120
121int execute_add(const po::variables_map &vm) {
122 size_t arg_index = 0;
123 // Parse group data.
124 std::string group_name;
125 std::string group_pool_name;
126
127 int r = utils::get_special_pool_group_names(vm, &arg_index,
128 &group_pool_name,
129 &group_name);
130 if (r < 0) {
131 std::cerr << "rbd: image add error: " << cpp_strerror(r) << std::endl;
132 return r;
133 }
134
135 std::string image_name;
136 std::string image_pool_name;
137
138 r = utils::get_special_pool_image_names(vm, &arg_index,
139 &image_pool_name,
140 &image_name);
141
142 if (r < 0) {
143 std::cerr << "rbd: image add error: " << cpp_strerror(r) << std::endl;
144 return r;
145 }
146
147 librados::Rados rados;
148
149 librados::IoCtx cg_io_ctx;
150 r = utils::init(group_pool_name, &rados, &cg_io_ctx);
151 if (r < 0) {
152 return r;
153 }
154
155 librados::IoCtx image_io_ctx;
156 r = utils::init(image_pool_name, &rados, &image_io_ctx);
157 if (r < 0) {
158 return r;
159 }
160
161 librbd::RBD rbd;
162 r = rbd.group_image_add(cg_io_ctx, group_name.c_str(),
163 image_io_ctx, image_name.c_str());
164 if (r < 0) {
165 std::cerr << "rbd: add image error: " << cpp_strerror(r) << std::endl;
166 return r;
167 }
168
169 return 0;
170}
171
172int execute_remove_image(const po::variables_map &vm) {
173 size_t arg_index = 0;
174
175 std::string group_name;
176 std::string group_pool_name;
177
178 int r = utils::get_special_pool_group_names(vm, &arg_index,
179 &group_pool_name,
180 &group_name);
181 if (r < 0) {
182 std::cerr << "rbd: image remove error: " << cpp_strerror(r) << std::endl;
183 return r;
184 }
185
186 std::string image_name;
187 std::string image_pool_name;
188 std::string image_id;
189
190 if (vm.count(at::IMAGE_ID)) {
191 image_id = vm[at::IMAGE_ID].as<std::string>();
192 }
193
194 bool has_image_spec = utils::check_if_image_spec_present(
195 vm, at::ARGUMENT_MODIFIER_NONE, arg_index);
196
197 if (!image_id.empty() && has_image_spec) {
198 std::cerr << "rbd: trying to access image using both name and id. "
199 << std::endl;
200 return -EINVAL;
201 }
202
203 if (image_id.empty()) {
204 r = utils::get_special_pool_image_names(vm, &arg_index, &image_pool_name,
205 &image_name);
206 } else {
207 image_pool_name = utils::get_pool_name(vm, &arg_index);
208 }
209
210 if (r < 0) {
211 std::cerr << "rbd: image remove error: " << cpp_strerror(r) << std::endl;
212 return r;
213 }
214
215 librados::Rados rados;
216
217 librados::IoCtx cg_io_ctx;
218 r = utils::init(group_pool_name, &rados, &cg_io_ctx);
219 if (r < 0) {
220 return r;
221 }
222
223 librados::IoCtx image_io_ctx;
224 r = utils::init(image_pool_name, &rados, &image_io_ctx);
225 if (r < 0) {
226 return r;
227 }
228
229 librbd::RBD rbd;
230 if (image_id.empty()) {
231 r = rbd.group_image_remove(cg_io_ctx, group_name.c_str(),
232 image_io_ctx, image_name.c_str());
233 } else {
234 r = rbd.group_image_remove_by_id(cg_io_ctx, group_name.c_str(),
235 image_io_ctx, image_id.c_str());
236 }
237 if (r < 0) {
238 std::cerr << "rbd: remove image error: " << cpp_strerror(r) << std::endl;
239 return r;
240 }
241
242 return 0;
243}
244
245int execute_list_images(const po::variables_map &vm) {
246 size_t arg_index = 0;
247 std::string group_name;
248 std::string pool_name;
249
250 int r = utils::get_pool_group_names(vm, at::ARGUMENT_MODIFIER_NONE,
251 &arg_index, &pool_name, &group_name);
252 if (r < 0) {
253 return r;
254 }
255
256 if (group_name.empty()) {
257 std::cerr << "rbd: "
258 << "consistency group name was not specified" << std::endl;
259 return -EINVAL;
260 }
261
262 at::Format::Formatter formatter;
263 r = utils::get_formatter(vm, &formatter);
264 if (r < 0) {
265 return r;
266 }
267 Formatter *f = formatter.get();
268
269 librados::Rados rados;
270 librados::IoCtx io_ctx;
271 r = utils::init(pool_name, &rados, &io_ctx);
272 if (r < 0) {
273 return r;
274 }
275
276 librbd::RBD rbd;
277 std::vector<librbd::group_image_status_t> images;
278
279 r = rbd.group_image_list(io_ctx, group_name.c_str(), &images);
280
281 if (r == -ENOENT)
282 r = 0;
283
284 if (r < 0)
285 return r;
286
287 if (f)
288 f->open_array_section("consistency_groups");
289
290 for (auto i : images) {
291 std::string image_name = i.name;
292 int64_t pool_id = i.pool;
293 int state = i.state;
294 std::string state_string;
295 if (cls::rbd::GROUP_IMAGE_LINK_STATE_INCOMPLETE == state) {
296 state_string = "incomplete";
297 }
298 if (f) {
299 f->dump_string("image name", image_name);
300 f->dump_int("pool id", pool_id);
301 f->dump_int("state", state);
302 } else
303 std::cout << pool_id << "." << image_name << " " << state_string << std::endl;
304 }
305
306 if (f) {
307 f->close_section();
308 f->flush(std::cout);
309 }
310
311 return 0;
312}
313
314void get_create_arguments(po::options_description *positional,
315 po::options_description *options) {
316 at::add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
317}
318
319void get_remove_arguments(po::options_description *positional,
320 po::options_description *options) {
321 at::add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
322}
323
324void get_list_arguments(po::options_description *positional,
325 po::options_description *options) {
326 add_pool_option(options, at::ARGUMENT_MODIFIER_NONE);
327 at::add_format_options(options);
328}
329
330void get_add_arguments(po::options_description *positional,
331 po::options_description *options) {
332 positional->add_options()
333 (at::GROUP_SPEC.c_str(),
334 "group specification\n"
335 "(example: [<pool-name>/]<group-name>)");
336
337 at::add_special_pool_option(options, "group");
338 at::add_group_option(options, at::ARGUMENT_MODIFIER_NONE);
339
340 positional->add_options()
341 (at::IMAGE_SPEC.c_str(),
342 "image specification\n"
343 "(example: [<pool-name>/]<image-name>)");
344
345 at::add_special_pool_option(options, "image");
346 at::add_image_option(options, at::ARGUMENT_MODIFIER_NONE);
347
348 at::add_pool_option(options, at::ARGUMENT_MODIFIER_NONE,
349 " unless overridden");
350}
351
352void get_remove_image_arguments(po::options_description *positional,
353 po::options_description *options) {
354 positional->add_options()
355 (at::GROUP_SPEC.c_str(),
356 "group specification\n"
357 "(example: [<pool-name>/]<group-name>)");
358
359 at::add_special_pool_option(options, "group");
360 at::add_group_option(options, at::ARGUMENT_MODIFIER_NONE);
361
362 positional->add_options()
363 (at::IMAGE_SPEC.c_str(),
364 "image specification\n"
365 "(example: [<pool-name>/]<image-name>)");
366
367 at::add_special_pool_option(options, "image");
368 at::add_image_option(options, at::ARGUMENT_MODIFIER_NONE);
369
370 at::add_pool_option(options, at::ARGUMENT_MODIFIER_NONE,
371 " unless overridden");
372 at::add_image_id_option(options);
373}
374
375void get_list_images_arguments(po::options_description *positional,
376 po::options_description *options) {
377 at::add_format_options(options);
378 at::add_group_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
379}
380
381Shell::Action action_create(
382 {"group", "create"}, {}, "Create a consistency group.",
383 "", &get_create_arguments, &execute_create);
384Shell::Action action_remove(
385 {"group", "remove"}, {"group", "rm"}, "Delete a consistency group.",
386 "", &get_remove_arguments, &execute_remove);
387Shell::Action action_list(
388 {"group", "list"}, {"group", "ls"}, "List rbd consistency groups.",
389 "", &get_list_arguments, &execute_list);
390Shell::Action action_add(
391 {"group", "image", "add"}, {}, "Add an image to a consistency group.",
392 "", &get_add_arguments, &execute_add);
393Shell::Action action_remove_image(
394 {"group", "image", "remove"}, {}, "Remove an image from a consistency group.",
395 "", &get_remove_image_arguments, &execute_remove_image);
396Shell::Action action_list_images(
397 {"group", "image", "list"}, {}, "List images in a consistency group.",
398 "", &get_list_images_arguments, &execute_list_images);
399} // namespace group
400} // namespace action
401} // namespace rbd