]> git.proxmox.com Git - ceph.git/blob - ceph/src/cls/rbd/cls_rbd_types.cc
import ceph quincy 17.2.4
[ceph.git] / ceph / src / cls / rbd / cls_rbd_types.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include <boost/variant.hpp>
5 #include "cls/rbd/cls_rbd_types.h"
6 #include "common/Formatter.h"
7
8 namespace cls {
9 namespace rbd {
10
11 using std::istringstream;
12 using std::ostringstream;
13 using std::string;
14
15 using ceph::bufferlist;
16 using ceph::Formatter;
17
18 std::ostream& operator<<(std::ostream& os,
19 MirrorPeerDirection mirror_peer_direction) {
20 switch (mirror_peer_direction) {
21 case MIRROR_PEER_DIRECTION_RX:
22 os << "RX";
23 break;
24 case MIRROR_PEER_DIRECTION_TX:
25 os << "TX";
26 break;
27 case MIRROR_PEER_DIRECTION_RX_TX:
28 os << "RX/TX";
29 break;
30 default:
31 os << "unknown";
32 break;
33 }
34 return os;
35 }
36
37 void MirrorPeer::encode(bufferlist &bl) const {
38 ENCODE_START(2, 1, bl);
39 encode(uuid, bl);
40 encode(site_name, bl);
41 encode(client_name, bl);
42 int64_t pool_id = -1;
43 encode(pool_id, bl);
44
45 // v2
46 encode(static_cast<uint8_t>(mirror_peer_direction), bl);
47 encode(mirror_uuid, bl);
48 encode(last_seen, bl);
49 ENCODE_FINISH(bl);
50 }
51
52 void MirrorPeer::decode(bufferlist::const_iterator &it) {
53 DECODE_START(2, it);
54 decode(uuid, it);
55 decode(site_name, it);
56 decode(client_name, it);
57 int64_t pool_id;
58 decode(pool_id, it);
59
60 if (struct_v >= 2) {
61 uint8_t mpd;
62 decode(mpd, it);
63 mirror_peer_direction = static_cast<MirrorPeerDirection>(mpd);
64 decode(mirror_uuid, it);
65 decode(last_seen, it);
66 }
67
68 DECODE_FINISH(it);
69 }
70
71 void MirrorPeer::dump(Formatter *f) const {
72 f->dump_string("uuid", uuid);
73 f->dump_stream("direction") << mirror_peer_direction;
74 f->dump_string("site_name", site_name);
75 f->dump_string("mirror_uuid", mirror_uuid);
76 f->dump_string("client_name", client_name);
77 f->dump_stream("last_seen") << last_seen;
78 }
79
80 void MirrorPeer::generate_test_instances(std::list<MirrorPeer*> &o) {
81 o.push_back(new MirrorPeer());
82 o.push_back(new MirrorPeer("uuid-123", MIRROR_PEER_DIRECTION_RX, "site A",
83 "client name", ""));
84 o.push_back(new MirrorPeer("uuid-234", MIRROR_PEER_DIRECTION_TX, "site B",
85 "", "mirror_uuid"));
86 o.push_back(new MirrorPeer("uuid-345", MIRROR_PEER_DIRECTION_RX_TX, "site C",
87 "client name", "mirror_uuid"));
88 }
89
90 bool MirrorPeer::operator==(const MirrorPeer &rhs) const {
91 return (uuid == rhs.uuid &&
92 mirror_peer_direction == rhs.mirror_peer_direction &&
93 site_name == rhs.site_name &&
94 client_name == rhs.client_name &&
95 mirror_uuid == rhs.mirror_uuid &&
96 last_seen == rhs.last_seen);
97 }
98
99 std::ostream& operator<<(std::ostream& os, const MirrorMode& mirror_mode) {
100 switch (mirror_mode) {
101 case MIRROR_MODE_DISABLED:
102 os << "disabled";
103 break;
104 case MIRROR_MODE_IMAGE:
105 os << "image";
106 break;
107 case MIRROR_MODE_POOL:
108 os << "pool";
109 break;
110 default:
111 os << "unknown (" << static_cast<uint32_t>(mirror_mode) << ")";
112 break;
113 }
114 return os;
115 }
116
117 std::ostream& operator<<(std::ostream& os, const MirrorPeer& peer) {
118 os << "["
119 << "uuid=" << peer.uuid << ", "
120 << "direction=" << peer.mirror_peer_direction << ", "
121 << "site_name=" << peer.site_name << ", "
122 << "client_name=" << peer.client_name << ", "
123 << "mirror_uuid=" << peer.mirror_uuid << ", "
124 << "last_seen=" << peer.last_seen
125 << "]";
126 return os;
127 }
128
129 void MirrorImage::encode(bufferlist &bl) const {
130 ENCODE_START(2, 1, bl);
131 encode(global_image_id, bl);
132 encode(static_cast<uint8_t>(state), bl);
133 encode(static_cast<uint8_t>(mode), bl);
134 ENCODE_FINISH(bl);
135 }
136
137 void MirrorImage::decode(bufferlist::const_iterator &it) {
138 uint8_t int_state;
139 DECODE_START(2, it);
140 decode(global_image_id, it);
141 decode(int_state, it);
142 state = static_cast<MirrorImageState>(int_state);
143 if (struct_v >= 2) {
144 uint8_t int_mode;
145 decode(int_mode, it);
146 mode = static_cast<MirrorImageMode>(int_mode);
147 }
148 DECODE_FINISH(it);
149 }
150
151 void MirrorImage::dump(Formatter *f) const {
152 f->dump_stream("mode") << mode;
153 f->dump_string("global_image_id", global_image_id);
154 f->dump_stream("state") << state;
155 }
156
157 void MirrorImage::generate_test_instances(std::list<MirrorImage*> &o) {
158 o.push_back(new MirrorImage());
159 o.push_back(new MirrorImage(MIRROR_IMAGE_MODE_JOURNAL, "uuid-123",
160 MIRROR_IMAGE_STATE_ENABLED));
161 o.push_back(new MirrorImage(MIRROR_IMAGE_MODE_SNAPSHOT, "uuid-abc",
162 MIRROR_IMAGE_STATE_DISABLING));
163 }
164
165 bool MirrorImage::operator==(const MirrorImage &rhs) const {
166 return mode == rhs.mode && global_image_id == rhs.global_image_id &&
167 state == rhs.state;
168 }
169
170 bool MirrorImage::operator<(const MirrorImage &rhs) const {
171 if (mode != rhs.mode) {
172 return mode < rhs.mode;
173 }
174 if (global_image_id != rhs.global_image_id) {
175 return global_image_id < rhs.global_image_id;
176 }
177 return state < rhs.state;
178 }
179
180 std::ostream& operator<<(std::ostream& os, const MirrorImageMode& mirror_mode) {
181 switch (mirror_mode) {
182 case MIRROR_IMAGE_MODE_JOURNAL:
183 os << "journal";
184 break;
185 case MIRROR_IMAGE_MODE_SNAPSHOT:
186 os << "snapshot";
187 break;
188 default:
189 os << "unknown (" << static_cast<uint32_t>(mirror_mode) << ")";
190 break;
191 }
192 return os;
193 }
194
195 std::ostream& operator<<(std::ostream& os, const MirrorImageState& mirror_state) {
196 switch (mirror_state) {
197 case MIRROR_IMAGE_STATE_DISABLING:
198 os << "disabling";
199 break;
200 case MIRROR_IMAGE_STATE_ENABLED:
201 os << "enabled";
202 break;
203 case MIRROR_IMAGE_STATE_DISABLED:
204 os << "disabled";
205 break;
206 default:
207 os << "unknown (" << static_cast<uint32_t>(mirror_state) << ")";
208 break;
209 }
210 return os;
211 }
212
213 std::ostream& operator<<(std::ostream& os, const MirrorImage& mirror_image) {
214 os << "["
215 << "mode=" << mirror_image.mode << ", "
216 << "global_image_id=" << mirror_image.global_image_id << ", "
217 << "state=" << mirror_image.state << "]";
218 return os;
219 }
220
221 std::ostream& operator<<(std::ostream& os,
222 const MirrorImageStatusState& state) {
223 switch (state) {
224 case MIRROR_IMAGE_STATUS_STATE_UNKNOWN:
225 os << "unknown";
226 break;
227 case MIRROR_IMAGE_STATUS_STATE_ERROR:
228 os << "error";
229 break;
230 case MIRROR_IMAGE_STATUS_STATE_SYNCING:
231 os << "syncing";
232 break;
233 case MIRROR_IMAGE_STATUS_STATE_STARTING_REPLAY:
234 os << "starting_replay";
235 break;
236 case MIRROR_IMAGE_STATUS_STATE_REPLAYING:
237 os << "replaying";
238 break;
239 case MIRROR_IMAGE_STATUS_STATE_STOPPING_REPLAY:
240 os << "stopping_replay";
241 break;
242 case MIRROR_IMAGE_STATUS_STATE_STOPPED:
243 os << "stopped";
244 break;
245 default:
246 os << "unknown (" << static_cast<uint32_t>(state) << ")";
247 break;
248 }
249 return os;
250 }
251
252 const std::string MirrorImageSiteStatus::LOCAL_MIRROR_UUID(""); // empty mirror uuid
253
254 void MirrorImageSiteStatus::encode_meta(uint8_t version, bufferlist &bl) const {
255 if (version >= 2) {
256 ceph::encode(mirror_uuid, bl);
257 }
258 cls::rbd::encode(state, bl);
259 ceph::encode(description, bl);
260 ceph::encode(last_update, bl);
261 ceph::encode(up, bl);
262 }
263
264 void MirrorImageSiteStatus::decode_meta(uint8_t version,
265 bufferlist::const_iterator &it) {
266 if (version < 2) {
267 mirror_uuid = LOCAL_MIRROR_UUID;
268 } else {
269 ceph::decode(mirror_uuid, it);
270 }
271
272 cls::rbd::decode(state, it);
273 ceph::decode(description, it);
274 ::decode(last_update, it);
275 ceph::decode(up, it);
276 }
277
278 void MirrorImageSiteStatus::encode(bufferlist &bl) const {
279 // break compatibility when site-name is provided
280 uint8_t version = (mirror_uuid == LOCAL_MIRROR_UUID ? 1 : 2);
281 ENCODE_START(version, version, bl);
282 encode_meta(version, bl);
283 ENCODE_FINISH(bl);
284 }
285
286 void MirrorImageSiteStatus::decode(bufferlist::const_iterator &it) {
287 DECODE_START(2, it);
288 decode_meta(struct_v, it);
289 DECODE_FINISH(it);
290 }
291
292 void MirrorImageSiteStatus::dump(Formatter *f) const {
293 f->dump_string("state", state_to_string());
294 f->dump_string("description", description);
295 f->dump_stream("last_update") << last_update;
296 }
297
298 std::string MirrorImageSiteStatus::state_to_string() const {
299 std::stringstream ss;
300 ss << (up ? "up+" : "down+") << state;
301 return ss.str();
302 }
303
304 void MirrorImageSiteStatus::generate_test_instances(
305 std::list<MirrorImageSiteStatus*> &o) {
306 o.push_back(new MirrorImageSiteStatus());
307 o.push_back(new MirrorImageSiteStatus("", MIRROR_IMAGE_STATUS_STATE_REPLAYING,
308 ""));
309 o.push_back(new MirrorImageSiteStatus("", MIRROR_IMAGE_STATUS_STATE_ERROR,
310 "error"));
311 o.push_back(new MirrorImageSiteStatus("2fb68ca9-1ba0-43b3-8cdf-8c5a9db71e65",
312 MIRROR_IMAGE_STATUS_STATE_STOPPED, ""));
313 }
314
315 bool MirrorImageSiteStatus::operator==(const MirrorImageSiteStatus &rhs) const {
316 return state == rhs.state && description == rhs.description && up == rhs.up;
317 }
318
319 std::ostream& operator<<(std::ostream& os,
320 const MirrorImageSiteStatus& status) {
321 os << "{"
322 << "state=" << status.state_to_string() << ", "
323 << "description=" << status.description << ", "
324 << "last_update=" << status.last_update << "]}";
325 return os;
326 }
327
328 void MirrorImageSiteStatusOnDisk::encode_meta(bufferlist &bl,
329 uint64_t features) const {
330 ENCODE_START(1, 1, bl);
331 auto sanitized_origin = origin;
332 sanitize_entity_inst(&sanitized_origin);
333 encode(sanitized_origin, bl, features);
334 ENCODE_FINISH(bl);
335 }
336
337 void MirrorImageSiteStatusOnDisk::encode(bufferlist &bl,
338 uint64_t features) const {
339 encode_meta(bl, features);
340 cls::rbd::MirrorImageSiteStatus::encode(bl);
341 }
342
343 void MirrorImageSiteStatusOnDisk::decode_meta(bufferlist::const_iterator &it) {
344 DECODE_START(1, it);
345 decode(origin, it);
346 sanitize_entity_inst(&origin);
347 DECODE_FINISH(it);
348 }
349
350 void MirrorImageSiteStatusOnDisk::decode(bufferlist::const_iterator &it) {
351 decode_meta(it);
352 cls::rbd::MirrorImageSiteStatus::decode(it);
353 }
354
355 void MirrorImageSiteStatusOnDisk::generate_test_instances(
356 std::list<MirrorImageSiteStatusOnDisk*> &o) {
357 o.push_back(new MirrorImageSiteStatusOnDisk());
358 o.push_back(new MirrorImageSiteStatusOnDisk(
359 {"", MIRROR_IMAGE_STATUS_STATE_ERROR, "error"}));
360 o.push_back(new MirrorImageSiteStatusOnDisk(
361 {"siteA", MIRROR_IMAGE_STATUS_STATE_STOPPED, ""}));
362 }
363
364 int MirrorImageStatus::get_local_mirror_image_site_status(
365 MirrorImageSiteStatus* status) const {
366 auto it = std::find_if(
367 mirror_image_site_statuses.begin(),
368 mirror_image_site_statuses.end(),
369 [](const MirrorImageSiteStatus& status) {
370 return status.mirror_uuid == MirrorImageSiteStatus::LOCAL_MIRROR_UUID;
371 });
372 if (it == mirror_image_site_statuses.end()) {
373 return -ENOENT;
374 }
375
376 *status = *it;
377 return 0;
378 }
379
380 void MirrorImageStatus::encode(bufferlist &bl) const {
381 // don't break compatibility for extra site statuses
382 ENCODE_START(2, 1, bl);
383
384 // local site status
385 MirrorImageSiteStatus local_status;
386 int r = get_local_mirror_image_site_status(&local_status);
387 local_status.encode_meta(1, bl);
388
389 bool local_status_valid = (r >= 0);
390 encode(local_status_valid, bl);
391
392 // remote site statuses
393 __u32 n = mirror_image_site_statuses.size();
394 if (local_status_valid) {
395 --n;
396 }
397 encode(n, bl);
398
399 for (auto& status : mirror_image_site_statuses) {
400 if (status.mirror_uuid == MirrorImageSiteStatus::LOCAL_MIRROR_UUID) {
401 continue;
402 }
403 status.encode_meta(2, bl);
404 }
405 ENCODE_FINISH(bl);
406 }
407
408 void MirrorImageStatus::decode(bufferlist::const_iterator &it) {
409 DECODE_START(2, it);
410
411 // local site status
412 MirrorImageSiteStatus local_status;
413 local_status.decode_meta(1, it);
414
415 if (struct_v < 2) {
416 mirror_image_site_statuses.push_back(local_status);
417 } else {
418 bool local_status_valid;
419 decode(local_status_valid, it);
420
421 __u32 n;
422 decode(n, it);
423 if (local_status_valid) {
424 ++n;
425 }
426
427 mirror_image_site_statuses.resize(n);
428 for (auto status_it = mirror_image_site_statuses.begin();
429 status_it != mirror_image_site_statuses.end(); ++status_it) {
430 if (local_status_valid &&
431 status_it == mirror_image_site_statuses.begin()) {
432 *status_it = local_status;
433 continue;
434 }
435
436 // remote site status
437 status_it->decode_meta(struct_v, it);
438 }
439 }
440 DECODE_FINISH(it);
441 }
442
443 void MirrorImageStatus::dump(Formatter *f) const {
444 MirrorImageSiteStatus local_status;
445 int r = get_local_mirror_image_site_status(&local_status);
446 if (r >= 0) {
447 local_status.dump(f);
448 }
449
450 f->open_array_section("remotes");
451 for (auto& status : mirror_image_site_statuses) {
452 if (status.mirror_uuid == MirrorImageSiteStatus::LOCAL_MIRROR_UUID) {
453 continue;
454 }
455
456 f->open_object_section("remote");
457 status.dump(f);
458 f->close_section();
459 }
460 f->close_section();
461 }
462
463 bool MirrorImageStatus::operator==(const MirrorImageStatus &rhs) const {
464 return (mirror_image_site_statuses == rhs.mirror_image_site_statuses);
465 }
466
467 void MirrorImageStatus::generate_test_instances(
468 std::list<MirrorImageStatus*> &o) {
469 o.push_back(new MirrorImageStatus());
470 o.push_back(new MirrorImageStatus({{"", MIRROR_IMAGE_STATUS_STATE_ERROR, ""}}));
471 o.push_back(new MirrorImageStatus({{"", MIRROR_IMAGE_STATUS_STATE_STOPPED, ""},
472 {"siteA", MIRROR_IMAGE_STATUS_STATE_REPLAYING, ""}}));
473 }
474
475 std::ostream& operator<<(std::ostream& os,
476 const MirrorImageStatus& status) {
477 os << "{";
478 MirrorImageSiteStatus local_status;
479 int r = status.get_local_mirror_image_site_status(&local_status);
480 if (r >= 0) {
481 os << "state=" << local_status.state_to_string() << ", "
482 << "description=" << local_status.description << ", "
483 << "last_update=" << local_status.last_update << ", ";
484 }
485
486 os << "remotes=[";
487 for (auto& remote_status : status.mirror_image_site_statuses) {
488 if (remote_status.mirror_uuid == MirrorImageSiteStatus::LOCAL_MIRROR_UUID) {
489 continue;
490 }
491
492 os << "{"
493 << "mirror_uuid=" << remote_status.mirror_uuid<< ", "
494 << "state=" << remote_status.state_to_string() << ", "
495 << "description=" << remote_status.description << ", "
496 << "last_update=" << remote_status.last_update
497 << "}";
498 }
499 os << "]}";
500 return os;
501 }
502
503 void ParentImageSpec::encode(bufferlist& bl) const {
504 ENCODE_START(1, 1, bl);
505 encode(pool_id, bl);
506 encode(pool_namespace, bl);
507 encode(image_id, bl);
508 encode(snap_id, bl);
509 ENCODE_FINISH(bl);
510 }
511
512 void ParentImageSpec::decode(bufferlist::const_iterator& bl) {
513 DECODE_START(1, bl);
514 decode(pool_id, bl);
515 decode(pool_namespace, bl);
516 decode(image_id, bl);
517 decode(snap_id, bl);
518 DECODE_FINISH(bl);
519 }
520
521 void ParentImageSpec::dump(Formatter *f) const {
522 f->dump_int("pool_id", pool_id);
523 f->dump_string("pool_namespace", pool_namespace);
524 f->dump_string("image_id", image_id);
525 f->dump_unsigned("snap_id", snap_id);
526 }
527
528 void ParentImageSpec::generate_test_instances(std::list<ParentImageSpec*>& o) {
529 o.push_back(new ParentImageSpec{});
530 o.push_back(new ParentImageSpec{1, "", "foo", 3});
531 o.push_back(new ParentImageSpec{1, "ns", "foo", 3});
532 }
533
534 std::ostream& operator<<(std::ostream& os, const ParentImageSpec& rhs) {
535 os << "["
536 << "pool_id=" << rhs.pool_id << ", "
537 << "pool_namespace=" << rhs.pool_namespace << ", "
538 << "image_id=" << rhs.image_id << ", "
539 << "snap_id=" << rhs.snap_id
540 << "]";
541 return os;
542 }
543
544 void ChildImageSpec::encode(bufferlist &bl) const {
545 ENCODE_START(2, 1, bl);
546 encode(pool_id, bl);
547 encode(image_id, bl);
548 encode(pool_namespace, bl);
549 ENCODE_FINISH(bl);
550 }
551
552 void ChildImageSpec::decode(bufferlist::const_iterator &it) {
553 DECODE_START(2, it);
554 decode(pool_id, it);
555 decode(image_id, it);
556 if (struct_v >= 2) {
557 decode(pool_namespace, it);
558 }
559 DECODE_FINISH(it);
560 }
561
562 void ChildImageSpec::dump(Formatter *f) const {
563 f->dump_int("pool_id", pool_id);
564 f->dump_string("pool_namespace", pool_namespace);
565 f->dump_string("image_id", image_id);
566 }
567
568 void ChildImageSpec::generate_test_instances(std::list<ChildImageSpec*> &o) {
569 o.push_back(new ChildImageSpec());
570 o.push_back(new ChildImageSpec(123, "", "abc"));
571 o.push_back(new ChildImageSpec(123, "ns", "abc"));
572 }
573
574 std::ostream& operator<<(std::ostream& os, const ChildImageSpec& rhs) {
575 os << "["
576 << "pool_id=" << rhs.pool_id << ", "
577 << "pool_namespace=" << rhs.pool_namespace << ", "
578 << "image_id=" << rhs.image_id
579 << "]";
580 return os;
581 }
582
583 void GroupImageSpec::encode(bufferlist &bl) const {
584 ENCODE_START(1, 1, bl);
585 encode(image_id, bl);
586 encode(pool_id, bl);
587 ENCODE_FINISH(bl);
588 }
589
590 void GroupImageSpec::decode(bufferlist::const_iterator &it) {
591 DECODE_START(1, it);
592 decode(image_id, it);
593 decode(pool_id, it);
594 DECODE_FINISH(it);
595 }
596
597 void GroupImageSpec::dump(Formatter *f) const {
598 f->dump_string("image_id", image_id);
599 f->dump_int("pool_id", pool_id);
600 }
601
602 int GroupImageSpec::from_key(const std::string &image_key,
603 GroupImageSpec *spec) {
604 if (nullptr == spec) return -EINVAL;
605 int prefix_len = cls::rbd::RBD_GROUP_IMAGE_KEY_PREFIX.size();
606 std::string data_string = image_key.substr(prefix_len,
607 image_key.size() - prefix_len);
608 size_t p = data_string.find("_");
609 if (std::string::npos == p) {
610 return -EIO;
611 }
612 data_string[p] = ' ';
613
614 istringstream iss(data_string);
615 uint64_t pool_id;
616 string image_id;
617 iss >> std::hex >> pool_id >> image_id;
618
619 spec->image_id = image_id;
620 spec->pool_id = pool_id;
621 return 0;
622 }
623
624 std::string GroupImageSpec::image_key() {
625 if (-1 == pool_id)
626 return "";
627 else {
628 ostringstream oss;
629 oss << RBD_GROUP_IMAGE_KEY_PREFIX << std::setw(16)
630 << std::setfill('0') << std::hex << pool_id << "_" << image_id;
631 return oss.str();
632 }
633 }
634
635 void GroupImageSpec::generate_test_instances(std::list<GroupImageSpec*> &o) {
636 o.push_back(new GroupImageSpec("10152ae8944a", 0));
637 o.push_back(new GroupImageSpec("1018643c9869", 3));
638 }
639
640 void GroupImageStatus::encode(bufferlist &bl) const {
641 ENCODE_START(1, 1, bl);
642 encode(spec, bl);
643 encode(state, bl);
644 ENCODE_FINISH(bl);
645 }
646
647 void GroupImageStatus::decode(bufferlist::const_iterator &it) {
648 DECODE_START(1, it);
649 decode(spec, it);
650 decode(state, it);
651 DECODE_FINISH(it);
652 }
653
654 std::string GroupImageStatus::state_to_string() const {
655 std::stringstream ss;
656 if (state == GROUP_IMAGE_LINK_STATE_INCOMPLETE) {
657 ss << "incomplete";
658 }
659 if (state == GROUP_IMAGE_LINK_STATE_ATTACHED) {
660 ss << "attached";
661 }
662 return ss.str();
663 }
664
665 void GroupImageStatus::dump(Formatter *f) const {
666 spec.dump(f);
667 f->dump_string("state", state_to_string());
668 }
669
670 void GroupImageStatus::generate_test_instances(std::list<GroupImageStatus*> &o) {
671 o.push_back(new GroupImageStatus(GroupImageSpec("10152ae8944a", 0), GROUP_IMAGE_LINK_STATE_ATTACHED));
672 o.push_back(new GroupImageStatus(GroupImageSpec("1018643c9869", 3), GROUP_IMAGE_LINK_STATE_ATTACHED));
673 o.push_back(new GroupImageStatus(GroupImageSpec("10152ae8944a", 0), GROUP_IMAGE_LINK_STATE_INCOMPLETE));
674 o.push_back(new GroupImageStatus(GroupImageSpec("1018643c9869", 3), GROUP_IMAGE_LINK_STATE_INCOMPLETE));
675 }
676
677
678 void GroupSpec::encode(bufferlist &bl) const {
679 ENCODE_START(1, 1, bl);
680 encode(pool_id, bl);
681 encode(group_id, bl);
682 ENCODE_FINISH(bl);
683 }
684
685 void GroupSpec::decode(bufferlist::const_iterator &it) {
686 DECODE_START(1, it);
687 decode(pool_id, it);
688 decode(group_id, it);
689 DECODE_FINISH(it);
690 }
691
692 void GroupSpec::dump(Formatter *f) const {
693 f->dump_string("group_id", group_id);
694 f->dump_int("pool_id", pool_id);
695 }
696
697 bool GroupSpec::is_valid() const {
698 return (!group_id.empty()) && (pool_id != -1);
699 }
700
701 void GroupSpec::generate_test_instances(std::list<GroupSpec *> &o) {
702 o.push_back(new GroupSpec("10152ae8944a", 0));
703 o.push_back(new GroupSpec("1018643c9869", 3));
704 }
705
706 void GroupSnapshotNamespace::encode(bufferlist& bl) const {
707 using ceph::encode;
708 encode(group_pool, bl);
709 encode(group_id, bl);
710 encode(group_snapshot_id, bl);
711 }
712
713 void GroupSnapshotNamespace::decode(bufferlist::const_iterator& it) {
714 using ceph::decode;
715 decode(group_pool, it);
716 decode(group_id, it);
717 decode(group_snapshot_id, it);
718 }
719
720 void GroupSnapshotNamespace::dump(Formatter *f) const {
721 f->dump_int("group_pool", group_pool);
722 f->dump_string("group_id", group_id);
723 f->dump_string("group_snapshot_id", group_snapshot_id);
724 }
725
726 void TrashSnapshotNamespace::encode(bufferlist& bl) const {
727 using ceph::encode;
728 encode(original_name, bl);
729 encode(static_cast<uint32_t>(original_snapshot_namespace_type), bl);
730 }
731
732 void TrashSnapshotNamespace::decode(bufferlist::const_iterator& it) {
733 using ceph::decode;
734 decode(original_name, it);
735 uint32_t snap_type;
736 decode(snap_type, it);
737 original_snapshot_namespace_type = static_cast<SnapshotNamespaceType>(
738 snap_type);
739 }
740
741 void TrashSnapshotNamespace::dump(Formatter *f) const {
742 f->dump_string("original_name", original_name);
743 f->dump_stream("original_snapshot_namespace")
744 << original_snapshot_namespace_type;
745 }
746
747 void MirrorSnapshotNamespace::encode(bufferlist& bl) const {
748 using ceph::encode;
749 encode(state, bl);
750 encode(complete, bl);
751 encode(mirror_peer_uuids, bl);
752 encode(primary_mirror_uuid, bl);
753 encode(primary_snap_id, bl);
754 encode(last_copied_object_number, bl);
755 encode(snap_seqs, bl);
756 }
757
758 void MirrorSnapshotNamespace::decode(bufferlist::const_iterator& it) {
759 using ceph::decode;
760 decode(state, it);
761 decode(complete, it);
762 decode(mirror_peer_uuids, it);
763 decode(primary_mirror_uuid, it);
764 decode(primary_snap_id, it);
765 decode(last_copied_object_number, it);
766 decode(snap_seqs, it);
767 }
768
769 void MirrorSnapshotNamespace::dump(Formatter *f) const {
770 f->dump_stream("state") << state;
771 f->dump_bool("complete", complete);
772 f->open_array_section("mirror_peer_uuids");
773 for (auto &peer : mirror_peer_uuids) {
774 f->dump_string("mirror_peer_uuid", peer);
775 }
776 f->close_section();
777 if (is_primary()) {
778 f->dump_unsigned("clean_since_snap_id", clean_since_snap_id);
779 } else {
780 f->dump_string("primary_mirror_uuid", primary_mirror_uuid);
781 f->dump_unsigned("primary_snap_id", primary_snap_id);
782 f->dump_unsigned("last_copied_object_number", last_copied_object_number);
783 f->dump_stream("snap_seqs") << snap_seqs;
784 }
785 }
786
787 class EncodeSnapshotNamespaceVisitor : public boost::static_visitor<void> {
788 public:
789 explicit EncodeSnapshotNamespaceVisitor(bufferlist &bl) : m_bl(bl) {
790 }
791
792 template <typename T>
793 inline void operator()(const T& t) const {
794 using ceph::encode;
795 encode(static_cast<uint32_t>(T::SNAPSHOT_NAMESPACE_TYPE), m_bl);
796 t.encode(m_bl);
797 }
798
799 private:
800 bufferlist &m_bl;
801 };
802
803 class DecodeSnapshotNamespaceVisitor : public boost::static_visitor<void> {
804 public:
805 DecodeSnapshotNamespaceVisitor(bufferlist::const_iterator &iter)
806 : m_iter(iter) {
807 }
808
809 template <typename T>
810 inline void operator()(T& t) const {
811 t.decode(m_iter);
812 }
813 private:
814 bufferlist::const_iterator &m_iter;
815 };
816
817 class DumpSnapshotNamespaceVisitor : public boost::static_visitor<void> {
818 public:
819 explicit DumpSnapshotNamespaceVisitor(Formatter *formatter, const std::string &key)
820 : m_formatter(formatter), m_key(key) {}
821
822 template <typename T>
823 inline void operator()(const T& t) const {
824 auto type = T::SNAPSHOT_NAMESPACE_TYPE;
825 m_formatter->dump_string(m_key.c_str(), stringify(type));
826 t.dump(m_formatter);
827 }
828 private:
829 ceph::Formatter *m_formatter;
830 std::string m_key;
831 };
832
833 class GetTypeVisitor : public boost::static_visitor<SnapshotNamespaceType> {
834 public:
835 template <typename T>
836 inline SnapshotNamespaceType operator()(const T&) const {
837 return static_cast<SnapshotNamespaceType>(T::SNAPSHOT_NAMESPACE_TYPE);
838 }
839 };
840
841 SnapshotNamespaceType get_snap_namespace_type(
842 const SnapshotNamespace& snapshot_namespace) {
843 return static_cast<SnapshotNamespaceType>(boost::apply_visitor(
844 GetTypeVisitor(), snapshot_namespace));
845 }
846
847 void SnapshotInfo::encode(bufferlist& bl) const {
848 ENCODE_START(1, 1, bl);
849 encode(id, bl);
850 encode(snapshot_namespace, bl);
851 encode(name, bl);
852 encode(image_size, bl);
853 encode(timestamp, bl);
854 encode(child_count, bl);
855 ENCODE_FINISH(bl);
856 }
857
858 void SnapshotInfo::decode(bufferlist::const_iterator& it) {
859 DECODE_START(1, it);
860 decode(id, it);
861 decode(snapshot_namespace, it);
862 decode(name, it);
863 decode(image_size, it);
864 decode(timestamp, it);
865 decode(child_count, it);
866 DECODE_FINISH(it);
867 }
868
869 void SnapshotInfo::dump(Formatter *f) const {
870 f->dump_unsigned("id", id);
871 f->open_object_section("namespace");
872 boost::apply_visitor(DumpSnapshotNamespaceVisitor(f, "type"),
873 snapshot_namespace);
874 f->close_section();
875 f->dump_string("name", name);
876 f->dump_unsigned("image_size", image_size);
877 f->dump_stream("timestamp") << timestamp;
878 }
879
880 void SnapshotInfo::generate_test_instances(std::list<SnapshotInfo*> &o) {
881 o.push_back(new SnapshotInfo(1ULL, UserSnapshotNamespace{}, "snap1", 123,
882 {123456, 0}, 12));
883 o.push_back(new SnapshotInfo(2ULL,
884 GroupSnapshotNamespace{567, "group1", "snap1"},
885 "snap1", 123, {123456, 0}, 987));
886 o.push_back(new SnapshotInfo(3ULL,
887 TrashSnapshotNamespace{
888 SNAPSHOT_NAMESPACE_TYPE_USER, "snap1"},
889 "12345", 123, {123456, 0}, 429));
890 o.push_back(new SnapshotInfo(1ULL,
891 MirrorSnapshotNamespace{MIRROR_SNAPSHOT_STATE_PRIMARY,
892 {"1", "2"}, "", CEPH_NOSNAP},
893 "snap1", 123, {123456, 0}, 12));
894 o.push_back(new SnapshotInfo(1ULL,
895 MirrorSnapshotNamespace{MIRROR_SNAPSHOT_STATE_NON_PRIMARY,
896 {"1", "2"}, "uuid", 123},
897 "snap1", 123, {123456, 0}, 12));
898 }
899
900 void SnapshotNamespace::encode(bufferlist& bl) const {
901 ENCODE_START(1, 1, bl);
902 boost::apply_visitor(EncodeSnapshotNamespaceVisitor(bl), *this);
903 ENCODE_FINISH(bl);
904 }
905
906 void SnapshotNamespace::decode(bufferlist::const_iterator &p)
907 {
908 DECODE_START(1, p);
909 uint32_t snap_type;
910 decode(snap_type, p);
911 switch (snap_type) {
912 case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_USER:
913 *this = UserSnapshotNamespace();
914 break;
915 case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_GROUP:
916 *this = GroupSnapshotNamespace();
917 break;
918 case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_TRASH:
919 *this = TrashSnapshotNamespace();
920 break;
921 case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR:
922 *this = MirrorSnapshotNamespace();
923 break;
924 default:
925 *this = UnknownSnapshotNamespace();
926 break;
927 }
928 boost::apply_visitor(DecodeSnapshotNamespaceVisitor(p), *this);
929 DECODE_FINISH(p);
930 }
931
932 void SnapshotNamespace::dump(Formatter *f) const {
933 boost::apply_visitor(
934 DumpSnapshotNamespaceVisitor(f, "snapshot_namespace_type"), *this);
935 }
936
937 void SnapshotNamespace::generate_test_instances(std::list<SnapshotNamespace*> &o) {
938 o.push_back(new SnapshotNamespace(UserSnapshotNamespace()));
939 o.push_back(new SnapshotNamespace(GroupSnapshotNamespace(0, "10152ae8944a",
940 "2118643c9732")));
941 o.push_back(new SnapshotNamespace(GroupSnapshotNamespace(5, "1018643c9869",
942 "33352be8933c")));
943 o.push_back(new SnapshotNamespace(TrashSnapshotNamespace()));
944 o.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_PRIMARY,
945 {"peer uuid"},
946 "", CEPH_NOSNAP)));
947 o.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_PRIMARY_DEMOTED,
948 {"peer uuid"},
949 "", CEPH_NOSNAP)));
950 o.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_NON_PRIMARY,
951 {"peer uuid"},
952 "uuid", 123)));
953 o.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED,
954 {"peer uuid"},
955 "uuid", 123)));
956 }
957
958 std::ostream& operator<<(std::ostream& os, const SnapshotNamespaceType& type) {
959 switch (type) {
960 case SNAPSHOT_NAMESPACE_TYPE_USER:
961 os << "user";
962 break;
963 case SNAPSHOT_NAMESPACE_TYPE_GROUP:
964 os << "group";
965 break;
966 case SNAPSHOT_NAMESPACE_TYPE_TRASH:
967 os << "trash";
968 break;
969 case SNAPSHOT_NAMESPACE_TYPE_MIRROR:
970 os << "mirror";
971 break;
972 default:
973 os << "unknown";
974 break;
975 }
976 return os;
977 }
978
979 std::ostream& operator<<(std::ostream& os, const UserSnapshotNamespace& ns) {
980 os << "[" << SNAPSHOT_NAMESPACE_TYPE_USER << "]";
981 return os;
982 }
983
984 std::ostream& operator<<(std::ostream& os, const GroupSnapshotNamespace& ns) {
985 os << "[" << SNAPSHOT_NAMESPACE_TYPE_GROUP << " "
986 << "group_pool=" << ns.group_pool << ", "
987 << "group_id=" << ns.group_id << ", "
988 << "group_snapshot_id=" << ns.group_snapshot_id << "]";
989 return os;
990 }
991
992 std::ostream& operator<<(std::ostream& os, const TrashSnapshotNamespace& ns) {
993 os << "[" << SNAPSHOT_NAMESPACE_TYPE_TRASH << " "
994 << "original_name=" << ns.original_name << ", "
995 << "original_snapshot_namespace=" << ns.original_snapshot_namespace_type
996 << "]";
997 return os;
998 }
999
1000 std::ostream& operator<<(std::ostream& os, const MirrorSnapshotNamespace& ns) {
1001 os << "[" << SNAPSHOT_NAMESPACE_TYPE_MIRROR << " "
1002 << "state=" << ns.state << ", "
1003 << "complete=" << ns.complete << ", "
1004 << "mirror_peer_uuids=" << ns.mirror_peer_uuids << ", ";
1005 if (ns.is_primary()) {
1006 os << "clean_since_snap_id=" << ns.clean_since_snap_id;
1007 } else {
1008 os << "primary_mirror_uuid=" << ns.primary_mirror_uuid << ", "
1009 << "primary_snap_id=" << ns.primary_snap_id << ", "
1010 << "last_copied_object_number=" << ns.last_copied_object_number << ", "
1011 << "snap_seqs=" << ns.snap_seqs;
1012 }
1013 os << "]";
1014 return os;
1015 }
1016
1017 std::ostream& operator<<(std::ostream& os, const UnknownSnapshotNamespace& ns) {
1018 os << "[unknown]";
1019 return os;
1020 }
1021
1022 std::ostream& operator<<(std::ostream& os, MirrorSnapshotState type) {
1023 switch (type) {
1024 case MIRROR_SNAPSHOT_STATE_PRIMARY:
1025 os << "primary";
1026 break;
1027 case MIRROR_SNAPSHOT_STATE_PRIMARY_DEMOTED:
1028 os << "primary (demoted)";
1029 break;
1030 case MIRROR_SNAPSHOT_STATE_NON_PRIMARY:
1031 os << "non-primary";
1032 break;
1033 case MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED:
1034 os << "non-primary (demoted)";
1035 break;
1036 default:
1037 os << "unknown";
1038 break;
1039 }
1040 return os;
1041 }
1042
1043 void ImageSnapshotSpec::encode(bufferlist& bl) const {
1044 using ceph::encode;
1045 ENCODE_START(1, 1, bl);
1046 encode(pool, bl);
1047 encode(image_id, bl);
1048 encode(snap_id, bl);
1049 ENCODE_FINISH(bl);
1050 }
1051
1052 void ImageSnapshotSpec::decode(bufferlist::const_iterator& it) {
1053 using ceph::decode;
1054 DECODE_START(1, it);
1055 decode(pool, it);
1056 decode(image_id, it);
1057 decode(snap_id, it);
1058 DECODE_FINISH(it);
1059 }
1060
1061 void ImageSnapshotSpec::dump(Formatter *f) const {
1062 f->dump_int("pool", pool);
1063 f->dump_string("image_id", image_id);
1064 f->dump_int("snap_id", snap_id);
1065 }
1066
1067 void ImageSnapshotSpec::generate_test_instances(std::list<ImageSnapshotSpec *> &o) {
1068 o.push_back(new ImageSnapshotSpec(0, "myimage", 2));
1069 o.push_back(new ImageSnapshotSpec(1, "testimage", 7));
1070 }
1071
1072 void GroupSnapshot::encode(bufferlist& bl) const {
1073 using ceph::encode;
1074 ENCODE_START(1, 1, bl);
1075 encode(id, bl);
1076 encode(name, bl);
1077 encode(state, bl);
1078 encode(snaps, bl);
1079 ENCODE_FINISH(bl);
1080 }
1081
1082 void GroupSnapshot::decode(bufferlist::const_iterator& it) {
1083 using ceph::decode;
1084 DECODE_START(1, it);
1085 decode(id, it);
1086 decode(name, it);
1087 decode(state, it);
1088 decode(snaps, it);
1089 DECODE_FINISH(it);
1090 }
1091
1092 void GroupSnapshot::dump(Formatter *f) const {
1093 f->dump_string("id", id);
1094 f->dump_string("name", name);
1095 f->dump_int("state", state);
1096 }
1097
1098 void GroupSnapshot::generate_test_instances(std::list<GroupSnapshot *> &o) {
1099 o.push_back(new GroupSnapshot("10152ae8944a", "groupsnapshot1", GROUP_SNAPSHOT_STATE_INCOMPLETE));
1100 o.push_back(new GroupSnapshot("1018643c9869", "groupsnapshot2", GROUP_SNAPSHOT_STATE_COMPLETE));
1101 }
1102 void TrashImageSpec::encode(bufferlist& bl) const {
1103 ENCODE_START(2, 1, bl);
1104 encode(source, bl);
1105 encode(name, bl);
1106 encode(deletion_time, bl);
1107 encode(deferment_end_time, bl);
1108 encode(state, bl);
1109 ENCODE_FINISH(bl);
1110 }
1111
1112 void TrashImageSpec::decode(bufferlist::const_iterator &it) {
1113 DECODE_START(2, it);
1114 decode(source, it);
1115 decode(name, it);
1116 decode(deletion_time, it);
1117 decode(deferment_end_time, it);
1118 if (struct_v >= 2) {
1119 decode(state, it);
1120 }
1121 DECODE_FINISH(it);
1122 }
1123
1124 void TrashImageSpec::dump(Formatter *f) const {
1125 f->dump_stream("source") << source;
1126 f->dump_string("name", name);
1127 f->dump_unsigned("deletion_time", deletion_time);
1128 f->dump_unsigned("deferment_end_time", deferment_end_time);
1129 }
1130
1131 void MirrorImageMap::encode(bufferlist &bl) const {
1132 ENCODE_START(1, 1, bl);
1133 encode(instance_id, bl);
1134 encode(mapped_time, bl);
1135 encode(data, bl);
1136 ENCODE_FINISH(bl);
1137 }
1138
1139 void MirrorImageMap::decode(bufferlist::const_iterator &it) {
1140 DECODE_START(1, it);
1141 decode(instance_id, it);
1142 decode(mapped_time, it);
1143 decode(data, it);
1144 DECODE_FINISH(it);
1145 }
1146
1147 void MirrorImageMap::dump(Formatter *f) const {
1148 f->dump_string("instance_id", instance_id);
1149 f->dump_stream("mapped_time") << mapped_time;
1150
1151 std::stringstream data_ss;
1152 data.hexdump(data_ss);
1153 f->dump_string("data", data_ss.str());
1154 }
1155
1156 void MirrorImageMap::generate_test_instances(
1157 std::list<MirrorImageMap*> &o) {
1158 bufferlist data;
1159 data.append(std::string(128, '1'));
1160
1161 o.push_back(new MirrorImageMap("uuid-123", utime_t(), data));
1162 o.push_back(new MirrorImageMap("uuid-abc", utime_t(), data));
1163 }
1164
1165 bool MirrorImageMap::operator==(const MirrorImageMap &rhs) const {
1166 return instance_id == rhs.instance_id && mapped_time == rhs.mapped_time &&
1167 data.contents_equal(rhs.data);
1168 }
1169
1170 bool MirrorImageMap::operator<(const MirrorImageMap &rhs) const {
1171 return instance_id < rhs.instance_id ||
1172 (instance_id == rhs.instance_id && mapped_time < rhs.mapped_time);
1173 }
1174
1175 std::ostream& operator<<(std::ostream& os,
1176 const MirrorImageMap &image_map) {
1177 return os << "[" << "instance_id=" << image_map.instance_id << ", mapped_time="
1178 << image_map.mapped_time << "]";
1179 }
1180
1181 std::ostream& operator<<(std::ostream& os,
1182 const MigrationHeaderType& type) {
1183 switch (type) {
1184 case MIGRATION_HEADER_TYPE_SRC:
1185 os << "source";
1186 break;
1187 case MIGRATION_HEADER_TYPE_DST:
1188 os << "destination";
1189 break;
1190 default:
1191 os << "unknown (" << static_cast<uint32_t>(type) << ")";
1192 break;
1193 }
1194 return os;
1195 }
1196
1197 std::ostream& operator<<(std::ostream& os,
1198 const MigrationState& migration_state) {
1199 switch (migration_state) {
1200 case MIGRATION_STATE_ERROR:
1201 os << "error";
1202 break;
1203 case MIGRATION_STATE_PREPARING:
1204 os << "preparing";
1205 break;
1206 case MIGRATION_STATE_PREPARED:
1207 os << "prepared";
1208 break;
1209 case MIGRATION_STATE_EXECUTING:
1210 os << "executing";
1211 break;
1212 case MIGRATION_STATE_EXECUTED:
1213 os << "executed";
1214 break;
1215 case MIGRATION_STATE_ABORTING:
1216 os << "aborting";
1217 break;
1218 default:
1219 os << "unknown (" << static_cast<uint32_t>(migration_state) << ")";
1220 break;
1221 }
1222 return os;
1223 }
1224
1225 void MigrationSpec::encode(bufferlist& bl) const {
1226 uint8_t min_version = 1;
1227 if (!source_spec.empty()) {
1228 min_version = 3;
1229 }
1230
1231 ENCODE_START(3, min_version, bl);
1232 encode(header_type, bl);
1233 encode(pool_id, bl);
1234 encode(pool_namespace, bl);
1235 encode(image_name, bl);
1236 encode(image_id, bl);
1237 encode(snap_seqs, bl);
1238 encode(overlap, bl);
1239 encode(flatten, bl);
1240 encode(mirroring, bl);
1241 encode(state, bl);
1242 encode(state_description, bl);
1243 encode(static_cast<uint8_t>(mirror_image_mode), bl);
1244 encode(source_spec, bl);
1245 ENCODE_FINISH(bl);
1246 }
1247
1248 void MigrationSpec::decode(bufferlist::const_iterator& bl) {
1249 DECODE_START(3, bl);
1250 decode(header_type, bl);
1251 decode(pool_id, bl);
1252 decode(pool_namespace, bl);
1253 decode(image_name, bl);
1254 decode(image_id, bl);
1255 decode(snap_seqs, bl);
1256 decode(overlap, bl);
1257 decode(flatten, bl);
1258 decode(mirroring, bl);
1259 decode(state, bl);
1260 decode(state_description, bl);
1261 if (struct_v >= 2) {
1262 uint8_t int_mode;
1263 decode(int_mode, bl);
1264 mirror_image_mode = static_cast<MirrorImageMode>(int_mode);
1265 }
1266 if (struct_v >= 3) {
1267 decode(source_spec, bl);
1268 }
1269 DECODE_FINISH(bl);
1270 }
1271
1272 std::ostream& operator<<(std::ostream& os,
1273 const std::map<uint64_t, uint64_t>& snap_seqs) {
1274 os << "{";
1275 size_t count = 0;
1276 for (auto &it : snap_seqs) {
1277 os << (count++ > 0 ? ", " : "") << "(" << it.first << ", " << it.second
1278 << ")";
1279 }
1280 os << "}";
1281 return os;
1282 }
1283
1284 void MigrationSpec::dump(Formatter *f) const {
1285 f->dump_stream("header_type") << header_type;
1286 if (header_type == MIGRATION_HEADER_TYPE_SRC ||
1287 source_spec.empty()) {
1288 f->dump_int("pool_id", pool_id);
1289 f->dump_string("pool_namespace", pool_namespace);
1290 f->dump_string("image_name", image_name);
1291 f->dump_string("image_id", image_id);
1292 } else {
1293 f->dump_string("source_spec", source_spec);
1294 }
1295 f->dump_stream("snap_seqs") << snap_seqs;
1296 f->dump_unsigned("overlap", overlap);
1297 f->dump_bool("mirroring", mirroring);
1298 f->dump_stream("mirror_image_mode") << mirror_image_mode;
1299 }
1300
1301 void MigrationSpec::generate_test_instances(std::list<MigrationSpec*> &o) {
1302 o.push_back(new MigrationSpec());
1303 o.push_back(new MigrationSpec(MIGRATION_HEADER_TYPE_SRC, 1, "ns",
1304 "image_name", "image_id", "", {{1, 2}}, 123,
1305 true, MIRROR_IMAGE_MODE_SNAPSHOT, true,
1306 MIGRATION_STATE_PREPARED, "description"));
1307 o.push_back(new MigrationSpec(MIGRATION_HEADER_TYPE_DST, -1, "", "", "",
1308 "{\"format\": \"raw\"}", {{1, 2}}, 123,
1309 true, MIRROR_IMAGE_MODE_SNAPSHOT, true,
1310 MIGRATION_STATE_PREPARED, "description"));
1311 }
1312
1313 std::ostream& operator<<(std::ostream& os,
1314 const MigrationSpec& migration_spec) {
1315 os << "["
1316 << "header_type=" << migration_spec.header_type << ", ";
1317 if (migration_spec.header_type == MIGRATION_HEADER_TYPE_SRC ||
1318 migration_spec.source_spec.empty()) {
1319 os << "pool_id=" << migration_spec.pool_id << ", "
1320 << "pool_namespace=" << migration_spec.pool_namespace << ", "
1321 << "image_name=" << migration_spec.image_name << ", "
1322 << "image_id=" << migration_spec.image_id << ", ";
1323 } else {
1324 os << "source_spec=" << migration_spec.source_spec << ", ";
1325 }
1326 os << "snap_seqs=" << migration_spec.snap_seqs << ", "
1327 << "overlap=" << migration_spec.overlap << ", "
1328 << "flatten=" << migration_spec.flatten << ", "
1329 << "mirroring=" << migration_spec.mirroring << ", "
1330 << "mirror_image_mode=" << migration_spec.mirror_image_mode << ", "
1331 << "state=" << migration_spec.state << ", "
1332 << "state_description=" << migration_spec.state_description << "]";
1333 return os;
1334 }
1335
1336 std::ostream& operator<<(std::ostream& os, const AssertSnapcSeqState& state) {
1337 switch (state) {
1338 case ASSERT_SNAPC_SEQ_GT_SNAPSET_SEQ:
1339 os << "gt";
1340 break;
1341 case ASSERT_SNAPC_SEQ_LE_SNAPSET_SEQ:
1342 os << "le";
1343 break;
1344 default:
1345 os << "unknown (" << static_cast<uint32_t>(state) << ")";
1346 break;
1347 }
1348 return os;
1349 }
1350
1351 void sanitize_entity_inst(entity_inst_t* entity_inst) {
1352 // make all addrs of type ANY because the type isn't what uniquely
1353 // identifies them and clients and on-disk formats can be encoded
1354 // with different backwards compatibility settings.
1355 entity_inst->addr.set_type(entity_addr_t::TYPE_ANY);
1356 }
1357
1358 } // namespace rbd
1359 } // namespace cls