1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "cls/rbd/cls_rbd_client.h"
5 #include "cls/lock/cls_lock_client.h"
6 #include "include/buffer.h"
7 #include "include/encoding.h"
8 #include "include/rbd_types.h"
9 #include "include/rados/librados.hpp"
10 #include "common/bit_vector.hpp"
11
12 #include <errno.h>
13
14 namespace librbd {
15 namespace cls_client {
16
17 void create_image(librados::ObjectWriteOperation *op, uint64_t size,
18 uint8_t order, uint64_t features,
19 const std::string &object_prefix, int64_t data_pool_id)
20 {
21 bufferlist bl;
22 encode(size, bl);
23 encode(order, bl);
24 encode(features, bl);
25 encode(object_prefix, bl);
26 encode(data_pool_id, bl);
27
28 op->exec("rbd", "create", bl);
29 }
30
31 int create_image(librados::IoCtx *ioctx, const std::string &oid,
32 uint64_t size, uint8_t order, uint64_t features,
33 const std::string &object_prefix, int64_t data_pool_id)
34 {
35 librados::ObjectWriteOperation op;
36 create_image(&op, size, order, features, object_prefix, data_pool_id);
37
38 return ioctx->operate(oid, &op);
39 }
40
41 void get_features_start(librados::ObjectReadOperation *op, bool read_only)
42 {
43 bufferlist bl;
44 encode(static_cast<uint64_t>(CEPH_NOSNAP), bl);
45 encode(read_only, bl);
46 op->exec("rbd", "get_features", bl);
47 }
48
49 int get_features_finish(bufferlist::const_iterator *it, uint64_t *features,
50 uint64_t *incompatible_features)
51 {
52 try {
53 decode(*features, *it);
54 decode(*incompatible_features, *it);
55 } catch (const buffer::error &err) {
56 return -EBADMSG;
57 }
58
59 return 0;
60 }
61
62 int get_features(librados::IoCtx *ioctx, const std::string &oid,
63 bool read_only, uint64_t *features,
64 uint64_t *incompatible_features)
65 {
66 librados::ObjectReadOperation op;
67 get_features_start(&op, read_only);
68
69 bufferlist out_bl;
70 int r = ioctx->operate(oid, &op, &out_bl);
71 if (r < 0) {
72 return r;
73 }
74
75 auto it = out_bl.cbegin();
76 return get_features_finish(&it, features, incompatible_features);
77 }
78
79 void set_features(librados::ObjectWriteOperation *op, uint64_t features,
80 uint64_t mask)
81 {
82 bufferlist bl;
83 encode(features, bl);
84 encode(mask, bl);
85
86 op->exec("rbd", "set_features", bl);
87 }
88
89 int set_features(librados::IoCtx *ioctx, const std::string &oid,
90 uint64_t features, uint64_t mask)
91 {
92 librados::ObjectWriteOperation op;
93 set_features(&op, features, mask);
94
95 return ioctx->operate(oid, &op);
96 }
97
98 void get_object_prefix_start(librados::ObjectReadOperation *op)
99 {
100 bufferlist bl;
101 op->exec("rbd", "get_object_prefix", bl);
102 }
103
104 int get_object_prefix_finish(bufferlist::const_iterator *it,
105 std::string *object_prefix)
106 {
107 try {
108 decode(*object_prefix, *it);
109 } catch (const buffer::error &err) {
110 return -EBADMSG;
111 }
112 return 0;
113 }
114
115 int get_object_prefix(librados::IoCtx *ioctx, const std::string &oid,
116 std::string *object_prefix)
117 {
118 librados::ObjectReadOperation op;
119 get_object_prefix_start(&op);
120
121 bufferlist out_bl;
122 int r = ioctx->operate(oid, &op, &out_bl);
123 if (r < 0) {
124 return r;
125 }
126
127 auto it = out_bl.cbegin();
128 return get_object_prefix_finish(&it, object_prefix);
129 }
130
131 void get_data_pool_start(librados::ObjectReadOperation *op) {
132 bufferlist bl;
133 op->exec("rbd", "get_data_pool", bl);
134 }
135
136 int get_data_pool_finish(bufferlist::const_iterator *it, int64_t *data_pool_id) {
137 try {
138 decode(*data_pool_id, *it);
139 } catch (const buffer::error &err) {
140 return -EBADMSG;
141 }
142 return 0;
143 }
144
145 int get_data_pool(librados::IoCtx *ioctx, const std::string &oid,
146 int64_t *data_pool_id) {
147 librados::ObjectReadOperation op;
148 get_data_pool_start(&op);
149
150 bufferlist out_bl;
151 int r = ioctx->operate(oid, &op, &out_bl);
152 if (r < 0) {
153 return r;
154 }
155
156 auto it = out_bl.cbegin();
157 return get_data_pool_finish(&it, data_pool_id);
158 }
159
160 void get_size_start(librados::ObjectReadOperation *op, snapid_t snap_id)
161 {
162 bufferlist bl;
163 encode(snap_id, bl);
164 op->exec("rbd", "get_size", bl);
165 }
166
167 int get_size_finish(bufferlist::const_iterator *it, uint64_t *size,
168 uint8_t *order)
169 {
170 try {
171 decode(*order, *it);
172 decode(*size, *it);
173 } catch (const buffer::error &err) {
174 return -EBADMSG;
175 }
176 return 0;
177 }
178
179 int get_size(librados::IoCtx *ioctx, const std::string &oid,
180 snapid_t snap_id, uint64_t *size, uint8_t *order)
181 {
182 librados::ObjectReadOperation op;
183 get_size_start(&op, snap_id);
184
185 bufferlist out_bl;
186 int r = ioctx->operate(oid, &op, &out_bl);
187 if (r < 0) {
188 return r;
189 }
190
191 auto it = out_bl.cbegin();
192 return get_size_finish(&it, size, order);
193 }
194
195 int set_size(librados::IoCtx *ioctx, const std::string &oid,
196 uint64_t size)
197 {
198 librados::ObjectWriteOperation op;
199 set_size(&op, size);
200 return ioctx->operate(oid, &op);
201 }
202
203 void set_size(librados::ObjectWriteOperation *op, uint64_t size)
204 {
205 bufferlist bl;
206 encode(size, bl);
207 op->exec("rbd", "set_size", bl);
208 }
209
210 void get_flags_start(librados::ObjectReadOperation *op, snapid_t snap_id) {
211 bufferlist in_bl;
212 encode(static_cast<snapid_t>(snap_id), in_bl);
213 op->exec("rbd", "get_flags", in_bl);
214 }
215
216 int get_flags_finish(bufferlist::const_iterator *it, uint64_t *flags) {
217 try {
218 decode(*flags, *it);
219 } catch (const buffer::error &err) {
220 return -EBADMSG;
221 }
222 return 0;
223 }
224
225 int get_flags(librados::IoCtx *ioctx, const std::string &oid,
226 snapid_t snap_id, uint64_t *flags)
227 {
228 librados::ObjectReadOperation op;
229 get_flags_start(&op, snap_id);
230
231 bufferlist out_bl;
232 int r = ioctx->operate(oid, &op, &out_bl);
233 if (r < 0) {
234 return r;
235 }
236
237 auto it = out_bl.cbegin();
238 return get_flags_finish(&it, flags);
239 }
240
241 void set_flags(librados::ObjectWriteOperation *op, snapid_t snap_id,
242 uint64_t flags, uint64_t mask)
243 {
244 bufferlist inbl;
245 encode(flags, inbl);
246 encode(mask, inbl);
247 encode(snap_id, inbl);
248 op->exec("rbd", "set_flags", inbl);
249 }
250
251 void op_features_get_start(librados::ObjectReadOperation *op)
252 {
253 bufferlist in_bl;
254 op->exec("rbd", "op_features_get", in_bl);
255 }
256
257 int op_features_get_finish(bufferlist::const_iterator *it, uint64_t *op_features)
258 {
259 try {
260 decode(*op_features, *it);
261 } catch (const buffer::error &err) {
262 return -EBADMSG;
263 }
264 return 0;
265 }
266
267 int op_features_get(librados::IoCtx *ioctx, const std::string &oid,
268 uint64_t *op_features)
269 {
270 librados::ObjectReadOperation op;
271 op_features_get_start(&op);
272
273 bufferlist out_bl;
274 int r = ioctx->operate(oid, &op, &out_bl);
275 if (r < 0) {
276 return r;
277 }
278
279 auto it = out_bl.cbegin();
280 return op_features_get_finish(&it, op_features);
281 }
282
283 void op_features_set(librados::ObjectWriteOperation *op,
284 uint64_t op_features, uint64_t mask)
285 {
286 bufferlist inbl;
287 encode(op_features, inbl);
288 encode(mask, inbl);
289 op->exec("rbd", "op_features_set", inbl);
290 }
291
292 int op_features_set(librados::IoCtx *ioctx, const std::string &oid,
293 uint64_t op_features, uint64_t mask)
294 {
295 librados::ObjectWriteOperation op;
296 op_features_set(&op, op_features, mask);
297
298 return ioctx->operate(oid, &op);
299 }
300
301 void get_parent_start(librados::ObjectReadOperation *op, snapid_t snap_id)
302 {
303 bufferlist bl;
304 encode(snap_id, bl);
305 op->exec("rbd", "get_parent", bl);
306 }
307
308 int get_parent_finish(bufferlist::const_iterator *it,
309 cls::rbd::ParentImageSpec *pspec,
310 uint64_t *parent_overlap)
311 {
312 *pspec = {};
313 try {
314 decode(pspec->pool_id, *it);
315 decode(pspec->image_id, *it);
316 decode(pspec->snap_id, *it);
317 decode(*parent_overlap, *it);
318 } catch (const buffer::error &) {
319 return -EBADMSG;
320 }
321 return 0;
322 }
323
324 int get_parent(librados::IoCtx *ioctx, const std::string &oid,
325 snapid_t snap_id, cls::rbd::ParentImageSpec *pspec,
326 uint64_t *parent_overlap)
327 {
328 librados::ObjectReadOperation op;
329 get_parent_start(&op, snap_id);
330
331 bufferlist out_bl;
332 int r = ioctx->operate(oid, &op, &out_bl);
333 if (r < 0) {
334 return r;
335 }
336
337 auto it = out_bl.cbegin();
338 return get_parent_finish(&it, pspec, parent_overlap);
339 }
340
341 int set_parent(librados::IoCtx *ioctx, const std::string &oid,
342 const cls::rbd::ParentImageSpec &pspec, uint64_t parent_overlap)
343 {
344 librados::ObjectWriteOperation op;
345 set_parent(&op, pspec, parent_overlap);
346 return ioctx->operate(oid, &op);
347 }
348
349 void set_parent(librados::ObjectWriteOperation *op,
350 const cls::rbd::ParentImageSpec &pspec,
351 uint64_t parent_overlap) {
352 assert(pspec.pool_namespace.empty());
353
354 bufferlist in_bl;
355 encode(pspec.pool_id, in_bl);
356 encode(pspec.image_id, in_bl);
357 encode(pspec.snap_id, in_bl);
358 encode(parent_overlap, in_bl);
359
360 op->exec("rbd", "set_parent", in_bl);
361 }
362
363 int remove_parent(librados::IoCtx *ioctx, const std::string &oid)
364 {
365 librados::ObjectWriteOperation op;
366 remove_parent(&op);
367 return ioctx->operate(oid, &op);
368 }
369
370 void remove_parent(librados::ObjectWriteOperation *op)
371 {
372 bufferlist inbl;
373 op->exec("rbd", "remove_parent", inbl);
374 }
375
376 void parent_get_start(librados::ObjectReadOperation* op) {
377 bufferlist in_bl;
378 op->exec("rbd", "parent_get", in_bl);
379 }
380
381 int parent_get_finish(bufferlist::const_iterator* it,
382 cls::rbd::ParentImageSpec* parent_image_spec) {
383 try {
384 decode(*parent_image_spec, *it);
385 } catch (const buffer::error &) {
386 return -EBADMSG;
387 }
388 return 0;
389 }
390
391 int parent_get(librados::IoCtx* ioctx, const std::string &oid,
392 cls::rbd::ParentImageSpec* parent_image_spec) {
393 librados::ObjectReadOperation op;
394 parent_get_start(&op);
395
396 bufferlist out_bl;
397 int r = ioctx->operate(oid, &op, &out_bl);
398 if (r < 0) {
399 return r;
400 }
401
402 auto it = out_bl.cbegin();
403 r = parent_get_finish(&it, parent_image_spec);
404 if (r < 0) {
405 return r;
406 }
407 return 0;
408 }
409
410 void parent_overlap_get_start(librados::ObjectReadOperation* op,
411 snapid_t snap_id) {
412 bufferlist in_bl;
413 encode(snap_id, in_bl);
414 op->exec("rbd", "parent_overlap_get", in_bl);
415 }
416
417 int parent_overlap_get_finish(bufferlist::const_iterator* it,
418 std::optional<uint64_t>* parent_overlap) {
419 try {
420 decode(*parent_overlap, *it);
421 } catch (const buffer::error &) {
422 return -EBADMSG;
423 }
424 return 0;
425 }
426
427 int parent_overlap_get(librados::IoCtx* ioctx, const std::string &oid,
428 snapid_t snap_id,
429 std::optional<uint64_t>* parent_overlap) {
430 librados::ObjectReadOperation op;
431 parent_overlap_get_start(&op, snap_id);
432
433 bufferlist out_bl;
434 int r = ioctx->operate(oid, &op, &out_bl);
435 if (r < 0) {
436 return r;
437 }
438
439 auto it = out_bl.cbegin();
440 r = parent_overlap_get_finish(&it, parent_overlap);
441 if (r < 0) {
442 return r;
443 }
444 return 0;
445 }
446
447 void parent_attach(librados::ObjectWriteOperation* op,
448 const cls::rbd::ParentImageSpec& parent_image_spec,
449 uint64_t parent_overlap, bool reattach) {
450 bufferlist in_bl;
451 encode(parent_image_spec, in_bl);
452 encode(parent_overlap, in_bl);
453 encode(reattach, in_bl);
454 op->exec("rbd", "parent_attach", in_bl);
455 }
456
457 int parent_attach(librados::IoCtx *ioctx, const std::string &oid,
458 const cls::rbd::ParentImageSpec& parent_image_spec,
459 uint64_t parent_overlap, bool reattach) {
460 librados::ObjectWriteOperation op;
461 parent_attach(&op, parent_image_spec, parent_overlap, reattach);
462 return ioctx->operate(oid, &op);
463 }
464
465 void parent_detach(librados::ObjectWriteOperation* op) {
466 bufferlist in_bl;
467 op->exec("rbd", "parent_detach", in_bl);
468 }
469
470 int parent_detach(librados::IoCtx *ioctx, const std::string &oid) {
471 librados::ObjectWriteOperation op;
472 parent_detach(&op);
473 return ioctx->operate(oid, &op);
474 }
475
476 int add_child(librados::IoCtx *ioctx, const std::string &oid,
477 const cls::rbd::ParentImageSpec &pspec,
478 const std::string &c_imageid)
479 {
480 librados::ObjectWriteOperation op;
481 add_child(&op, pspec, c_imageid);
482 return ioctx->operate(oid, &op);
483 }
484
485 void add_child(librados::ObjectWriteOperation *op,
486 const cls::rbd::ParentImageSpec& pspec,
487 const std::string &c_imageid)
488 {
489 assert(pspec.pool_namespace.empty());
490
491 bufferlist in;
492 encode(pspec.pool_id, in);
493 encode(pspec.image_id, in);
494 encode(pspec.snap_id, in);
495 encode(c_imageid, in);
496
497 op->exec("rbd", "add_child", in);
498 }
499
500 void remove_child(librados::ObjectWriteOperation *op,
501 const cls::rbd::ParentImageSpec &pspec,
502 const std::string &c_imageid)
503 {
504 assert(pspec.pool_namespace.empty());
505
506 bufferlist in;
507 encode(pspec.pool_id, in);
508 encode(pspec.image_id, in);
509 encode(pspec.snap_id, in);
510 encode(c_imageid, in);
511 op->exec("rbd", "remove_child", in);
512 }
513
514 int remove_child(librados::IoCtx *ioctx, const std::string &oid,
515 const cls::rbd::ParentImageSpec &pspec,
516 const std::string &c_imageid)
517 {
518 librados::ObjectWriteOperation op;
519 remove_child(&op, pspec, c_imageid);
520 return ioctx->operate(oid, &op);
521 }
522
523 void get_children_start(librados::ObjectReadOperation *op,
524 const cls::rbd::ParentImageSpec &pspec) {
525 bufferlist in_bl;
526 encode(pspec.pool_id, in_bl);
527 encode(pspec.image_id, in_bl);
528 encode(pspec.snap_id, in_bl);
529 op->exec("rbd", "get_children", in_bl);
530 }
531
532 int get_children_finish(bufferlist::const_iterator *it,
533 std::set<std::string>* children) {
534 try {
535 decode(*children, *it);
536 } catch (const buffer::error &err) {
537 return -EBADMSG;
538 }
539 return 0;
540 }
541
542 int get_children(librados::IoCtx *ioctx, const std::string &oid,
543 const cls::rbd::ParentImageSpec &pspec, set<string>& children)
544 {
545 librados::ObjectReadOperation op;
546 get_children_start(&op, pspec);
547
548 bufferlist out_bl;
549 int r = ioctx->operate(oid, &op, &out_bl);
550 if (r < 0) {
551 return r;
552 }
553
554 auto it = out_bl.cbegin();
555 return get_children_finish(&it, &children);
556 }
557
558 void snapshot_get_start(librados::ObjectReadOperation *op, snapid_t snap_id)
559 {
560 bufferlist bl;
561 encode(snap_id, bl);
562 op->exec("rbd", "snapshot_get", bl);
563 }
564
565 int snapshot_get_finish(bufferlist::const_iterator* it,
566 cls::rbd::SnapshotInfo* snap_info)
567 {
568 try {
569 decode(*snap_info, *it);
570 } catch (const buffer::error &err) {
571 return -EBADMSG;
572 }
573 return 0;
574 }
575
576 int snapshot_get(librados::IoCtx *ioctx, const std::string &oid,
577 snapid_t snap_id, cls::rbd::SnapshotInfo* snap_info)
578 {
579 librados::ObjectReadOperation op;
580 snapshot_get_start(&op, snap_id);
581
582 bufferlist out_bl;
583 int r = ioctx->operate(oid, &op, &out_bl);
584 if (r < 0) {
585 return r;
586 }
587
588 auto it = out_bl.cbegin();
589 return snapshot_get_finish(&it, snap_info);
590 }
591
592 void snapshot_add(librados::ObjectWriteOperation *op, snapid_t snap_id,
593 const std::string &snap_name,
594 const cls::rbd::SnapshotNamespace &snap_namespace)
595 {
596 bufferlist bl;
597 encode(snap_name, bl);
598 encode(snap_id, bl);
599 encode(snap_namespace, bl);
600 op->exec("rbd", "snapshot_add", bl);
601 }
602
603 void snapshot_remove(librados::ObjectWriteOperation *op, snapid_t snap_id)
604 {
605 bufferlist bl;
606 encode(snap_id, bl);
607 op->exec("rbd", "snapshot_remove", bl);
608 }
609
610 void snapshot_rename(librados::ObjectWriteOperation *op,
611 snapid_t src_snap_id,
612 const std::string &dst_name)
613 {
614 bufferlist bl;
615 encode(src_snap_id, bl);
616 encode(dst_name, bl);
617 op->exec("rbd", "snapshot_rename", bl);
618 }
619
620 void snapshot_trash_add(librados::ObjectWriteOperation *op,
621 snapid_t snap_id)
622 {
623 bufferlist bl;
624 encode(snap_id, bl);
625 op->exec("rbd", "snapshot_trash_add", bl);
626 }
627
628 void get_snapcontext_start(librados::ObjectReadOperation *op)
629 {
630 bufferlist bl;
631 op->exec("rbd", "get_snapcontext", bl);
632 }
633
634 int get_snapcontext_finish(bufferlist::const_iterator *it,
635 ::SnapContext *snapc)
636 {
637 try {
638 decode(*snapc, *it);
639 } catch (const buffer::error &err) {
640 return -EBADMSG;
641 }
642 if (!snapc->is_valid()) {
643 return -EBADMSG;
644 }
645 return 0;
646 }
647
648 int get_snapcontext(librados::IoCtx *ioctx, const std::string &oid,
649 ::SnapContext *snapc)
650 {
651 librados::ObjectReadOperation op;
652 get_snapcontext_start(&op);
653
654 bufferlist out_bl;
655 int r = ioctx->operate(oid, &op, &out_bl);
656 if (r < 0) {
657 return r;
658 }
659
660 auto bl_it = out_bl.cbegin();
661 return get_snapcontext_finish(&bl_it, snapc);
662 }
663
664 void get_snapshot_name_start(librados::ObjectReadOperation *op,
665 snapid_t snap_id)
666 {
667 bufferlist bl;
668 encode(snap_id, bl);
669 op->exec("rbd", "get_snapshot_name", bl);
670 }
671
672 int get_snapshot_name_finish(bufferlist::const_iterator *it,
673 std::string *name)
674 {
675 try {
676 decode(*name, *it);
677 } catch (const buffer::error &err) {
678 return -EBADMSG;
679 }
680 return 0;
681 }
682
683 int get_snapshot_name(librados::IoCtx *ioctx, const std::string &oid,
684 snapid_t snap_id, std::string *name)
685 {
686 librados::ObjectReadOperation op;
687 get_snapshot_name_start(&op, snap_id);
688
689 bufferlist out_bl;
690 int r = ioctx->operate(oid, &op, &out_bl);
691 if (r < 0) {
692 return r;
693 }
694
695 auto it = out_bl.cbegin();
696 return get_snapshot_name_finish(&it, name);
697 }
698
699 void get_snapshot_timestamp_start(librados::ObjectReadOperation *op,
700 snapid_t snap_id)
701 {
702 bufferlist bl;
703 encode(snap_id, bl);
704 op->exec("rbd", "get_snapshot_timestamp", bl);
705 }
706
707 int get_snapshot_timestamp_finish(bufferlist::const_iterator *it,
708 utime_t *timestamp)
709 {
710 try {
711 decode(*timestamp, *it);
712 } catch (const buffer::error &err) {
713 return -EBADMSG;
714 }
715 return 0;
716 }
717
718 int get_snapshot_timestamp(librados::IoCtx *ioctx, const std::string &oid,
719 snapid_t snap_id, utime_t *timestamp)
720 {
721 librados::ObjectReadOperation op;
722 get_snapshot_timestamp_start(&op, snap_id);
723
724 bufferlist out_bl;
725 int r = ioctx->operate(oid, &op, &out_bl);
726 if (r < 0) {
727 return r;
728 }
729
730 auto it = out_bl.cbegin();
731 return get_snapshot_timestamp_finish(&it, timestamp);
732 }
733
734 void old_snapshot_add(librados::ObjectWriteOperation *op,
735 snapid_t snap_id, const std::string &snap_name)
736 {
737 bufferlist bl;
738 encode(snap_name, bl);
739 encode(snap_id, bl);
740 op->exec("rbd", "snap_add", bl);
741 }
742
743 void old_snapshot_remove(librados::ObjectWriteOperation *op,
744 const std::string &snap_name)
745 {
746 bufferlist bl;
747 encode(snap_name, bl);
748 op->exec("rbd", "snap_remove", bl);
749 }
750
751 void old_snapshot_rename(librados::ObjectWriteOperation *op,
752 snapid_t src_snap_id, const std::string &dst_name)
753 {
754 bufferlist bl;
755 encode(src_snap_id, bl);
756 encode(dst_name, bl);
757 op->exec("rbd", "snap_rename", bl);
758 }
759
760 void old_snapshot_list_start(librados::ObjectReadOperation *op) {
761 bufferlist in_bl;
762 op->exec("rbd", "snap_list", in_bl);
763 }
764
765 int old_snapshot_list_finish(bufferlist::const_iterator *it,
766 std::vector<string> *names,
767 std::vector<uint64_t> *sizes,
768 ::SnapContext *snapc) {
769 try {
770 uint32_t num_snaps;
771 decode(snapc->seq, *it);
772 decode(num_snaps, *it);
773
774 names->resize(num_snaps);
775 sizes->resize(num_snaps);
776 snapc->snaps.resize(num_snaps);
777 for (uint32_t i = 0; i < num_snaps; ++i) {
778 decode(snapc->snaps[i], *it);
779 decode((*sizes)[i], *it);
780 decode((*names)[i], *it);
781 }
782 } catch (const buffer::error &err) {
783 return -EBADMSG;
784 }
785 return 0;
786 }
787
788 int old_snapshot_list(librados::IoCtx *ioctx, const std::string &oid,
789 std::vector<string> *names,
790 std::vector<uint64_t> *sizes,
791 ::SnapContext *snapc)
792 {
793 librados::ObjectReadOperation op;
794 old_snapshot_list_start(&op);
795
796 bufferlist out_bl;
797 int r = ioctx->operate(oid, &op, &out_bl);
798 if (r < 0) {
799 return r;
800 }
801
802 auto it = out_bl.cbegin();
803 return old_snapshot_list_finish(&it, names, sizes, snapc);
804 }
805
806 void get_all_features_start(librados::ObjectReadOperation *op) {
807 bufferlist in;
808 op->exec("rbd", "get_all_features", in);
809 }
810
811 int get_all_features_finish(bufferlist::const_iterator *it,
812 uint64_t *all_features) {
813 try {
814 decode(*all_features, *it);
815 } catch (const buffer::error &err) {
816 return -EBADMSG;
817 }
818 return 0;
819 }
820
821 int get_all_features(librados::IoCtx *ioctx, const std::string &oid,
822 uint64_t *all_features) {
823 librados::ObjectReadOperation op;
824 get_all_features_start(&op);
825
826 bufferlist out_bl;
827 int r = ioctx->operate(oid, &op, &out_bl);
828 if (r < 0) {
829 return r;
830 }
831
832 auto it = out_bl.cbegin();
833 return get_all_features_finish(&it, all_features);
834 }
835
836 void copyup(librados::ObjectWriteOperation *op, bufferlist data) {
837 op->exec("rbd", "copyup", data);
838 }
839
840 int copyup(librados::IoCtx *ioctx, const std::string &oid,
841 bufferlist data) {
842 librados::ObjectWriteOperation op;
843 copyup(&op, data);
844
845 return ioctx->operate(oid, &op);
846 }
847
848 void sparse_copyup(librados::ObjectWriteOperation *op,
849 const std::map<uint64_t, uint64_t> &extent_map,
850 bufferlist data) {
851 bufferlist bl;
852 encode(extent_map, bl);
853 encode(data, bl);
854 op->exec("rbd", "sparse_copyup", bl);
855 }
856
857 int sparse_copyup(librados::IoCtx *ioctx, const std::string &oid,
858 const std::map<uint64_t, uint64_t> &extent_map,
859 bufferlist data) {
860 librados::ObjectWriteOperation op;
861 sparse_copyup(&op, extent_map, data);
862
863 return ioctx->operate(oid, &op);
864 }
865
866 void get_protection_status_start(librados::ObjectReadOperation *op,
867 snapid_t snap_id)
868 {
869 bufferlist bl;
870 encode(snap_id, bl);
871 op->exec("rbd", "get_protection_status", bl);
872 }
873
874 int get_protection_status_finish(bufferlist::const_iterator *it,
875 uint8_t *protection_status)
876 {
877 try {
878 decode(*protection_status, *it);
879 } catch (const buffer::error &) {
880 return -EBADMSG;
881 }
882 return 0;
883 }
884
885 int get_protection_status(librados::IoCtx *ioctx, const std::string &oid,
886 snapid_t snap_id, uint8_t *protection_status)
887 {
888 librados::ObjectReadOperation op;
889 get_protection_status_start(&op, snap_id);
890
891 bufferlist out_bl;
892 int r = ioctx->operate(oid, &op, &out_bl);
893 if (r < 0) {
894 return r;
895 }
896
897 auto it = out_bl.cbegin();
898 return get_protection_status_finish(&it, protection_status);
899 }
900
901 int set_protection_status(librados::IoCtx *ioctx, const std::string &oid,
902 snapid_t snap_id, uint8_t protection_status)
903 {
904 // TODO remove
905 librados::ObjectWriteOperation op;
906 set_protection_status(&op, snap_id, protection_status);
907 return ioctx->operate(oid, &op);
908 }
909
910 void set_protection_status(librados::ObjectWriteOperation *op,
911 snapid_t snap_id, uint8_t protection_status)
912 {
913 bufferlist in;
914 encode(snap_id, in);
(1) Event overrun-buffer-val: |
Overrunning buffer pointed to by "protection_status" of 1 bytes by passing it to a function which accesses it at byte offset 7. [details] |
915 encode(protection_status, in);
916 op->exec("rbd", "set_protection_status", in);
917 }
918
919 int snapshot_get_limit(librados::IoCtx *ioctx, const std::string &oid,
920 uint64_t *limit)
921 {
922 bufferlist in, out;
923 int r = ioctx->exec(oid, "rbd", "snapshot_get_limit", in, out);
924
925 if (r < 0) {
926 return r;
927 }
928
929 try {
930 auto iter = out.cbegin();
931 decode(*limit, iter);
932 } catch (const buffer::error &err) {
933 return -EBADMSG;
934 }
935
936 return 0;
937 }
938
939 void snapshot_set_limit(librados::ObjectWriteOperation *op, uint64_t limit)
940 {
941 bufferlist in;
942 encode(limit, in);
943 op->exec("rbd", "snapshot_set_limit", in);
944 }
945
946 void get_stripe_unit_count_start(librados::ObjectReadOperation *op) {
947 bufferlist empty_bl;
948 op->exec("rbd", "get_stripe_unit_count", empty_bl);
949 }
950
951 int get_stripe_unit_count_finish(bufferlist::const_iterator *it,
952 uint64_t *stripe_unit,
953 uint64_t *stripe_count) {
954 ceph_assert(stripe_unit);
955 ceph_assert(stripe_count);
956
957 try {
958 decode(*stripe_unit, *it);
959 decode(*stripe_count, *it);
960 } catch (const buffer::error &err) {
961 return -EBADMSG;
962 }
963 return 0;
964 }
965
966 int get_stripe_unit_count(librados::IoCtx *ioctx, const std::string &oid,
967 uint64_t *stripe_unit, uint64_t *stripe_count)
968 {
969 librados::ObjectReadOperation op;
970 get_stripe_unit_count_start(&op);
971
972 bufferlist out_bl;
973 int r = ioctx->operate(oid, &op, &out_bl);
974 if (r < 0) {
975 return r;
976 }
977
978 auto it = out_bl.cbegin();
979 return get_stripe_unit_count_finish(&it, stripe_unit, stripe_count);
980 }
981
982 void set_stripe_unit_count(librados::ObjectWriteOperation *op,
983 uint64_t stripe_unit, uint64_t stripe_count)
984 {
985 bufferlist bl;
986 encode(stripe_unit, bl);
987 encode(stripe_count, bl);
988
989 op->exec("rbd", "set_stripe_unit_count", bl);
990 }
991
992 int set_stripe_unit_count(librados::IoCtx *ioctx, const std::string &oid,
993 uint64_t stripe_unit, uint64_t stripe_count)
994 {
995 librados::ObjectWriteOperation op;
996 set_stripe_unit_count(&op, stripe_unit, stripe_count);
997
998 return ioctx->operate(oid, &op);
999 }
1000
1001 void get_create_timestamp_start(librados::ObjectReadOperation *op) {
1002 bufferlist empty_bl;
1003 op->exec("rbd", "get_create_timestamp", empty_bl);
1004 }
1005
1006 int get_create_timestamp_finish(bufferlist::const_iterator *it,
1007 utime_t *timestamp) {
1008 ceph_assert(timestamp);
1009
1010 try {
1011 decode(*timestamp, *it);
1012 } catch (const buffer::error &err) {
1013 return -EBADMSG;
1014 }
1015 return 0;
1016 }
1017
1018 int get_create_timestamp(librados::IoCtx *ioctx, const std::string &oid,
1019 utime_t *timestamp)
1020 {
1021 librados::ObjectReadOperation op;
1022 get_create_timestamp_start(&op);
1023
1024 bufferlist out_bl;
1025 int r = ioctx->operate(oid, &op, &out_bl);
1026 if (r < 0) {
1027 return r;
1028 }
1029
1030 auto it = out_bl.cbegin();
1031 return get_create_timestamp_finish(&it, timestamp);
1032 }
1033
1034 void get_access_timestamp_start(librados::ObjectReadOperation *op) {
1035 bufferlist empty_bl;
1036 op->exec("rbd", "get_access_timestamp", empty_bl);
1037 }
1038
1039 int get_access_timestamp_finish(bufferlist::const_iterator *it,
1040 utime_t *timestamp) {
1041 ceph_assert(timestamp);
1042
1043 try {
1044 decode(*timestamp, *it);
1045 } catch (const buffer::error &err) {
1046 return -EBADMSG;
1047 }
1048 return 0;
1049 }
1050
1051 int get_access_timestamp(librados::IoCtx *ioctx, const std::string &oid,
1052 utime_t *timestamp)
1053 {
1054 librados::ObjectReadOperation op;
1055 get_access_timestamp_start(&op);
1056
1057 bufferlist out_bl;
1058 int r = ioctx->operate(oid, &op, &out_bl);
1059 if (r < 0) {
1060 return r;
1061 }
1062
1063 auto it = out_bl.cbegin();
1064 return get_access_timestamp_finish(&it, timestamp);
1065 }
1066
1067 void set_access_timestamp(librados::ObjectWriteOperation *op)
1068 {
1069 bufferlist empty_bl;
1070 op->exec("rbd","set_access_timestamp",empty_bl);
1071 }
1072
1073 int set_access_timestamp(librados::IoCtx *ioctx, const std::string &oid)
1074 {
1075 librados::ObjectWriteOperation op;
1076 set_access_timestamp(&op);
1077 return ioctx->operate(oid, &op);
1078 }
1079
1080 void get_modify_timestamp_start(librados::ObjectReadOperation *op) {
1081 bufferlist empty_bl;
1082 op->exec("rbd", "get_modify_timestamp", empty_bl);
1083 }
1084
1085 int get_modify_timestamp_finish(bufferlist::const_iterator *it,
1086 utime_t *timestamp) {
1087 ceph_assert(timestamp);
1088
1089 try {
1090 decode(*timestamp, *it);
1091 } catch (const buffer::error &err) {
1092 return -EBADMSG;
1093 }
1094 return 0;
1095 }
1096
1097 int get_modify_timestamp(librados::IoCtx *ioctx, const std::string &oid,
1098 utime_t *timestamp)
1099 {
1100 librados::ObjectReadOperation op;
1101 get_modify_timestamp_start(&op);
1102
1103 bufferlist out_bl;
1104 int r = ioctx->operate(oid, &op, &out_bl);
1105 if (r < 0) {
1106 return r;
1107 }
1108
1109 auto it = out_bl.cbegin();
1110 return get_modify_timestamp_finish(&it, timestamp);
1111 }
1112
1113 void set_modify_timestamp(librados::ObjectWriteOperation *op)
1114 {
1115 bufferlist empty_bl;
1116 op->exec("rbd","set_modify_timestamp",empty_bl);
1117 }
1118
1119 int set_modify_timestamp(librados::IoCtx *ioctx, const std::string &oid)
1120 {
1121 librados::ObjectWriteOperation op;
1122 set_modify_timestamp(&op);
1123 return ioctx->operate(oid, &op);
1124 }
1125
1126
1127 /************************ rbd_id object methods ************************/
1128
1129 void get_id_start(librados::ObjectReadOperation *op) {
1130 bufferlist empty_bl;
1131 op->exec("rbd", "get_id", empty_bl);
1132 }
1133
1134 int get_id_finish(bufferlist::const_iterator *it, std::string *id) {
1135 try {
1136 decode(*id, *it);
1137 } catch (const buffer::error &err) {
1138 return -EBADMSG;
1139 }
1140 return 0;
1141 }
1142
1143 int get_id(librados::IoCtx *ioctx, const std::string &oid, std::string *id)
1144 {
1145 librados::ObjectReadOperation op;
1146 get_id_start(&op);
1147
1148 bufferlist out_bl;
1149 int r = ioctx->operate(oid, &op, &out_bl);
1150 if (r < 0) {
1151 return r;
1152 }
1153
1154 auto it = out_bl.cbegin();
1155 return get_id_finish(&it, id);
1156 }
1157
1158 void set_id(librados::ObjectWriteOperation *op, const std::string &id)
1159 {
1160 bufferlist bl;
1161 encode(id, bl);
1162 op->exec("rbd", "set_id", bl);
1163 }
1164
1165 int set_id(librados::IoCtx *ioctx, const std::string &oid, const std::string &id)
1166 {
1167 librados::ObjectWriteOperation op;
1168 set_id(&op, id);
1169
1170 return ioctx->operate(oid, &op);
1171 }
1172
1173 /******************** rbd_directory object methods ********************/
1174
1175 void dir_get_id_start(librados::ObjectReadOperation *op,
1176 const std::string &image_name) {
1177 bufferlist bl;
1178 encode(image_name, bl);
1179
1180 op->exec("rbd", "dir_get_id", bl);
1181 }
1182
1183 int dir_get_id_finish(bufferlist::const_iterator *iter, std::string *image_id) {
1184 try {
1185 decode(*image_id, *iter);
1186 } catch (const buffer::error &err) {
1187 return -EBADMSG;
1188 }
1189
1190 return 0;
1191 }
1192
1193 int dir_get_id(librados::IoCtx *ioctx, const std::string &oid,
1194 const std::string &name, std::string *id) {
1195 librados::ObjectReadOperation op;
1196 dir_get_id_start(&op, name);
1197
1198 bufferlist out_bl;
1199 int r = ioctx->operate(oid, &op, &out_bl);
1200 if (r < 0) {
1201 return r;
1202 }
1203
1204 auto iter = out_bl.cbegin();
1205 return dir_get_id_finish(&iter, id);
1206 }
1207
1208 void dir_get_name_start(librados::ObjectReadOperation *op,
1209 const std::string &id) {
1210 bufferlist in_bl;
1211 encode(id, in_bl);
1212 op->exec("rbd", "dir_get_name", in_bl);
1213 }
1214
1215 int dir_get_name_finish(bufferlist::const_iterator *it, std::string *name) {
1216 try {
1217 decode(*name, *it);
1218 } catch (const buffer::error &err) {
1219 return -EBADMSG;
1220 }
1221 return 0;
1222 }
1223
1224 int dir_get_name(librados::IoCtx *ioctx, const std::string &oid,
1225 const std::string &id, std::string *name) {
1226 librados::ObjectReadOperation op;
1227 dir_get_name_start(&op, id);
1228
1229 bufferlist out_bl;
1230 int r = ioctx->operate(oid, &op, &out_bl);
1231 if (r < 0) {
1232 return r;
1233 }
1234
1235 auto it = out_bl.cbegin();
1236 return dir_get_name_finish(&it, name);
1237 }
1238
1239 void dir_list_start(librados::ObjectReadOperation *op,
1240 const std::string &start, uint64_t max_return)
1241 {
1242 bufferlist in_bl;
1243 encode(start, in_bl);
1244 encode(max_return, in_bl);
1245
1246 op->exec("rbd", "dir_list", in_bl);
1247 }
1248
1249 int dir_list_finish(bufferlist::const_iterator *it, map<string, string> *images)
1250 {
1251 try {
1252 decode(*images, *it);
1253 } catch (const buffer::error &err) {
1254 return -EBADMSG;
1255 }
1256 return 0;
1257 }
1258
1259 int dir_list(librados::IoCtx *ioctx, const std::string &oid,
1260 const std::string &start, uint64_t max_return,
1261 map<string, string> *images)
1262 {
1263 librados::ObjectReadOperation op;
1264 dir_list_start(&op, start, max_return);
1265
1266 bufferlist out_bl;
1267 int r = ioctx->operate(oid, &op, &out_bl);
1268 if (r < 0) {
1269 return r;
1270 }
1271
1272 auto iter = out_bl.cbegin();
1273 return dir_list_finish(&iter, images);
1274 }
1275
1276 void dir_add_image(librados::ObjectWriteOperation *op,
1277 const std::string &name, const std::string &id)
1278 {
1279 bufferlist bl;
1280 encode(name, bl);
1281 encode(id, bl);
1282 op->exec("rbd", "dir_add_image", bl);
1283 }
1284
1285 int dir_add_image(librados::IoCtx *ioctx, const std::string &oid,
1286 const std::string &name, const std::string &id)
1287 {
1288 librados::ObjectWriteOperation op;
1289 dir_add_image(&op, name, id);
1290
1291 return ioctx->operate(oid, &op);
1292 }
1293
1294 int dir_remove_image(librados::IoCtx *ioctx, const std::string &oid,
1295 const std::string &name, const std::string &id)
1296 {
1297 librados::ObjectWriteOperation op;
1298 dir_remove_image(&op, name, id);
1299
1300 return ioctx->operate(oid, &op);
1301 }
1302
1303 void dir_state_assert(librados::ObjectOperation *op,
1304 cls::rbd::DirectoryState directory_state)
1305 {
1306 bufferlist bl;
1307 encode(directory_state, bl);
1308 op->exec("rbd", "dir_state_assert", bl);
1309 }
1310
1311 int dir_state_assert(librados::IoCtx *ioctx, const std::string &oid,
1312 cls::rbd::DirectoryState directory_state)
1313 {
1314 librados::ObjectWriteOperation op;
1315 dir_state_assert(&op, directory_state);
1316
1317 return ioctx->operate(oid, &op);
1318 }
1319
1320 void dir_state_set(librados::ObjectWriteOperation *op,
1321 cls::rbd::DirectoryState directory_state)
1322 {
1323 bufferlist bl;
1324 encode(directory_state, bl);
1325 op->exec("rbd", "dir_state_set", bl);
1326 }
1327
1328 int dir_state_set(librados::IoCtx *ioctx, const std::string &oid,
1329 cls::rbd::DirectoryState directory_state)
1330 {
1331 librados::ObjectWriteOperation op;
1332 dir_state_set(&op, directory_state);
1333
1334 return ioctx->operate(oid, &op);
1335 }
1336
1337 void dir_remove_image(librados::ObjectWriteOperation *op,
1338 const std::string &name, const std::string &id)
1339 {
1340 bufferlist bl;
1341 encode(name, bl);
1342 encode(id, bl);
1343
1344 op->exec("rbd", "dir_remove_image", bl);
1345 }
1346
1347 void dir_rename_image(librados::ObjectWriteOperation *op,
1348 const std::string &src, const std::string &dest,
1349 const std::string &id)
1350 {
1351 bufferlist in;
1352 encode(src, in);
1353 encode(dest, in);
1354 encode(id, in);
1355 op->exec("rbd", "dir_rename_image", in);
1356 }
1357
1358 void object_map_load_start(librados::ObjectReadOperation *op) {
1359 bufferlist in_bl;
1360 op->exec("rbd", "object_map_load", in_bl);
1361 }
1362
1363 int object_map_load_finish(bufferlist::const_iterator *it,
1364 ceph::BitVector<2> *object_map) {
1365 try {
1366 decode(*object_map, *it);
1367 } catch (const buffer::error &err) {
1368 return -EBADMSG;
1369 }
1370 return 0;
1371 }
1372
1373 int object_map_load(librados::IoCtx *ioctx, const std::string &oid,
1374 ceph::BitVector<2> *object_map)
1375 {
1376 librados::ObjectReadOperation op;
1377 object_map_load_start(&op);
1378
1379 bufferlist out_bl;
1380 int r = ioctx->operate(oid, &op, &out_bl);
1381 if (r < 0) {
1382 return r;
1383 }
1384
1385 auto it = out_bl.cbegin();
1386 return object_map_load_finish(&it, object_map);
1387 }
1388
1389 void object_map_save(librados::ObjectWriteOperation *rados_op,
1390 const ceph::BitVector<2> &object_map)
1391 {
1392 ceph::BitVector<2> object_map_copy(object_map);
1393 object_map_copy.set_crc_enabled(false);
1394
1395 bufferlist in;
1396 encode(object_map_copy, in);
1397 rados_op->exec("rbd", "object_map_save", in);
1398 }
1399
1400 void object_map_resize(librados::ObjectWriteOperation *rados_op,
1401 uint64_t object_count, uint8_t default_state)
1402 {
1403 bufferlist in;
1404 encode(object_count, in);
1405 encode(default_state, in);
1406 rados_op->exec("rbd", "object_map_resize", in);
1407 }
1408
1409 void object_map_update(librados::ObjectWriteOperation *rados_op,
1410 uint64_t start_object_no, uint64_t end_object_no,
1411 uint8_t new_object_state,
1412 const boost::optional<uint8_t> ¤t_object_state)
1413 {
1414 bufferlist in;
1415 encode(start_object_no, in);
1416 encode(end_object_no, in);
1417 encode(new_object_state, in);
1418 encode(current_object_state, in);
1419 rados_op->exec("rbd", "object_map_update", in);
1420 }
1421
1422 void object_map_snap_add(librados::ObjectWriteOperation *rados_op)
1423 {
1424 bufferlist in;
1425 rados_op->exec("rbd", "object_map_snap_add", in);
1426 }
1427
1428 void object_map_snap_remove(librados::ObjectWriteOperation *rados_op,
1429 const ceph::BitVector<2> &object_map)
1430 {
1431 ceph::BitVector<2> object_map_copy(object_map);
1432 object_map_copy.set_crc_enabled(false);
1433
1434 bufferlist in;
1435 encode(object_map_copy, in);
1436 rados_op->exec("rbd", "object_map_snap_remove", in);
1437 }
1438
1439 void metadata_set(librados::ObjectWriteOperation *op,
1440 const map<string, bufferlist> &data)
1441 {
1442 bufferlist bl;
1443 encode(data, bl);
1444
1445 op->exec("rbd", "metadata_set", bl);
1446 }
1447
1448 int metadata_set(librados::IoCtx *ioctx, const std::string &oid,
1449 const map<string, bufferlist> &data)
1450 {
1451 librados::ObjectWriteOperation op;
1452 metadata_set(&op, data);
1453
1454 return ioctx->operate(oid, &op);
1455 }
1456
1457 void metadata_remove(librados::ObjectWriteOperation *op,
1458 const std::string &key)
1459 {
1460 bufferlist bl;
1461 encode(key, bl);
1462
1463 op->exec("rbd", "metadata_remove", bl);
1464 }
1465
1466 int metadata_remove(librados::IoCtx *ioctx, const std::string &oid,
1467 const std::string &key)
1468 {
1469 librados::ObjectWriteOperation op;
1470 metadata_remove(&op, key);
1471
1472 return ioctx->operate(oid, &op);
1473 }
1474
1475 int metadata_list(librados::IoCtx *ioctx, const std::string &oid,
1476 const std::string &start, uint64_t max_return,
1477 map<string, bufferlist> *pairs)
1478 {
1479 librados::ObjectReadOperation op;
1480 metadata_list_start(&op, start, max_return);
1481
1482 bufferlist out_bl;
1483 int r = ioctx->operate(oid, &op, &out_bl);
1484 if (r < 0) {
1485 return r;
1486 }
1487
1488 auto it = out_bl.cbegin();
1489 return metadata_list_finish(&it, pairs);
1490 }
1491
1492 void metadata_list_start(librados::ObjectReadOperation *op,
1493 const std::string &start, uint64_t max_return)
1494 {
1495 bufferlist in_bl;
1496 encode(start, in_bl);
1497 encode(max_return, in_bl);
1498 op->exec("rbd", "metadata_list", in_bl);
1499 }
1500
1501 int metadata_list_finish(bufferlist::const_iterator *it,
1502 std::map<std::string, bufferlist> *pairs)
1503 {
1504 ceph_assert(pairs);
1505 try {
1506 decode(*pairs, *it);
1507 } catch (const buffer::error &err) {
1508 return -EBADMSG;
1509 }
1510 return 0;
1511 }
1512
1513 int metadata_get(librados::IoCtx *ioctx, const std::string &oid,
1514 const std::string &key, string *s)
1515 {
1516 ceph_assert(s);
1517 bufferlist in, out;
1518 encode(key, in);
1519 int r = ioctx->exec(oid, "rbd", "metadata_get", in, out);
1520 if (r < 0)
1521 return r;
1522
1523 auto iter = out.cbegin();
1524 try {
1525 decode(*s, iter);
1526 } catch (const buffer::error &err) {
1527 return -EBADMSG;
1528 }
1529
1530 return 0;
1531 }
1532
1533 void child_attach(librados::ObjectWriteOperation *op, snapid_t snap_id,
1534 const cls::rbd::ChildImageSpec& child_image)
1535 {
1536 bufferlist bl;
1537 encode(snap_id, bl);
1538 encode(child_image, bl);
1539 op->exec("rbd", "child_attach", bl);
1540 }
1541
1542 int child_attach(librados::IoCtx *ioctx, const std::string &oid,
1543 snapid_t snap_id,
1544 const cls::rbd::ChildImageSpec& child_image)
1545 {
1546 librados::ObjectWriteOperation op;
1547 child_attach(&op, snap_id, child_image);
1548
1549 int r = ioctx->operate(oid, &op);
1550 if (r < 0) {
1551 return r;
1552 }
1553 return 0;
1554 }
1555
1556 void child_detach(librados::ObjectWriteOperation *op, snapid_t snap_id,
1557 const cls::rbd::ChildImageSpec& child_image)
1558 {
1559 bufferlist bl;
1560 encode(snap_id, bl);
1561 encode(child_image, bl);
1562 op->exec("rbd", "child_detach", bl);
1563 }
1564
1565 int child_detach(librados::IoCtx *ioctx, const std::string &oid,
1566 snapid_t snap_id,
1567 const cls::rbd::ChildImageSpec& child_image)
1568 {
1569 librados::ObjectWriteOperation op;
1570 child_detach(&op, snap_id, child_image);
1571
1572 int r = ioctx->operate(oid, &op);
1573 if (r < 0) {
1574 return r;
1575 }
1576 return 0;
1577 }
1578
1579 void children_list_start(librados::ObjectReadOperation *op,
1580 snapid_t snap_id)
1581 {
1582 bufferlist bl;
1583 encode(snap_id, bl);
1584 op->exec("rbd", "children_list", bl);
1585 }
1586
1587 int children_list_finish(bufferlist::const_iterator *it,
1588 cls::rbd::ChildImageSpecs *child_images)
1589 {
1590 child_images->clear();
1591 try {
1592 decode(*child_images, *it);
1593 } catch (const buffer::error &err) {
1594 return -EBADMSG;
1595 }
1596 return 0;
1597 }
1598
1599 int children_list(librados::IoCtx *ioctx, const std::string &oid,
1600 snapid_t snap_id,
1601 cls::rbd::ChildImageSpecs *child_images)
1602 {
1603 librados::ObjectReadOperation op;
1604 children_list_start(&op, snap_id);
1605
1606 bufferlist out_bl;
1607 int r = ioctx->operate(oid, &op, &out_bl);
1608 if (r < 0) {
1609 return r;
1610 }
1611
1612 auto it = out_bl.cbegin();
1613 r = children_list_finish(&it, child_images);
1614 if (r < 0) {
1615 return r;
1616 }
1617 return 0;
1618 }
1619
1620 int migration_set(librados::IoCtx *ioctx, const std::string &oid,
1621 const cls::rbd::MigrationSpec &migration_spec) {
1622 librados::ObjectWriteOperation op;
1623 migration_set(&op, migration_spec);
1624 return ioctx->operate(oid, &op);
1625 }
1626
1627 void migration_set(librados::ObjectWriteOperation *op,
1628 const cls::rbd::MigrationSpec &migration_spec) {
1629 bufferlist bl;
1630 encode(migration_spec, bl);
1631 op->exec("rbd", "migration_set", bl);
1632 }
1633
1634 int migration_set_state(librados::IoCtx *ioctx, const std::string &oid,
1635 cls::rbd::MigrationState state,
1636 const std::string &description) {
1637 librados::ObjectWriteOperation op;
1638 migration_set_state(&op, state, description);
1639 return ioctx->operate(oid, &op);
1640 }
1641
1642 void migration_set_state(librados::ObjectWriteOperation *op,
1643 cls::rbd::MigrationState state,
1644 const std::string &description) {
1645 bufferlist bl;
1646 encode(state, bl);
1647 encode(description, bl);
1648 op->exec("rbd", "migration_set_state", bl);
1649 }
1650
1651 void migration_get_start(librados::ObjectReadOperation *op) {
1652 bufferlist bl;
1653 op->exec("rbd", "migration_get", bl);
1654 }
1655
1656 int migration_get_finish(bufferlist::const_iterator *it,
1657 cls::rbd::MigrationSpec *migration_spec) {
1658 try {
1659 decode(*migration_spec, *it);
1660 } catch (const buffer::error &err) {
1661 return -EBADMSG;
1662 }
1663 return 0;
1664 }
1665
1666 int migration_get(librados::IoCtx *ioctx, const std::string &oid,
1667 cls::rbd::MigrationSpec *migration_spec) {
1668 librados::ObjectReadOperation op;
1669 migration_get_start(&op);
1670
1671 bufferlist out_bl;
1672 int r = ioctx->operate(oid, &op, &out_bl);
1673 if (r < 0) {
1674 return r;
1675 }
1676
1677 auto iter = out_bl.cbegin();
1678 r = migration_get_finish(&iter, migration_spec);
1679 if (r < 0) {
1680 return r;
1681 }
1682 return 0;
1683 }
1684
1685 int migration_remove(librados::IoCtx *ioctx, const std::string &oid) {
1686 librados::ObjectWriteOperation op;
1687 migration_remove(&op);
1688 return ioctx->operate(oid, &op);
1689 }
1690
1691 void migration_remove(librados::ObjectWriteOperation *op) {
1692 bufferlist bl;
1693 op->exec("rbd", "migration_remove", bl);
1694 }
1695
1696 int assert_snapc_seq(librados::IoCtx *ioctx, const std::string &oid,
1697 uint64_t snapc_seq,
1698 cls::rbd::AssertSnapcSeqState state) {
1699 librados::ObjectWriteOperation op;
1700 assert_snapc_seq(&op, snapc_seq, state);
1701 return ioctx->operate(oid, &op);
1702 }
1703
1704 void assert_snapc_seq(librados::ObjectWriteOperation *op,
1705 uint64_t snapc_seq,
1706 cls::rbd::AssertSnapcSeqState state) {
1707 bufferlist bl;
1708 encode(snapc_seq, bl);
1709 encode(state, bl);
1710 op->exec("rbd", "assert_snapc_seq", bl);
1711 }
1712
1713 void mirror_uuid_get_start(librados::ObjectReadOperation *op) {
1714 bufferlist bl;
1715 op->exec("rbd", "mirror_uuid_get", bl);
1716 }
1717
1718 int mirror_uuid_get_finish(bufferlist::const_iterator *it,
1719 std::string *uuid) {
1720 try {
1721 decode(*uuid, *it);
1722 } catch (const buffer::error &err) {
1723 return -EBADMSG;
1724 }
1725 return 0;
1726 }
1727
1728 int mirror_uuid_get(librados::IoCtx *ioctx, std::string *uuid) {
1729 librados::ObjectReadOperation op;
1730 mirror_uuid_get_start(&op);
1731
1732 bufferlist out_bl;
1733 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
1734 if (r < 0) {
1735 return r;
1736 }
1737
1738 auto it = out_bl.cbegin();
1739 r = mirror_uuid_get_finish(&it, uuid);
1740 if (r < 0) {
1741 return r;
1742 }
1743 return 0;
1744 }
1745
1746 int mirror_uuid_set(librados::IoCtx *ioctx, const std::string &uuid) {
1747 bufferlist in_bl;
1748 encode(uuid, in_bl);
1749
1750 bufferlist out_bl;
1751 int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_uuid_set", in_bl,
1752 out_bl);
1753 if (r < 0) {
1754 return r;
1755 }
1756 return 0;
1757 }
1758
1759 void mirror_mode_get_start(librados::ObjectReadOperation *op) {
1760 bufferlist bl;
1761 op->exec("rbd", "mirror_mode_get", bl);
1762 }
1763
1764 int mirror_mode_get_finish(bufferlist::const_iterator *it,
1765 cls::rbd::MirrorMode *mirror_mode) {
1766 try {
1767 uint32_t mirror_mode_decode;
1768 decode(mirror_mode_decode, *it);
1769 *mirror_mode = static_cast<cls::rbd::MirrorMode>(mirror_mode_decode);
1770 } catch (const buffer::error &err) {
1771 return -EBADMSG;
1772 }
1773
1774 return 0;
1775 }
1776
1777 int mirror_mode_get(librados::IoCtx *ioctx,
1778 cls::rbd::MirrorMode *mirror_mode) {
1779 librados::ObjectReadOperation op;
1780 mirror_mode_get_start(&op);
1781
1782 bufferlist out_bl;
1783 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
1784 if (r == -ENOENT) {
1785 *mirror_mode = cls::rbd::MIRROR_MODE_DISABLED;
1786 return 0;
1787 } else if (r < 0) {
1788 return r;
1789 }
1790
1791 auto it = out_bl.cbegin();
1792 r = mirror_mode_get_finish(&it, mirror_mode);
1793 if (r < 0) {
1794 return r;
1795 }
1796 return 0;
1797 }
1798
1799 int mirror_mode_set(librados::IoCtx *ioctx,
1800 cls::rbd::MirrorMode mirror_mode) {
1801 bufferlist in_bl;
1802 encode(static_cast<uint32_t>(mirror_mode), in_bl);
1803
1804 bufferlist out_bl;
1805 int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_mode_set", in_bl,
1806 out_bl);
1807 if (r < 0) {
1808 return r;
1809 }
1810 return 0;
1811 }
1812
1813 int mirror_peer_list(librados::IoCtx *ioctx,
1814 std::vector<cls::rbd::MirrorPeer> *peers) {
1815 bufferlist in_bl;
1816 bufferlist out_bl;
1817 int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_peer_list", in_bl,
1818 out_bl);
1819 if (r < 0) {
1820 return r;
1821 }
1822
1823 peers->clear();
1824 try {
1825 auto bl_it = out_bl.cbegin();
1826 decode(*peers, bl_it);
1827 } catch (const buffer::error &err) {
1828 return -EBADMSG;
1829 }
1830 return 0;
1831 }
1832
1833 int mirror_peer_add(librados::IoCtx *ioctx, const std::string &uuid,
1834 const std::string &cluster_name,
1835 const std::string &client_name, int64_t pool_id) {
1836 cls::rbd::MirrorPeer peer(uuid, cluster_name, client_name, pool_id);
1837 bufferlist in_bl;
1838 encode(peer, in_bl);
1839
1840 bufferlist out_bl;
1841 int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_peer_add", in_bl,
1842 out_bl);
1843 if (r < 0) {
1844 return r;
1845 }
1846 return 0;
1847 }
1848
1849 int mirror_peer_remove(librados::IoCtx *ioctx,
1850 const std::string &uuid) {
1851 bufferlist in_bl;
1852 encode(uuid, in_bl);
1853
1854 bufferlist out_bl;
1855 int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_peer_remove", in_bl,
1856 out_bl);
1857 if (r < 0) {
1858 return r;
1859 }
1860 return 0;
1861 }
1862
1863 int mirror_peer_set_client(librados::IoCtx *ioctx,
1864 const std::string &uuid,
1865 const std::string &client_name) {
1866 bufferlist in_bl;
1867 encode(uuid, in_bl);
1868 encode(client_name, in_bl);
1869
1870 bufferlist out_bl;
1871 int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_peer_set_client",
1872 in_bl, out_bl);
1873 if (r < 0) {
1874 return r;
1875 }
1876 return 0;
1877 }
1878
1879 int mirror_peer_set_cluster(librados::IoCtx *ioctx,
1880 const std::string &uuid,
1881 const std::string &cluster_name) {
1882 bufferlist in_bl;
1883 encode(uuid, in_bl);
1884 encode(cluster_name, in_bl);
1885
1886 bufferlist out_bl;
1887 int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_peer_set_cluster",
1888 in_bl, out_bl);
1889 if (r < 0) {
1890 return r;
1891 }
1892 return 0;
1893 }
1894
1895 void mirror_image_list_start(librados::ObjectReadOperation *op,
1896 const std::string &start, uint64_t max_return)
1897 {
1898 bufferlist in_bl;
1899 encode(start, in_bl);
1900 encode(max_return, in_bl);
1901 op->exec("rbd", "mirror_image_list", in_bl);
1902 }
1903
1904 int mirror_image_list_finish(bufferlist::const_iterator *it,
1905 std::map<string, string> *mirror_image_ids)
1906 {
1907 try {
1908 decode(*mirror_image_ids, *it);
1909 } catch (const buffer::error &err) {
1910 return -EBADMSG;
1911 }
1912 return 0;
1913 }
1914
1915 int mirror_image_list(librados::IoCtx *ioctx,
1916 const std::string &start, uint64_t max_return,
1917 std::map<std::string, std::string> *mirror_image_ids) {
1918 librados::ObjectReadOperation op;
1919 mirror_image_list_start(&op, start, max_return);
1920
1921 bufferlist out_bl;
1922 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
1923 if (r < 0) {
1924 return r;
1925 }
1926
1927 auto bl_it = out_bl.cbegin();
1928 return mirror_image_list_finish(&bl_it, mirror_image_ids);
1929 }
1930
1931 void mirror_image_get_image_id_start(librados::ObjectReadOperation *op,
1932 const std::string &global_image_id) {
1933 bufferlist in_bl;
1934 encode(global_image_id, in_bl);
1935 op->exec( "rbd", "mirror_image_get_image_id", in_bl);
1936 }
1937
1938 int mirror_image_get_image_id_finish(bufferlist::const_iterator *it,
1939 std::string *image_id) {
1940 try {
1941 decode(*image_id, *it);
1942 } catch (const buffer::error &err) {
1943 return -EBADMSG;
1944 }
1945 return 0;
1946 }
1947
1948 int mirror_image_get_image_id(librados::IoCtx *ioctx,
1949 const std::string &global_image_id,
1950 std::string *image_id) {
1951 librados::ObjectReadOperation op;
1952 mirror_image_get_image_id_start(&op, global_image_id);
1953
1954 bufferlist out_bl;
1955 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
1956 if (r < 0) {
1957 return r;
1958 }
1959
1960 auto it = out_bl.cbegin();
1961 return mirror_image_get_image_id_finish(&it, image_id);
1962 }
1963
1964 int mirror_image_get(librados::IoCtx *ioctx, const std::string &image_id,
1965 cls::rbd::MirrorImage *mirror_image) {
1966 librados::ObjectReadOperation op;
1967 mirror_image_get_start(&op, image_id);
1968
1969 bufferlist out_bl;
1970 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
1971 if (r < 0) {
1972 return r;
1973 }
1974
1975 auto iter = out_bl.cbegin();
1976 r = mirror_image_get_finish(&iter, mirror_image);
1977 if (r < 0) {
1978 return r;
1979 }
1980 return 0;
1981 }
1982
1983 void mirror_image_get_start(librados::ObjectReadOperation *op,
1984 const std::string &image_id) {
1985 bufferlist in_bl;
1986 encode(image_id, in_bl);
1987
1988 op->exec("rbd", "mirror_image_get", in_bl);
1989 }
1990
1991 int mirror_image_get_finish(bufferlist::const_iterator *iter,
1992 cls::rbd::MirrorImage *mirror_image) {
1993 try {
1994 decode(*mirror_image, *iter);
1995 } catch (const buffer::error &err) {
1996 return -EBADMSG;
1997 }
1998 return 0;
1999 }
2000
2001 void mirror_image_set(librados::ObjectWriteOperation *op,
2002 const std::string &image_id,
2003 const cls::rbd::MirrorImage &mirror_image) {
2004 bufferlist bl;
2005 encode(image_id, bl);
2006 encode(mirror_image, bl);
2007
2008 op->exec("rbd", "mirror_image_set", bl);
2009 }
2010
2011 int mirror_image_set(librados::IoCtx *ioctx, const std::string &image_id,
2012 const cls::rbd::MirrorImage &mirror_image) {
2013 librados::ObjectWriteOperation op;
2014 mirror_image_set(&op, image_id, mirror_image);
2015
2016 int r = ioctx->operate(RBD_MIRRORING, &op);
2017 if (r < 0) {
2018 return r;
2019 }
2020 return 0;
2021 }
2022
2023 void mirror_image_remove(librados::ObjectWriteOperation *op,
2024 const std::string &image_id) {
2025 bufferlist bl;
2026 encode(image_id, bl);
2027
2028 op->exec("rbd", "mirror_image_remove", bl);
2029 }
2030
2031 int mirror_image_remove(librados::IoCtx *ioctx, const std::string &image_id) {
2032 librados::ObjectWriteOperation op;
2033 mirror_image_remove(&op, image_id);
2034
2035 int r = ioctx->operate(RBD_MIRRORING, &op);
2036 if (r < 0) {
2037 return r;
2038 }
2039 return 0;
2040 }
2041
2042 int mirror_image_status_set(librados::IoCtx *ioctx,
2043 const std::string &global_image_id,
2044 const cls::rbd::MirrorImageStatus &status) {
2045 librados::ObjectWriteOperation op;
2046 mirror_image_status_set(&op, global_image_id, status);
2047 return ioctx->operate(RBD_MIRRORING, &op);
2048 }
2049
2050 void mirror_image_status_set(librados::ObjectWriteOperation *op,
2051 const std::string &global_image_id,
2052 const cls::rbd::MirrorImageStatus &status) {
2053 bufferlist bl;
2054 encode(global_image_id, bl);
2055 encode(status, bl);
2056 op->exec("rbd", "mirror_image_status_set", bl);
2057 }
2058
2059 int mirror_image_status_remove(librados::IoCtx *ioctx,
2060 const std::string &global_image_id) {
2061 librados::ObjectWriteOperation op;
2062 mirror_image_status_remove(&op, global_image_id);
2063 return ioctx->operate(RBD_MIRRORING, &op);
2064 }
2065
2066 void mirror_image_status_remove(librados::ObjectWriteOperation *op,
2067 const std::string &global_image_id) {
2068 bufferlist bl;
2069 encode(global_image_id, bl);
2070 op->exec("rbd", "mirror_image_status_remove", bl);
2071 }
2072
2073 int mirror_image_status_get(librados::IoCtx *ioctx,
2074 const std::string &global_image_id,
2075 cls::rbd::MirrorImageStatus *status) {
2076 librados::ObjectReadOperation op;
2077 mirror_image_status_get_start(&op, global_image_id);
2078
2079 bufferlist out_bl;
2080 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2081 if (r < 0) {
2082 return r;
2083 }
2084
2085 auto iter = out_bl.cbegin();
2086 r = mirror_image_status_get_finish(&iter, status);
2087 if (r < 0) {
2088 return r;
2089 }
2090 return 0;
2091 }
2092
2093 void mirror_image_status_get_start(librados::ObjectReadOperation *op,
2094 const std::string &global_image_id) {
2095 bufferlist bl;
2096 encode(global_image_id, bl);
2097 op->exec("rbd", "mirror_image_status_get", bl);
2098 }
2099
2100 int mirror_image_status_get_finish(bufferlist::const_iterator *iter,
2101 cls::rbd::MirrorImageStatus *status) {
2102 try {
2103 decode(*status, *iter);
2104 } catch (const buffer::error &err) {
2105 return -EBADMSG;
2106 }
2107 return 0;
2108 }
2109
2110 int mirror_image_status_list(librados::IoCtx *ioctx,
2111 const std::string &start, uint64_t max_return,
2112 std::map<std::string, cls::rbd::MirrorImage> *images,
2113 std::map<std::string, cls::rbd::MirrorImageStatus> *statuses) {
2114 librados::ObjectReadOperation op;
2115 mirror_image_status_list_start(&op, start, max_return);
2116
2117 bufferlist out_bl;
2118 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2119 if (r < 0) {
2120 return r;
2121 }
2122
2123 auto iter = out_bl.cbegin();
2124 r = mirror_image_status_list_finish(&iter, images, statuses);
2125 if (r < 0) {
2126 return r;
2127 }
2128 return 0;
2129 }
2130
2131 void mirror_image_status_list_start(librados::ObjectReadOperation *op,
2132 const std::string &start,
2133 uint64_t max_return) {
2134 bufferlist bl;
2135 encode(start, bl);
2136 encode(max_return, bl);
2137 op->exec("rbd", "mirror_image_status_list", bl);
2138 }
2139
2140 int mirror_image_status_list_finish(bufferlist::const_iterator *iter,
2141 std::map<std::string, cls::rbd::MirrorImage> *images,
2142 std::map<std::string, cls::rbd::MirrorImageStatus> *statuses) {
2143 images->clear();
2144 statuses->clear();
2145 try {
2146 decode(*images, *iter);
2147 decode(*statuses, *iter);
2148 } catch (const buffer::error &err) {
2149 return -EBADMSG;
2150 }
2151 return 0;
2152 }
2153
2154 int mirror_image_status_get_summary(librados::IoCtx *ioctx,
2155 std::map<cls::rbd::MirrorImageStatusState, int> *states) {
2156 librados::ObjectReadOperation op;
2157 mirror_image_status_get_summary_start(&op);
2158
2159 bufferlist out_bl;
2160 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2161 if (r < 0) {
2162 return r;
2163 }
2164
2165 auto iter = out_bl.cbegin();
2166 r = mirror_image_status_get_summary_finish(&iter, states);
2167 if (r < 0) {
2168 return r;
2169 }
2170 return 0;
2171 }
2172
2173 void mirror_image_status_get_summary_start(librados::ObjectReadOperation *op) {
2174 bufferlist bl;
2175 op->exec("rbd", "mirror_image_status_get_summary", bl);
2176 }
2177
2178 int mirror_image_status_get_summary_finish(bufferlist::const_iterator *iter,
2179 std::map<cls::rbd::MirrorImageStatusState, int> *states) {
2180 try {
2181 decode(*states, *iter);
2182 } catch (const buffer::error &err) {
2183 return -EBADMSG;
2184 }
2185 return 0;
2186 }
2187
2188 int mirror_image_status_remove_down(librados::IoCtx *ioctx) {
2189 librados::ObjectWriteOperation op;
2190 mirror_image_status_remove_down(&op);
2191 return ioctx->operate(RBD_MIRRORING, &op);
2192 }
2193
2194 void mirror_image_status_remove_down(librados::ObjectWriteOperation *op) {
2195 bufferlist bl;
2196 op->exec("rbd", "mirror_image_status_remove_down", bl);
2197 }
2198
2199 int mirror_image_instance_get(librados::IoCtx *ioctx,
2200 const std::string &global_image_id,
2201 entity_inst_t *instance) {
2202 librados::ObjectReadOperation op;
2203 mirror_image_instance_get_start(&op, global_image_id);
2204
2205 bufferlist out_bl;
2206 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2207 if (r < 0) {
2208 return r;
2209 }
2210
2211 auto iter = out_bl.cbegin();
2212 r = mirror_image_instance_get_finish(&iter, instance);
2213 if (r < 0) {
2214 return r;
2215 }
2216 return 0;
2217 }
2218
2219 void mirror_image_instance_get_start(librados::ObjectReadOperation *op,
2220 const std::string &global_image_id) {
2221 bufferlist bl;
2222 encode(global_image_id, bl);
2223 op->exec("rbd", "mirror_image_instance_get", bl);
2224 }
2225
2226 int mirror_image_instance_get_finish(bufferlist::const_iterator *iter,
2227 entity_inst_t *instance) {
2228 try {
2229 decode(*instance, *iter);
2230 } catch (const buffer::error &err) {
2231 return -EBADMSG;
2232 }
2233 return 0;
2234 }
2235
2236 int mirror_image_instance_list(
2237 librados::IoCtx *ioctx, const std::string &start, uint64_t max_return,
2238 std::map<std::string, entity_inst_t> *instances) {
2239 librados::ObjectReadOperation op;
2240 mirror_image_instance_list_start(&op, start, max_return);
2241
2242 bufferlist out_bl;
2243 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2244 if (r < 0) {
2245 return r;
2246 }
2247
2248 auto iter = out_bl.cbegin();
2249 r = mirror_image_instance_list_finish(&iter, instances);
2250 if (r < 0) {
2251 return r;
2252 }
2253 return 0;
2254 }
2255
2256 void mirror_image_instance_list_start(librados::ObjectReadOperation *op,
2257 const std::string &start,
2258 uint64_t max_return) {
2259 bufferlist bl;
2260 encode(start, bl);
2261 encode(max_return, bl);
2262 op->exec("rbd", "mirror_image_instance_list", bl);
2263 }
2264
2265 int mirror_image_instance_list_finish(
2266 bufferlist::const_iterator *iter,
2267 std::map<std::string, entity_inst_t> *instances) {
2268 instances->clear();
2269 try {
2270 decode(*instances, *iter);
2271 } catch (const buffer::error &err) {
2272 return -EBADMSG;
2273 }
2274 return 0;
2275 }
2276
2277 void mirror_instances_list_start(librados::ObjectReadOperation *op) {
2278 bufferlist bl;
2279 op->exec("rbd", "mirror_instances_list", bl);
2280 }
2281
2282 int mirror_instances_list_finish(bufferlist::const_iterator *iter,
2283 std::vector<std::string> *instance_ids) {
2284 instance_ids->clear();
2285 try {
2286 decode(*instance_ids, *iter);
2287 } catch (const buffer::error &err) {
2288 return -EBADMSG;
2289 }
2290 return 0;
2291 }
2292
2293 int mirror_instances_list(librados::IoCtx *ioctx,
2294 std::vector<std::string> *instance_ids) {
2295 librados::ObjectReadOperation op;
2296 mirror_instances_list_start(&op);
2297
2298 bufferlist out_bl;
2299 int r = ioctx->operate(RBD_MIRROR_LEADER, &op, &out_bl);
2300 if (r < 0) {
2301 return r;
2302 }
2303
2304 auto iter = out_bl.cbegin();
2305 r = mirror_instances_list_finish(&iter, instance_ids);
2306 if (r < 0) {
2307 return r;
2308 }
2309 return 0;
2310 }
2311
2312 void mirror_instances_add(librados::ObjectWriteOperation *op,
2313 const std::string &instance_id) {
2314 bufferlist bl;
2315 encode(instance_id, bl);
2316 op->exec("rbd", "mirror_instances_add", bl);
2317 }
2318
2319 int mirror_instances_add(librados::IoCtx *ioctx,
2320 const std::string &instance_id) {
2321 librados::ObjectWriteOperation op;
2322 mirror_instances_add(&op, instance_id);
2323 return ioctx->operate(RBD_MIRROR_LEADER, &op);
2324 }
2325
2326 void mirror_instances_remove(librados::ObjectWriteOperation *op,
2327 const std::string &instance_id) {
2328 bufferlist bl;
2329 encode(instance_id, bl);
2330 op->exec("rbd", "mirror_instances_remove", bl);
2331 }
2332
2333 int mirror_instances_remove(librados::IoCtx *ioctx,
2334 const std::string &instance_id) {
2335 librados::ObjectWriteOperation op;
2336 mirror_instances_remove(&op, instance_id);
2337 return ioctx->operate(RBD_MIRROR_LEADER, &op);
2338 }
2339
2340 void mirror_image_map_list_start(librados::ObjectReadOperation *op,
2341 const std::string &start_after,
2342 uint64_t max_read) {
2343 bufferlist bl;
2344 encode(start_after, bl);
2345 encode(max_read, bl);
2346
2347 op->exec("rbd", "mirror_image_map_list", bl);
2348 }
2349
2350 int mirror_image_map_list_finish(bufferlist::const_iterator *iter,
2351 std::map<std::string, cls::rbd::MirrorImageMap> *image_mapping) {
2352 try {
2353 decode(*image_mapping, *iter);
2354 } catch (const buffer::error &err) {
2355 return -EBADMSG;
2356 }
2357 return 0;
2358 }
2359
2360 int mirror_image_map_list(
2361 librados::IoCtx *ioctx, const std::string &start_after,
2362 uint64_t max_read,
2363 std::map<std::string, cls::rbd::MirrorImageMap> *image_mapping) {
2364 librados::ObjectReadOperation op;
2365 mirror_image_map_list_start(&op, start_after, max_read);
2366
2367 bufferlist out_bl;
2368 int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
2369 if (r < 0) {
2370 return r;
2371 }
2372
2373 auto iter = out_bl.cbegin();
2374 return mirror_image_map_list_finish(&iter, image_mapping);
2375 }
2376
2377 void mirror_image_map_update(librados::ObjectWriteOperation *op,
2378 const std::string &global_image_id,
2379 const cls::rbd::MirrorImageMap &image_map) {
2380 bufferlist bl;
2381 encode(global_image_id, bl);
2382 encode(image_map, bl);
2383
2384 op->exec("rbd", "mirror_image_map_update", bl);
2385 }
2386
2387 void mirror_image_map_remove(librados::ObjectWriteOperation *op,
2388 const std::string &global_image_id) {
2389 bufferlist bl;
2390 encode(global_image_id, bl);
2391
2392 op->exec("rbd", "mirror_image_map_remove", bl);
2393 }
2394
2395 // Groups functions
2396 int group_dir_list(librados::IoCtx *ioctx, const std::string &oid,
2397 const std::string &start, uint64_t max_return,
2398 map<string, string> *cgs)
2399 {
2400 bufferlist in, out;
2401 encode(start, in);
2402 encode(max_return, in);
2403 int r = ioctx->exec(oid, "rbd", "group_dir_list", in, out);
2404 if (r < 0)
2405 return r;
2406
2407 auto iter = out.cbegin();
2408 try {
2409 decode(*cgs, iter);
2410 } catch (const buffer::error &err) {
2411 return -EBADMSG;
2412 }
2413
2414 return 0;
2415 }
2416
2417 int group_dir_add(librados::IoCtx *ioctx, const std::string &oid,
2418 const std::string &name, const std::string &id)
2419 {
2420 bufferlist in, out;
2421 encode(name, in);
2422 encode(id, in);
2423 return ioctx->exec(oid, "rbd", "group_dir_add", in, out);
2424 }
2425
2426 int group_dir_rename(librados::IoCtx *ioctx, const std::string &oid,
2427 const std::string &src, const std::string &dest,
2428 const std::string &id)
2429 {
2430 bufferlist in, out;
2431 encode(src, in);
2432 encode(dest, in);
2433 encode(id, in);
2434 return ioctx->exec(oid, "rbd", "group_dir_rename", in, out);
2435 }
2436
2437 int group_dir_remove(librados::IoCtx *ioctx, const std::string &oid,
2438 const std::string &name, const std::string &id)
2439 {
2440 bufferlist in, out;
2441 encode(name, in);
2442 encode(id, in);
2443 return ioctx->exec(oid, "rbd", "group_dir_remove", in, out);
2444 }
2445
2446 int group_image_remove(librados::IoCtx *ioctx, const std::string &oid,
2447 const cls::rbd::GroupImageSpec &spec)
2448 {
2449 bufferlist bl, bl2;
2450 encode(spec, bl);
2451
2452 return ioctx->exec(oid, "rbd", "group_image_remove", bl, bl2);
2453 }
2454
2455 int group_image_list(librados::IoCtx *ioctx,
2456 const std::string &oid,
2457 const cls::rbd::GroupImageSpec &start,
2458 uint64_t max_return,
2459 std::vector<cls::rbd::GroupImageStatus> *images)
2460 {
2461 bufferlist bl, bl2;
2462 encode(start, bl);
2463 encode(max_return, bl);
2464
2465 int r = ioctx->exec(oid, "rbd", "group_image_list", bl, bl2);
2466 if (r < 0)
2467 return r;
2468
2469 auto iter = bl2.cbegin();
2470 try {
2471 decode(*images, iter);
2472 } catch (const buffer::error &err) {
2473 return -EBADMSG;
2474 }
2475
2476 return 0;
2477 }
2478
2479 int group_image_set(librados::IoCtx *ioctx, const std::string &oid,
2480 const cls::rbd::GroupImageStatus &st)
2481 {
2482 bufferlist bl, bl2;
2483 encode(st, bl);
2484
2485 return ioctx->exec(oid, "rbd", "group_image_set", bl, bl2);
2486 }
2487
2488 int image_group_add(librados::IoCtx *ioctx, const std::string &oid,
2489 const cls::rbd::GroupSpec &group_spec)
2490 {
2491 bufferlist bl, bl2;
2492 encode(group_spec, bl);
2493
2494 return ioctx->exec(oid, "rbd", "image_group_add", bl, bl2);
2495 }
2496
2497 int image_group_remove(librados::IoCtx *ioctx, const std::string &oid,
2498 const cls::rbd::GroupSpec &group_spec)
2499 {
2500 bufferlist bl, bl2;
2501 encode(group_spec, bl);
2502
2503 return ioctx->exec(oid, "rbd", "image_group_remove", bl, bl2);
2504 }
2505
2506 void image_group_get_start(librados::ObjectReadOperation *op)
2507 {
2508 bufferlist in_bl;
2509 op->exec("rbd", "image_group_get", in_bl);
2510 }
2511
2512 int image_group_get_finish(bufferlist::const_iterator *iter,
2513 cls::rbd::GroupSpec *group_spec)
2514 {
2515 try {
2516 decode(*group_spec, *iter);
2517 } catch (const buffer::error &err) {
2518 return -EBADMSG;
2519 }
2520 return 0;
2521 }
2522
2523 int image_group_get(librados::IoCtx *ioctx, const std::string &oid,
2524 cls::rbd::GroupSpec *group_spec)
2525 {
2526 librados::ObjectReadOperation op;
2527 image_group_get_start(&op);
2528
2529 bufferlist out_bl;
2530 int r = ioctx->operate(oid, &op, &out_bl);
2531 if (r < 0) {
2532 return r;
2533 }
2534
2535 auto iter = out_bl.cbegin();
2536 return image_group_get_finish(&iter, group_spec);
2537 }
2538
2539 int group_snap_set(librados::IoCtx *ioctx, const std::string &oid,
2540 const cls::rbd::GroupSnapshot &snapshot)
2541 {
2542 using ceph::encode;
2543 bufferlist inbl, outbl;
2544 encode(snapshot, inbl);
2545 int r = ioctx->exec(oid, "rbd", "group_snap_set", inbl, outbl);
2546 return r;
2547 }
2548
2549 int group_snap_remove(librados::IoCtx *ioctx, const std::string &oid,
2550 const std::string &snap_id)
2551 {
2552 using ceph::encode;
2553 bufferlist inbl, outbl;
2554 encode(snap_id, inbl);
2555 return ioctx->exec(oid, "rbd", "group_snap_remove", inbl, outbl);
2556 }
2557
2558 int group_snap_get_by_id(librados::IoCtx *ioctx, const std::string &oid,
2559 const std::string &snap_id,
2560 cls::rbd::GroupSnapshot *snapshot)
2561 {
2562 using ceph::encode;
2563 using ceph::decode;
2564 bufferlist inbl, outbl;
2565
2566 encode(snap_id, inbl);
2567 int r = ioctx->exec(oid, "rbd", "group_snap_get_by_id", inbl, outbl);
2568 if (r < 0) {
2569 return r;
2570 }
2571
2572 auto iter = outbl.cbegin();
2573 try {
2574 decode(*snapshot, iter);
2575 } catch (const buffer::error &err) {
2576 return -EBADMSG;
2577 }
2578
2579 return 0;
2580 }
2581 int group_snap_list(librados::IoCtx *ioctx, const std::string &oid,
2582 const cls::rbd::GroupSnapshot &start,
2583 uint64_t max_return,
2584 std::vector<cls::rbd::GroupSnapshot> *snapshots)
2585 {
2586 using ceph::encode;
2587 using ceph::decode;
2588 bufferlist inbl, outbl;
2589 encode(start, inbl);
2590 encode(max_return, inbl);
2591
2592 int r = ioctx->exec(oid, "rbd", "group_snap_list", inbl, outbl);
2593 if (r < 0) {
2594 return r;
2595 }
2596 auto iter = outbl.cbegin();
2597 try {
2598 decode(*snapshots, iter);
2599 } catch (const buffer::error &err) {
2600 return -EBADMSG;
2601 }
2602
2603 return 0;
2604 }
2605
2606 // rbd_trash functions
2607 void trash_add(librados::ObjectWriteOperation *op,
2608 const std::string &id,
2609 const cls::rbd::TrashImageSpec &trash_spec)
2610 {
2611 bufferlist bl;
2612 encode(id, bl);
2613 encode(trash_spec, bl);
2614 op->exec("rbd", "trash_add", bl);
2615 }
2616
2617 int trash_add(librados::IoCtx *ioctx, const std::string &id,
2618 const cls::rbd::TrashImageSpec &trash_spec)
2619 {
2620 librados::ObjectWriteOperation op;
2621 trash_add(&op, id, trash_spec);
2622
2623 return ioctx->operate(RBD_TRASH, &op);
2624 }
2625
2626 void trash_remove(librados::ObjectWriteOperation *op,
2627 const std::string &id)
2628 {
2629 bufferlist bl;
2630 encode(id, bl);
2631 op->exec("rbd", "trash_remove", bl);
2632 }
2633
2634 int trash_remove(librados::IoCtx *ioctx, const std::string &id)
2635 {
2636 librados::ObjectWriteOperation op;
2637 trash_remove(&op, id);
2638
2639 return ioctx->operate(RBD_TRASH, &op);
2640 }
2641
2642 void trash_list_start(librados::ObjectReadOperation *op,
2643 const std::string &start, uint64_t max_return)
2644 {
2645 bufferlist bl;
2646 encode(start, bl);
2647 encode(max_return, bl);
2648 op->exec("rbd", "trash_list", bl);
2649 }
2650
2651 int trash_list_finish(bufferlist::const_iterator *it,
2652 map<string, cls::rbd::TrashImageSpec> *entries)
2653 {
2654 ceph_assert(entries);
2655
2656 try {
2657 decode(*entries, *it);
2658 } catch (const buffer::error &err) {
2659 return -EBADMSG;
2660 }
2661
2662 return 0;
2663 }
2664
2665 int trash_list(librados::IoCtx *ioctx,
2666 const std::string &start, uint64_t max_return,
2667 map<string, cls::rbd::TrashImageSpec> *entries)
2668 {
2669 librados::ObjectReadOperation op;
2670 trash_list_start(&op, start, max_return);
2671
2672 bufferlist out_bl;
2673 int r = ioctx->operate(RBD_TRASH, &op, &out_bl);
2674 if (r < 0) {
2675 return r;
2676 }
2677
2678 auto iter = out_bl.cbegin();
2679 return trash_list_finish(&iter, entries);
2680 }
2681
2682 void trash_get_start(librados::ObjectReadOperation *op,
2683 const std::string &id)
2684 {
2685 bufferlist bl;
2686 encode(id, bl);
2687 op->exec("rbd", "trash_get", bl);
2688 }
2689
2690 int trash_get_finish(bufferlist::const_iterator *it,
2691 cls::rbd::TrashImageSpec *trash_spec) {
2692 ceph_assert(trash_spec);
2693 try {
2694 decode(*trash_spec, *it);
2695 } catch (const buffer::error &err) {
2696 return -EBADMSG;
2697 }
2698
2699 return 0;
2700 }
2701
2702 int trash_get(librados::IoCtx *ioctx, const std::string &id,
2703 cls::rbd::TrashImageSpec *trash_spec)
2704 {
2705 librados::ObjectReadOperation op;
2706 trash_get_start(&op, id);
2707
2708 bufferlist out_bl;
2709 int r = ioctx->operate(RBD_TRASH, &op, &out_bl);
2710 if (r < 0) {
2711 return r;
2712 }
2713
2714 auto it = out_bl.cbegin();
2715 return trash_get_finish(&it, trash_spec);
2716 }
2717
2718 void trash_state_set(librados::ObjectWriteOperation *op,
2719 const std::string &id,
2720 const cls::rbd::TrashImageState &trash_state,
2721 const cls::rbd::TrashImageState &expect_state)
2722 {
2723 bufferlist bl;
2724 encode(id, bl);
2725 encode(trash_state, bl);
2726 encode(expect_state, bl);
2727 op->exec("rbd", "trash_state_set", bl);
2728 }
2729
2730 int trash_state_set(librados::IoCtx *ioctx, const std::string &id,
2731 const cls::rbd::TrashImageState &trash_state,
2732 const cls::rbd::TrashImageState &expect_state)
2733 {
2734 librados::ObjectWriteOperation op;
2735 trash_state_set(&op, id, trash_state, expect_state);
2736
2737 return ioctx->operate(RBD_TRASH, &op);
2738 }
2739
2740 void namespace_add(librados::ObjectWriteOperation *op,
2741 const std::string &name)
2742 {
2743 bufferlist bl;
2744 encode(name, bl);
2745 op->exec("rbd", "namespace_add", bl);
2746 }
2747
2748 int namespace_add(librados::IoCtx *ioctx, const std::string &name)
2749 {
2750 librados::ObjectWriteOperation op;
2751 namespace_add(&op, name);
2752
2753 return ioctx->operate(RBD_NAMESPACE, &op);
2754 }
2755
2756 void namespace_remove(librados::ObjectWriteOperation *op,
2757 const std::string &name)
2758 {
2759 bufferlist bl;
2760 encode(name, bl);
2761 op->exec("rbd", "namespace_remove", bl);
2762 }
2763
2764 int namespace_remove(librados::IoCtx *ioctx, const std::string &name)
2765 {
2766 librados::ObjectWriteOperation op;
2767 namespace_remove(&op, name);
2768
2769 return ioctx->operate(RBD_NAMESPACE, &op);
2770 }
2771
2772 void namespace_list_start(librados::ObjectReadOperation *op,
2773 const std::string &start, uint64_t max_return)
2774 {
2775 bufferlist bl;
2776 encode(start, bl);
2777 encode(max_return, bl);
2778 op->exec("rbd", "namespace_list", bl);
2779 }
2780
2781 int namespace_list_finish(bufferlist::const_iterator *it,
2782 std::list<std::string> *entries)
2783 {
2784 ceph_assert(entries);
2785
2786 try {
2787 decode(*entries, *it);
2788 } catch (const buffer::error &err) {
2789 return -EBADMSG;
2790 }
2791
2792 return 0;
2793 }
2794
2795 int namespace_list(librados::IoCtx *ioctx,
2796 const std::string &start, uint64_t max_return,
2797 std::list<std::string> *entries)
2798 {
2799 librados::ObjectReadOperation op;
2800 namespace_list_start(&op, start, max_return);
2801
2802 bufferlist out_bl;
2803 int r = ioctx->operate(RBD_NAMESPACE, &op, &out_bl);
2804 if (r < 0) {
2805 return r;
2806 }
2807
2808 auto iter = out_bl.cbegin();
2809 return namespace_list_finish(&iter, entries);
2810 }
2811
2812 void sparsify(librados::ObjectWriteOperation *op, size_t sparse_size,
2813 bool remove_empty)
2814 {
2815 bufferlist bl;
2816 encode(sparse_size, bl);
2817 encode(remove_empty, bl);
2818 op->exec("rbd", "sparsify", bl);
2819 }
2820
2821 int sparsify(librados::IoCtx *ioctx, const std::string &oid, size_t sparse_size,
2822 bool remove_empty)
2823 {
2824 librados::ObjectWriteOperation op;
2825 sparsify(&op, sparse_size, remove_empty);
2826
2827 return ioctx->operate(oid, &op);
2828 }
2829
2830 } // namespace cls_client
2831 } // namespace librbd
2832