]>
Commit | Line | Data |
---|---|---|
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 | ||
14 | namespace rbd { | |
15 | namespace action { | |
16 | namespace consgrp { | |
17 | ||
18 | namespace at = argument_types; | |
19 | namespace po = boost::program_options; | |
20 | ||
21 | int 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 | ||
50 | int 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 | ||
91 | int 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 | ||
121 | int 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 | ||
172 | int 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 | ||
245 | int 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 | ||
314 | void 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 | ||
319 | void 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 | ||
324 | void 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 | ||
330 | void 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 | ||
352 | void 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 | ||
375 | void 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 | ||
381 | Shell::Action action_create( | |
382 | {"group", "create"}, {}, "Create a consistency group.", | |
383 | "", &get_create_arguments, &execute_create); | |
384 | Shell::Action action_remove( | |
385 | {"group", "remove"}, {"group", "rm"}, "Delete a consistency group.", | |
386 | "", &get_remove_arguments, &execute_remove); | |
387 | Shell::Action action_list( | |
388 | {"group", "list"}, {"group", "ls"}, "List rbd consistency groups.", | |
389 | "", &get_list_arguments, &execute_list); | |
390 | Shell::Action action_add( | |
391 | {"group", "image", "add"}, {}, "Add an image to a consistency group.", | |
392 | "", &get_add_arguments, &execute_add); | |
393 | Shell::Action action_remove_image( | |
394 | {"group", "image", "remove"}, {}, "Remove an image from a consistency group.", | |
395 | "", &get_remove_image_arguments, &execute_remove_image); | |
396 | Shell::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 |