1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include <boost/variant.hpp>
5 #include "cls/rbd/cls_rbd_types.h"
6 #include "common/Formatter.h"
11 using std::istringstream
;
12 using std::ostringstream
;
15 using ceph::bufferlist
;
16 using ceph::Formatter
;
18 std::ostream
& operator<<(std::ostream
& os
,
19 MirrorPeerDirection mirror_peer_direction
) {
20 switch (mirror_peer_direction
) {
21 case MIRROR_PEER_DIRECTION_RX
:
24 case MIRROR_PEER_DIRECTION_TX
:
27 case MIRROR_PEER_DIRECTION_RX_TX
:
37 void MirrorPeer::encode(bufferlist
&bl
) const {
38 ENCODE_START(2, 1, bl
);
40 encode(site_name
, bl
);
41 encode(client_name
, bl
);
46 encode(static_cast<uint8_t>(mirror_peer_direction
), bl
);
47 encode(mirror_uuid
, bl
);
48 encode(last_seen
, bl
);
52 void MirrorPeer::decode(bufferlist::const_iterator
&it
) {
55 decode(site_name
, it
);
56 decode(client_name
, it
);
63 mirror_peer_direction
= static_cast<MirrorPeerDirection
>(mpd
);
64 decode(mirror_uuid
, it
);
65 decode(last_seen
, it
);
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
;
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",
84 o
.push_back(new MirrorPeer("uuid-234", MIRROR_PEER_DIRECTION_TX
, "site B",
86 o
.push_back(new MirrorPeer("uuid-345", MIRROR_PEER_DIRECTION_RX_TX
, "site C",
87 "client name", "mirror_uuid"));
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
);
99 std::ostream
& operator<<(std::ostream
& os
, const MirrorMode
& mirror_mode
) {
100 switch (mirror_mode
) {
101 case MIRROR_MODE_DISABLED
:
104 case MIRROR_MODE_IMAGE
:
107 case MIRROR_MODE_POOL
:
111 os
<< "unknown (" << static_cast<uint32_t>(mirror_mode
) << ")";
117 std::ostream
& operator<<(std::ostream
& os
, const MirrorPeer
& peer
) {
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
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
);
137 void MirrorImage::decode(bufferlist::const_iterator
&it
) {
140 decode(global_image_id
, it
);
141 decode(int_state
, it
);
142 state
= static_cast<MirrorImageState
>(int_state
);
145 decode(int_mode
, it
);
146 mode
= static_cast<MirrorImageMode
>(int_mode
);
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
;
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
));
165 bool MirrorImage::operator==(const MirrorImage
&rhs
) const {
166 return mode
== rhs
.mode
&& global_image_id
== rhs
.global_image_id
&&
170 bool MirrorImage::operator<(const MirrorImage
&rhs
) const {
171 if (mode
!= rhs
.mode
) {
172 return mode
< rhs
.mode
;
174 if (global_image_id
!= rhs
.global_image_id
) {
175 return global_image_id
< rhs
.global_image_id
;
177 return state
< rhs
.state
;
180 std::ostream
& operator<<(std::ostream
& os
, const MirrorImageMode
& mirror_mode
) {
181 switch (mirror_mode
) {
182 case MIRROR_IMAGE_MODE_JOURNAL
:
185 case MIRROR_IMAGE_MODE_SNAPSHOT
:
189 os
<< "unknown (" << static_cast<uint32_t>(mirror_mode
) << ")";
195 std::ostream
& operator<<(std::ostream
& os
, const MirrorImageState
& mirror_state
) {
196 switch (mirror_state
) {
197 case MIRROR_IMAGE_STATE_DISABLING
:
200 case MIRROR_IMAGE_STATE_ENABLED
:
203 case MIRROR_IMAGE_STATE_DISABLED
:
207 os
<< "unknown (" << static_cast<uint32_t>(mirror_state
) << ")";
213 std::ostream
& operator<<(std::ostream
& os
, const MirrorImage
& mirror_image
) {
215 << "mode=" << mirror_image
.mode
<< ", "
216 << "global_image_id=" << mirror_image
.global_image_id
<< ", "
217 << "state=" << mirror_image
.state
<< "]";
221 std::ostream
& operator<<(std::ostream
& os
,
222 const MirrorImageStatusState
& state
) {
224 case MIRROR_IMAGE_STATUS_STATE_UNKNOWN
:
227 case MIRROR_IMAGE_STATUS_STATE_ERROR
:
230 case MIRROR_IMAGE_STATUS_STATE_SYNCING
:
233 case MIRROR_IMAGE_STATUS_STATE_STARTING_REPLAY
:
234 os
<< "starting_replay";
236 case MIRROR_IMAGE_STATUS_STATE_REPLAYING
:
239 case MIRROR_IMAGE_STATUS_STATE_STOPPING_REPLAY
:
240 os
<< "stopping_replay";
242 case MIRROR_IMAGE_STATUS_STATE_STOPPED
:
246 os
<< "unknown (" << static_cast<uint32_t>(state
) << ")";
252 const std::string
MirrorImageSiteStatus::LOCAL_MIRROR_UUID(""); // empty mirror uuid
254 void MirrorImageSiteStatus::encode_meta(uint8_t version
, bufferlist
&bl
) const {
256 ceph::encode(mirror_uuid
, bl
);
258 cls::rbd::encode(state
, bl
);
259 ceph::encode(description
, bl
);
260 ceph::encode(last_update
, bl
);
261 ceph::encode(up
, bl
);
264 void MirrorImageSiteStatus::decode_meta(uint8_t version
,
265 bufferlist::const_iterator
&it
) {
267 mirror_uuid
= LOCAL_MIRROR_UUID
;
269 ceph::decode(mirror_uuid
, it
);
272 cls::rbd::decode(state
, it
);
273 ceph::decode(description
, it
);
274 ::decode(last_update
, it
);
275 ceph::decode(up
, it
);
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
);
286 void MirrorImageSiteStatus::decode(bufferlist::const_iterator
&it
) {
288 decode_meta(struct_v
, it
);
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
;
298 std::string
MirrorImageSiteStatus::state_to_string() const {
299 std::stringstream ss
;
300 ss
<< (up
? "up+" : "down+") << state
;
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
,
309 o
.push_back(new MirrorImageSiteStatus("", MIRROR_IMAGE_STATUS_STATE_ERROR
,
311 o
.push_back(new MirrorImageSiteStatus("2fb68ca9-1ba0-43b3-8cdf-8c5a9db71e65",
312 MIRROR_IMAGE_STATUS_STATE_STOPPED
, ""));
315 bool MirrorImageSiteStatus::operator==(const MirrorImageSiteStatus
&rhs
) const {
316 return state
== rhs
.state
&& description
== rhs
.description
&& up
== rhs
.up
;
319 std::ostream
& operator<<(std::ostream
& os
,
320 const MirrorImageSiteStatus
& status
) {
322 << "state=" << status
.state_to_string() << ", "
323 << "description=" << status
.description
<< ", "
324 << "last_update=" << status
.last_update
<< "]}";
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
);
337 void MirrorImageSiteStatusOnDisk::encode(bufferlist
&bl
,
338 uint64_t features
) const {
339 encode_meta(bl
, features
);
340 cls::rbd::MirrorImageSiteStatus::encode(bl
);
343 void MirrorImageSiteStatusOnDisk::decode_meta(bufferlist::const_iterator
&it
) {
346 sanitize_entity_inst(&origin
);
350 void MirrorImageSiteStatusOnDisk::decode(bufferlist::const_iterator
&it
) {
352 cls::rbd::MirrorImageSiteStatus::decode(it
);
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
, ""}));
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
;
372 if (it
== mirror_image_site_statuses
.end()) {
380 void MirrorImageStatus::encode(bufferlist
&bl
) const {
381 // don't break compatibility for extra site statuses
382 ENCODE_START(2, 1, bl
);
385 MirrorImageSiteStatus local_status
;
386 int r
= get_local_mirror_image_site_status(&local_status
);
387 local_status
.encode_meta(1, bl
);
389 bool local_status_valid
= (r
>= 0);
390 encode(local_status_valid
, bl
);
392 // remote site statuses
393 __u32 n
= mirror_image_site_statuses
.size();
394 if (local_status_valid
) {
399 for (auto& status
: mirror_image_site_statuses
) {
400 if (status
.mirror_uuid
== MirrorImageSiteStatus::LOCAL_MIRROR_UUID
) {
403 status
.encode_meta(2, bl
);
408 void MirrorImageStatus::decode(bufferlist::const_iterator
&it
) {
412 MirrorImageSiteStatus local_status
;
413 local_status
.decode_meta(1, it
);
416 mirror_image_site_statuses
.push_back(local_status
);
418 bool local_status_valid
;
419 decode(local_status_valid
, it
);
423 if (local_status_valid
) {
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
;
436 // remote site status
437 status_it
->decode_meta(struct_v
, it
);
443 void MirrorImageStatus::dump(Formatter
*f
) const {
444 MirrorImageSiteStatus local_status
;
445 int r
= get_local_mirror_image_site_status(&local_status
);
447 local_status
.dump(f
);
450 f
->open_array_section("remotes");
451 for (auto& status
: mirror_image_site_statuses
) {
452 if (status
.mirror_uuid
== MirrorImageSiteStatus::LOCAL_MIRROR_UUID
) {
456 f
->open_object_section("remote");
463 bool MirrorImageStatus::operator==(const MirrorImageStatus
&rhs
) const {
464 return (mirror_image_site_statuses
== rhs
.mirror_image_site_statuses
);
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
, ""}}));
475 std::ostream
& operator<<(std::ostream
& os
,
476 const MirrorImageStatus
& status
) {
478 MirrorImageSiteStatus local_status
;
479 int r
= status
.get_local_mirror_image_site_status(&local_status
);
481 os
<< "state=" << local_status
.state_to_string() << ", "
482 << "description=" << local_status
.description
<< ", "
483 << "last_update=" << local_status
.last_update
<< ", ";
487 for (auto& remote_status
: status
.mirror_image_site_statuses
) {
488 if (remote_status
.mirror_uuid
== MirrorImageSiteStatus::LOCAL_MIRROR_UUID
) {
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
503 void ParentImageSpec::encode(bufferlist
& bl
) const {
504 ENCODE_START(1, 1, bl
);
506 encode(pool_namespace
, bl
);
507 encode(image_id
, bl
);
512 void ParentImageSpec::decode(bufferlist::const_iterator
& bl
) {
515 decode(pool_namespace
, bl
);
516 decode(image_id
, bl
);
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
);
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});
534 std::ostream
& operator<<(std::ostream
& os
, const ParentImageSpec
& rhs
) {
536 << "pool_id=" << rhs
.pool_id
<< ", "
537 << "pool_namespace=" << rhs
.pool_namespace
<< ", "
538 << "image_id=" << rhs
.image_id
<< ", "
539 << "snap_id=" << rhs
.snap_id
544 void ChildImageSpec::encode(bufferlist
&bl
) const {
545 ENCODE_START(2, 1, bl
);
547 encode(image_id
, bl
);
548 encode(pool_namespace
, bl
);
552 void ChildImageSpec::decode(bufferlist::const_iterator
&it
) {
555 decode(image_id
, it
);
557 decode(pool_namespace
, it
);
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
);
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"));
574 std::ostream
& operator<<(std::ostream
& os
, const ChildImageSpec
& rhs
) {
576 << "pool_id=" << rhs
.pool_id
<< ", "
577 << "pool_namespace=" << rhs
.pool_namespace
<< ", "
578 << "image_id=" << rhs
.image_id
583 void GroupImageSpec::encode(bufferlist
&bl
) const {
584 ENCODE_START(1, 1, bl
);
585 encode(image_id
, bl
);
590 void GroupImageSpec::decode(bufferlist::const_iterator
&it
) {
592 decode(image_id
, it
);
597 void GroupImageSpec::dump(Formatter
*f
) const {
598 f
->dump_string("image_id", image_id
);
599 f
->dump_int("pool_id", pool_id
);
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
) {
612 data_string
[p
] = ' ';
614 istringstream
iss(data_string
);
617 iss
>> std::hex
>> pool_id
>> image_id
;
619 spec
->image_id
= image_id
;
620 spec
->pool_id
= pool_id
;
624 std::string
GroupImageSpec::image_key() {
629 oss
<< RBD_GROUP_IMAGE_KEY_PREFIX
<< std::setw(16)
630 << std::setfill('0') << std::hex
<< pool_id
<< "_" << image_id
;
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));
640 void GroupImageStatus::encode(bufferlist
&bl
) const {
641 ENCODE_START(1, 1, bl
);
647 void GroupImageStatus::decode(bufferlist::const_iterator
&it
) {
654 std::string
GroupImageStatus::state_to_string() const {
655 std::stringstream ss
;
656 if (state
== GROUP_IMAGE_LINK_STATE_INCOMPLETE
) {
659 if (state
== GROUP_IMAGE_LINK_STATE_ATTACHED
) {
665 void GroupImageStatus::dump(Formatter
*f
) const {
667 f
->dump_string("state", state_to_string());
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
));
678 void GroupSpec::encode(bufferlist
&bl
) const {
679 ENCODE_START(1, 1, bl
);
681 encode(group_id
, bl
);
685 void GroupSpec::decode(bufferlist::const_iterator
&it
) {
688 decode(group_id
, it
);
692 void GroupSpec::dump(Formatter
*f
) const {
693 f
->dump_string("group_id", group_id
);
694 f
->dump_int("pool_id", pool_id
);
697 bool GroupSpec::is_valid() const {
698 return (!group_id
.empty()) && (pool_id
!= -1);
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));
706 void GroupSnapshotNamespace::encode(bufferlist
& bl
) const {
708 encode(group_pool
, bl
);
709 encode(group_id
, bl
);
710 encode(group_snapshot_id
, bl
);
713 void GroupSnapshotNamespace::decode(bufferlist::const_iterator
& it
) {
715 decode(group_pool
, it
);
716 decode(group_id
, it
);
717 decode(group_snapshot_id
, it
);
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
);
726 void TrashSnapshotNamespace::encode(bufferlist
& bl
) const {
728 encode(original_name
, bl
);
729 encode(static_cast<uint32_t>(original_snapshot_namespace_type
), bl
);
732 void TrashSnapshotNamespace::decode(bufferlist::const_iterator
& it
) {
734 decode(original_name
, it
);
736 decode(snap_type
, it
);
737 original_snapshot_namespace_type
= static_cast<SnapshotNamespaceType
>(
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
;
747 void MirrorSnapshotNamespace::encode(bufferlist
& bl
) const {
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
);
758 void MirrorSnapshotNamespace::decode(bufferlist::const_iterator
& 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
);
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
);
778 f
->dump_unsigned("clean_since_snap_id", clean_since_snap_id
);
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
;
787 class EncodeSnapshotNamespaceVisitor
{
789 explicit EncodeSnapshotNamespaceVisitor(bufferlist
&bl
) : m_bl(bl
) {
792 template <typename T
>
793 inline void operator()(const T
& t
) const {
795 encode(static_cast<uint32_t>(T::SNAPSHOT_NAMESPACE_TYPE
), m_bl
);
803 class DecodeSnapshotNamespaceVisitor
{
805 DecodeSnapshotNamespaceVisitor(bufferlist::const_iterator
&iter
)
809 template <typename T
>
810 inline void operator()(T
& t
) const {
814 bufferlist::const_iterator
&m_iter
;
817 class DumpSnapshotNamespaceVisitor
{
819 explicit DumpSnapshotNamespaceVisitor(Formatter
*formatter
, const std::string
&key
)
820 : m_formatter(formatter
), m_key(key
) {}
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
));
829 ceph::Formatter
*m_formatter
;
833 class GetTypeVisitor
{
835 template <typename T
>
836 inline SnapshotNamespaceType
operator()(const T
&) const {
837 return static_cast<SnapshotNamespaceType
>(T::SNAPSHOT_NAMESPACE_TYPE
);
841 SnapshotNamespaceType
get_snap_namespace_type(
842 const SnapshotNamespace
& snapshot_namespace
) {
843 return static_cast<SnapshotNamespaceType
>(snapshot_namespace
.visit(
847 void SnapshotInfo::encode(bufferlist
& bl
) const {
848 ENCODE_START(1, 1, bl
);
850 encode(snapshot_namespace
, bl
);
852 encode(image_size
, bl
);
853 encode(timestamp
, bl
);
854 encode(child_count
, bl
);
858 void SnapshotInfo::decode(bufferlist::const_iterator
& it
) {
861 decode(snapshot_namespace
, it
);
863 decode(image_size
, it
);
864 decode(timestamp
, it
);
865 decode(child_count
, it
);
869 void SnapshotInfo::dump(Formatter
*f
) const {
870 f
->dump_unsigned("id", id
);
871 f
->open_object_section("namespace");
872 snapshot_namespace
.visit(DumpSnapshotNamespaceVisitor(f
, "type"));
874 f
->dump_string("name", name
);
875 f
->dump_unsigned("image_size", image_size
);
876 f
->dump_stream("timestamp") << timestamp
;
879 void SnapshotInfo::generate_test_instances(std::list
<SnapshotInfo
*> &o
) {
880 o
.push_back(new SnapshotInfo(1ULL, UserSnapshotNamespace
{}, "snap1", 123,
882 o
.push_back(new SnapshotInfo(2ULL,
883 GroupSnapshotNamespace
{567, "group1", "snap1"},
884 "snap1", 123, {123456, 0}, 987));
885 o
.push_back(new SnapshotInfo(3ULL,
886 TrashSnapshotNamespace
{
887 SNAPSHOT_NAMESPACE_TYPE_USER
, "snap1"},
888 "12345", 123, {123456, 0}, 429));
889 o
.push_back(new SnapshotInfo(1ULL,
890 MirrorSnapshotNamespace
{MIRROR_SNAPSHOT_STATE_PRIMARY
,
891 {"1", "2"}, "", CEPH_NOSNAP
},
892 "snap1", 123, {123456, 0}, 12));
893 o
.push_back(new SnapshotInfo(1ULL,
894 MirrorSnapshotNamespace
{MIRROR_SNAPSHOT_STATE_NON_PRIMARY
,
895 {"1", "2"}, "uuid", 123},
896 "snap1", 123, {123456, 0}, 12));
899 void SnapshotNamespace::encode(bufferlist
& bl
) const {
900 ENCODE_START(1, 1, bl
);
901 visit(EncodeSnapshotNamespaceVisitor(bl
));
905 void SnapshotNamespace::decode(bufferlist::const_iterator
&p
)
909 decode(snap_type
, p
);
911 case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_USER
:
912 *this = UserSnapshotNamespace();
914 case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_GROUP
:
915 *this = GroupSnapshotNamespace();
917 case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_TRASH
:
918 *this = TrashSnapshotNamespace();
920 case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR
:
921 *this = MirrorSnapshotNamespace();
924 *this = UnknownSnapshotNamespace();
927 visit(DecodeSnapshotNamespaceVisitor(p
));
931 void SnapshotNamespace::dump(Formatter
*f
) const {
932 visit(DumpSnapshotNamespaceVisitor(f
, "snapshot_namespace_type"));
935 void SnapshotNamespace::generate_test_instances(std::list
<SnapshotNamespace
*> &o
) {
936 o
.push_back(new SnapshotNamespace(UserSnapshotNamespace()));
937 o
.push_back(new SnapshotNamespace(GroupSnapshotNamespace(0, "10152ae8944a",
939 o
.push_back(new SnapshotNamespace(GroupSnapshotNamespace(5, "1018643c9869",
941 o
.push_back(new SnapshotNamespace(TrashSnapshotNamespace()));
942 o
.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_PRIMARY
,
945 o
.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_PRIMARY_DEMOTED
,
948 o
.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_NON_PRIMARY
,
951 o
.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED
,
956 std::ostream
& operator<<(std::ostream
& os
, const SnapshotNamespace
& ns
) {
957 return ns
.visit([&os
](const auto& val
) -> std::ostream
& {
962 std::ostream
& operator<<(std::ostream
& os
, const SnapshotNamespaceType
& type
) {
964 case SNAPSHOT_NAMESPACE_TYPE_USER
:
967 case SNAPSHOT_NAMESPACE_TYPE_GROUP
:
970 case SNAPSHOT_NAMESPACE_TYPE_TRASH
:
973 case SNAPSHOT_NAMESPACE_TYPE_MIRROR
:
983 std::ostream
& operator<<(std::ostream
& os
, const UserSnapshotNamespace
& ns
) {
984 os
<< "[" << SNAPSHOT_NAMESPACE_TYPE_USER
<< "]";
988 std::ostream
& operator<<(std::ostream
& os
, const GroupSnapshotNamespace
& ns
) {
989 os
<< "[" << SNAPSHOT_NAMESPACE_TYPE_GROUP
<< " "
990 << "group_pool=" << ns
.group_pool
<< ", "
991 << "group_id=" << ns
.group_id
<< ", "
992 << "group_snapshot_id=" << ns
.group_snapshot_id
<< "]";
996 std::ostream
& operator<<(std::ostream
& os
, const TrashSnapshotNamespace
& ns
) {
997 os
<< "[" << SNAPSHOT_NAMESPACE_TYPE_TRASH
<< " "
998 << "original_name=" << ns
.original_name
<< ", "
999 << "original_snapshot_namespace=" << ns
.original_snapshot_namespace_type
1004 std::ostream
& operator<<(std::ostream
& os
, const MirrorSnapshotNamespace
& ns
) {
1005 os
<< "[" << SNAPSHOT_NAMESPACE_TYPE_MIRROR
<< " "
1006 << "state=" << ns
.state
<< ", "
1007 << "complete=" << ns
.complete
<< ", "
1008 << "mirror_peer_uuids=" << ns
.mirror_peer_uuids
<< ", ";
1009 if (ns
.is_primary()) {
1010 os
<< "clean_since_snap_id=" << ns
.clean_since_snap_id
;
1012 os
<< "primary_mirror_uuid=" << ns
.primary_mirror_uuid
<< ", "
1013 << "primary_snap_id=" << ns
.primary_snap_id
<< ", "
1014 << "last_copied_object_number=" << ns
.last_copied_object_number
<< ", "
1015 << "snap_seqs=" << ns
.snap_seqs
;
1021 std::ostream
& operator<<(std::ostream
& os
, const UnknownSnapshotNamespace
& ns
) {
1026 std::ostream
& operator<<(std::ostream
& os
, MirrorSnapshotState type
) {
1028 case MIRROR_SNAPSHOT_STATE_PRIMARY
:
1031 case MIRROR_SNAPSHOT_STATE_PRIMARY_DEMOTED
:
1032 os
<< "primary (demoted)";
1034 case MIRROR_SNAPSHOT_STATE_NON_PRIMARY
:
1035 os
<< "non-primary";
1037 case MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED
:
1038 os
<< "non-primary (demoted)";
1047 void ImageSnapshotSpec::encode(bufferlist
& bl
) const {
1049 ENCODE_START(1, 1, bl
);
1051 encode(image_id
, bl
);
1052 encode(snap_id
, bl
);
1056 void ImageSnapshotSpec::decode(bufferlist::const_iterator
& it
) {
1058 DECODE_START(1, it
);
1060 decode(image_id
, it
);
1061 decode(snap_id
, it
);
1065 void ImageSnapshotSpec::dump(Formatter
*f
) const {
1066 f
->dump_int("pool", pool
);
1067 f
->dump_string("image_id", image_id
);
1068 f
->dump_int("snap_id", snap_id
);
1071 void ImageSnapshotSpec::generate_test_instances(std::list
<ImageSnapshotSpec
*> &o
) {
1072 o
.push_back(new ImageSnapshotSpec(0, "myimage", 2));
1073 o
.push_back(new ImageSnapshotSpec(1, "testimage", 7));
1076 void GroupSnapshot::encode(bufferlist
& bl
) const {
1078 ENCODE_START(1, 1, bl
);
1086 void GroupSnapshot::decode(bufferlist::const_iterator
& it
) {
1088 DECODE_START(1, it
);
1096 void GroupSnapshot::dump(Formatter
*f
) const {
1097 f
->dump_string("id", id
);
1098 f
->dump_string("name", name
);
1099 f
->dump_int("state", state
);
1102 void GroupSnapshot::generate_test_instances(std::list
<GroupSnapshot
*> &o
) {
1103 o
.push_back(new GroupSnapshot("10152ae8944a", "groupsnapshot1", GROUP_SNAPSHOT_STATE_INCOMPLETE
));
1104 o
.push_back(new GroupSnapshot("1018643c9869", "groupsnapshot2", GROUP_SNAPSHOT_STATE_COMPLETE
));
1106 void TrashImageSpec::encode(bufferlist
& bl
) const {
1107 ENCODE_START(2, 1, bl
);
1110 encode(deletion_time
, bl
);
1111 encode(deferment_end_time
, bl
);
1116 void TrashImageSpec::decode(bufferlist::const_iterator
&it
) {
1117 DECODE_START(2, it
);
1120 decode(deletion_time
, it
);
1121 decode(deferment_end_time
, it
);
1122 if (struct_v
>= 2) {
1128 void TrashImageSpec::dump(Formatter
*f
) const {
1129 f
->dump_stream("source") << source
;
1130 f
->dump_string("name", name
);
1131 f
->dump_unsigned("deletion_time", deletion_time
);
1132 f
->dump_unsigned("deferment_end_time", deferment_end_time
);
1135 void MirrorImageMap::encode(bufferlist
&bl
) const {
1136 ENCODE_START(1, 1, bl
);
1137 encode(instance_id
, bl
);
1138 encode(mapped_time
, bl
);
1143 void MirrorImageMap::decode(bufferlist::const_iterator
&it
) {
1144 DECODE_START(1, it
);
1145 decode(instance_id
, it
);
1146 decode(mapped_time
, it
);
1151 void MirrorImageMap::dump(Formatter
*f
) const {
1152 f
->dump_string("instance_id", instance_id
);
1153 f
->dump_stream("mapped_time") << mapped_time
;
1155 std::stringstream data_ss
;
1156 data
.hexdump(data_ss
);
1157 f
->dump_string("data", data_ss
.str());
1160 void MirrorImageMap::generate_test_instances(
1161 std::list
<MirrorImageMap
*> &o
) {
1163 data
.append(std::string(128, '1'));
1165 o
.push_back(new MirrorImageMap("uuid-123", utime_t(), data
));
1166 o
.push_back(new MirrorImageMap("uuid-abc", utime_t(), data
));
1169 bool MirrorImageMap::operator==(const MirrorImageMap
&rhs
) const {
1170 return instance_id
== rhs
.instance_id
&& mapped_time
== rhs
.mapped_time
&&
1171 data
.contents_equal(rhs
.data
);
1174 bool MirrorImageMap::operator<(const MirrorImageMap
&rhs
) const {
1175 return instance_id
< rhs
.instance_id
||
1176 (instance_id
== rhs
.instance_id
&& mapped_time
< rhs
.mapped_time
);
1179 std::ostream
& operator<<(std::ostream
& os
,
1180 const MirrorImageMap
&image_map
) {
1181 return os
<< "[" << "instance_id=" << image_map
.instance_id
<< ", mapped_time="
1182 << image_map
.mapped_time
<< "]";
1185 std::ostream
& operator<<(std::ostream
& os
,
1186 const MigrationHeaderType
& type
) {
1188 case MIGRATION_HEADER_TYPE_SRC
:
1191 case MIGRATION_HEADER_TYPE_DST
:
1192 os
<< "destination";
1195 os
<< "unknown (" << static_cast<uint32_t>(type
) << ")";
1201 std::ostream
& operator<<(std::ostream
& os
,
1202 const MigrationState
& migration_state
) {
1203 switch (migration_state
) {
1204 case MIGRATION_STATE_ERROR
:
1207 case MIGRATION_STATE_PREPARING
:
1210 case MIGRATION_STATE_PREPARED
:
1213 case MIGRATION_STATE_EXECUTING
:
1216 case MIGRATION_STATE_EXECUTED
:
1219 case MIGRATION_STATE_ABORTING
:
1223 os
<< "unknown (" << static_cast<uint32_t>(migration_state
) << ")";
1229 void MigrationSpec::encode(bufferlist
& bl
) const {
1230 uint8_t min_version
= 1;
1231 if (!source_spec
.empty()) {
1235 ENCODE_START(3, min_version
, bl
);
1236 encode(header_type
, bl
);
1237 encode(pool_id
, bl
);
1238 encode(pool_namespace
, bl
);
1239 encode(image_name
, bl
);
1240 encode(image_id
, bl
);
1241 encode(snap_seqs
, bl
);
1242 encode(overlap
, bl
);
1243 encode(flatten
, bl
);
1244 encode(mirroring
, bl
);
1246 encode(state_description
, bl
);
1247 encode(static_cast<uint8_t>(mirror_image_mode
), bl
);
1248 encode(source_spec
, bl
);
1252 void MigrationSpec::decode(bufferlist::const_iterator
& bl
) {
1253 DECODE_START(3, bl
);
1254 decode(header_type
, bl
);
1255 decode(pool_id
, bl
);
1256 decode(pool_namespace
, bl
);
1257 decode(image_name
, bl
);
1258 decode(image_id
, bl
);
1259 decode(snap_seqs
, bl
);
1260 decode(overlap
, bl
);
1261 decode(flatten
, bl
);
1262 decode(mirroring
, bl
);
1264 decode(state_description
, bl
);
1265 if (struct_v
>= 2) {
1267 decode(int_mode
, bl
);
1268 mirror_image_mode
= static_cast<MirrorImageMode
>(int_mode
);
1270 if (struct_v
>= 3) {
1271 decode(source_spec
, bl
);
1276 std::ostream
& operator<<(std::ostream
& os
,
1277 const std::map
<uint64_t, uint64_t>& snap_seqs
) {
1280 for (auto &it
: snap_seqs
) {
1281 os
<< (count
++ > 0 ? ", " : "") << "(" << it
.first
<< ", " << it
.second
1288 void MigrationSpec::dump(Formatter
*f
) const {
1289 f
->dump_stream("header_type") << header_type
;
1290 if (header_type
== MIGRATION_HEADER_TYPE_SRC
||
1291 source_spec
.empty()) {
1292 f
->dump_int("pool_id", pool_id
);
1293 f
->dump_string("pool_namespace", pool_namespace
);
1294 f
->dump_string("image_name", image_name
);
1295 f
->dump_string("image_id", image_id
);
1297 f
->dump_string("source_spec", source_spec
);
1299 f
->dump_stream("snap_seqs") << snap_seqs
;
1300 f
->dump_unsigned("overlap", overlap
);
1301 f
->dump_bool("mirroring", mirroring
);
1302 f
->dump_stream("mirror_image_mode") << mirror_image_mode
;
1305 void MigrationSpec::generate_test_instances(std::list
<MigrationSpec
*> &o
) {
1306 o
.push_back(new MigrationSpec());
1307 o
.push_back(new MigrationSpec(MIGRATION_HEADER_TYPE_SRC
, 1, "ns",
1308 "image_name", "image_id", "", {{1, 2}}, 123,
1309 true, MIRROR_IMAGE_MODE_SNAPSHOT
, true,
1310 MIGRATION_STATE_PREPARED
, "description"));
1311 o
.push_back(new MigrationSpec(MIGRATION_HEADER_TYPE_DST
, -1, "", "", "",
1312 "{\"format\": \"raw\"}", {{1, 2}}, 123,
1313 true, MIRROR_IMAGE_MODE_SNAPSHOT
, true,
1314 MIGRATION_STATE_PREPARED
, "description"));
1317 std::ostream
& operator<<(std::ostream
& os
,
1318 const MigrationSpec
& migration_spec
) {
1320 << "header_type=" << migration_spec
.header_type
<< ", ";
1321 if (migration_spec
.header_type
== MIGRATION_HEADER_TYPE_SRC
||
1322 migration_spec
.source_spec
.empty()) {
1323 os
<< "pool_id=" << migration_spec
.pool_id
<< ", "
1324 << "pool_namespace=" << migration_spec
.pool_namespace
<< ", "
1325 << "image_name=" << migration_spec
.image_name
<< ", "
1326 << "image_id=" << migration_spec
.image_id
<< ", ";
1328 os
<< "source_spec=" << migration_spec
.source_spec
<< ", ";
1330 os
<< "snap_seqs=" << migration_spec
.snap_seqs
<< ", "
1331 << "overlap=" << migration_spec
.overlap
<< ", "
1332 << "flatten=" << migration_spec
.flatten
<< ", "
1333 << "mirroring=" << migration_spec
.mirroring
<< ", "
1334 << "mirror_image_mode=" << migration_spec
.mirror_image_mode
<< ", "
1335 << "state=" << migration_spec
.state
<< ", "
1336 << "state_description=" << migration_spec
.state_description
<< "]";
1340 std::ostream
& operator<<(std::ostream
& os
, const AssertSnapcSeqState
& state
) {
1342 case ASSERT_SNAPC_SEQ_GT_SNAPSET_SEQ
:
1345 case ASSERT_SNAPC_SEQ_LE_SNAPSET_SEQ
:
1349 os
<< "unknown (" << static_cast<uint32_t>(state
) << ")";
1355 void sanitize_entity_inst(entity_inst_t
* entity_inst
) {
1356 // make all addrs of type ANY because the type isn't what uniquely
1357 // identifies them and clients and on-disk formats can be encoded
1358 // with different backwards compatibility settings.
1359 entity_inst
->addr
.set_type(entity_addr_t::TYPE_ANY
);