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 std::ostream
& operator<<(std::ostream
& os
,
12 MirrorPeerDirection mirror_peer_direction
) {
13 switch (mirror_peer_direction
) {
14 case MIRROR_PEER_DIRECTION_RX
:
17 case MIRROR_PEER_DIRECTION_TX
:
20 case MIRROR_PEER_DIRECTION_RX_TX
:
30 void MirrorPeer::encode(bufferlist
&bl
) const {
31 ENCODE_START(2, 1, bl
);
33 encode(site_name
, bl
);
34 encode(client_name
, bl
);
39 encode(static_cast<uint8_t>(mirror_peer_direction
), bl
);
40 encode(mirror_uuid
, bl
);
41 encode(last_seen
, bl
);
45 void MirrorPeer::decode(bufferlist::const_iterator
&it
) {
48 decode(site_name
, it
);
49 decode(client_name
, it
);
56 mirror_peer_direction
= static_cast<MirrorPeerDirection
>(mpd
);
57 decode(mirror_uuid
, it
);
58 decode(last_seen
, it
);
64 void MirrorPeer::dump(Formatter
*f
) const {
65 f
->dump_string("uuid", uuid
);
66 f
->dump_stream("direction") << mirror_peer_direction
;
67 f
->dump_string("site_name", site_name
);
68 f
->dump_string("mirror_uuid", mirror_uuid
);
69 f
->dump_string("client_name", client_name
);
70 f
->dump_stream("last_seen") << last_seen
;
73 void MirrorPeer::generate_test_instances(std::list
<MirrorPeer
*> &o
) {
74 o
.push_back(new MirrorPeer());
75 o
.push_back(new MirrorPeer("uuid-123", MIRROR_PEER_DIRECTION_RX
, "site A",
77 o
.push_back(new MirrorPeer("uuid-234", MIRROR_PEER_DIRECTION_TX
, "site B",
79 o
.push_back(new MirrorPeer("uuid-345", MIRROR_PEER_DIRECTION_RX_TX
, "site C",
80 "client name", "mirror_uuid"));
83 bool MirrorPeer::operator==(const MirrorPeer
&rhs
) const {
84 return (uuid
== rhs
.uuid
&&
85 mirror_peer_direction
== rhs
.mirror_peer_direction
&&
86 site_name
== rhs
.site_name
&&
87 client_name
== rhs
.client_name
&&
88 mirror_uuid
== rhs
.mirror_uuid
&&
89 last_seen
== rhs
.last_seen
);
92 std::ostream
& operator<<(std::ostream
& os
, const MirrorMode
& mirror_mode
) {
93 switch (mirror_mode
) {
94 case MIRROR_MODE_DISABLED
:
97 case MIRROR_MODE_IMAGE
:
100 case MIRROR_MODE_POOL
:
104 os
<< "unknown (" << static_cast<uint32_t>(mirror_mode
) << ")";
110 std::ostream
& operator<<(std::ostream
& os
, const MirrorPeer
& peer
) {
112 << "uuid=" << peer
.uuid
<< ", "
113 << "direction=" << peer
.mirror_peer_direction
<< ", "
114 << "site_name=" << peer
.site_name
<< ", "
115 << "client_name=" << peer
.client_name
<< ", "
116 << "mirror_uuid=" << peer
.mirror_uuid
<< ", "
117 << "last_seen=" << peer
.last_seen
122 void MirrorImage::encode(bufferlist
&bl
) const {
123 ENCODE_START(2, 1, bl
);
124 encode(global_image_id
, bl
);
125 encode(static_cast<uint8_t>(state
), bl
);
126 encode(static_cast<uint8_t>(mode
), bl
);
130 void MirrorImage::decode(bufferlist::const_iterator
&it
) {
133 decode(global_image_id
, it
);
134 decode(int_state
, it
);
135 state
= static_cast<MirrorImageState
>(int_state
);
138 decode(int_mode
, it
);
139 mode
= static_cast<MirrorImageMode
>(int_mode
);
144 void MirrorImage::dump(Formatter
*f
) const {
145 f
->dump_stream("mode") << mode
;
146 f
->dump_string("global_image_id", global_image_id
);
147 f
->dump_stream("state") << state
;
150 void MirrorImage::generate_test_instances(std::list
<MirrorImage
*> &o
) {
151 o
.push_back(new MirrorImage());
152 o
.push_back(new MirrorImage(MIRROR_IMAGE_MODE_JOURNAL
, "uuid-123",
153 MIRROR_IMAGE_STATE_ENABLED
));
154 o
.push_back(new MirrorImage(MIRROR_IMAGE_MODE_SNAPSHOT
, "uuid-abc",
155 MIRROR_IMAGE_STATE_DISABLING
));
158 bool MirrorImage::operator==(const MirrorImage
&rhs
) const {
159 return mode
== rhs
.mode
&& global_image_id
== rhs
.global_image_id
&&
163 bool MirrorImage::operator<(const MirrorImage
&rhs
) const {
164 if (mode
!= rhs
.mode
) {
165 return mode
< rhs
.mode
;
167 if (global_image_id
!= rhs
.global_image_id
) {
168 return global_image_id
< rhs
.global_image_id
;
170 return state
< rhs
.state
;
173 std::ostream
& operator<<(std::ostream
& os
, const MirrorImageMode
& mirror_mode
) {
174 switch (mirror_mode
) {
175 case MIRROR_IMAGE_MODE_JOURNAL
:
178 case MIRROR_IMAGE_MODE_SNAPSHOT
:
182 os
<< "unknown (" << static_cast<uint32_t>(mirror_mode
) << ")";
188 std::ostream
& operator<<(std::ostream
& os
, const MirrorImageState
& mirror_state
) {
189 switch (mirror_state
) {
190 case MIRROR_IMAGE_STATE_DISABLING
:
193 case MIRROR_IMAGE_STATE_ENABLED
:
196 case MIRROR_IMAGE_STATE_DISABLED
:
200 os
<< "unknown (" << static_cast<uint32_t>(mirror_state
) << ")";
206 std::ostream
& operator<<(std::ostream
& os
, const MirrorImage
& mirror_image
) {
208 << "mode=" << mirror_image
.mode
<< ", "
209 << "global_image_id=" << mirror_image
.global_image_id
<< ", "
210 << "state=" << mirror_image
.state
<< "]";
214 std::ostream
& operator<<(std::ostream
& os
,
215 const MirrorImageStatusState
& state
) {
217 case MIRROR_IMAGE_STATUS_STATE_UNKNOWN
:
220 case MIRROR_IMAGE_STATUS_STATE_ERROR
:
223 case MIRROR_IMAGE_STATUS_STATE_SYNCING
:
226 case MIRROR_IMAGE_STATUS_STATE_STARTING_REPLAY
:
227 os
<< "starting_replay";
229 case MIRROR_IMAGE_STATUS_STATE_REPLAYING
:
232 case MIRROR_IMAGE_STATUS_STATE_STOPPING_REPLAY
:
233 os
<< "stopping_replay";
235 case MIRROR_IMAGE_STATUS_STATE_STOPPED
:
239 os
<< "unknown (" << static_cast<uint32_t>(state
) << ")";
245 const std::string
MirrorImageSiteStatus::LOCAL_MIRROR_UUID(""); // empty mirror uuid
247 void MirrorImageSiteStatus::encode_meta(uint8_t version
, bufferlist
&bl
) const {
249 ceph::encode(mirror_uuid
, bl
);
251 cls::rbd::encode(state
, bl
);
252 ceph::encode(description
, bl
);
253 ceph::encode(last_update
, bl
);
254 ceph::encode(up
, bl
);
257 void MirrorImageSiteStatus::decode_meta(uint8_t version
,
258 bufferlist::const_iterator
&it
) {
260 mirror_uuid
= LOCAL_MIRROR_UUID
;
262 ceph::decode(mirror_uuid
, it
);
265 cls::rbd::decode(state
, it
);
266 ceph::decode(description
, it
);
267 ::decode(last_update
, it
);
268 ceph::decode(up
, it
);
271 void MirrorImageSiteStatus::encode(bufferlist
&bl
) const {
272 // break compatibility when site-name is provided
273 uint8_t version
= (mirror_uuid
== LOCAL_MIRROR_UUID
? 1 : 2);
274 ENCODE_START(version
, version
, bl
);
275 encode_meta(version
, bl
);
279 void MirrorImageSiteStatus::decode(bufferlist::const_iterator
&it
) {
281 decode_meta(struct_v
, it
);
285 void MirrorImageSiteStatus::dump(Formatter
*f
) const {
286 f
->dump_string("state", state_to_string());
287 f
->dump_string("description", description
);
288 f
->dump_stream("last_update") << last_update
;
291 std::string
MirrorImageSiteStatus::state_to_string() const {
292 std::stringstream ss
;
293 ss
<< (up
? "up+" : "down+") << state
;
297 void MirrorImageSiteStatus::generate_test_instances(
298 std::list
<MirrorImageSiteStatus
*> &o
) {
299 o
.push_back(new MirrorImageSiteStatus());
300 o
.push_back(new MirrorImageSiteStatus("", MIRROR_IMAGE_STATUS_STATE_REPLAYING
,
302 o
.push_back(new MirrorImageSiteStatus("", MIRROR_IMAGE_STATUS_STATE_ERROR
,
304 o
.push_back(new MirrorImageSiteStatus("2fb68ca9-1ba0-43b3-8cdf-8c5a9db71e65",
305 MIRROR_IMAGE_STATUS_STATE_STOPPED
, ""));
308 bool MirrorImageSiteStatus::operator==(const MirrorImageSiteStatus
&rhs
) const {
309 return state
== rhs
.state
&& description
== rhs
.description
&& up
== rhs
.up
;
312 std::ostream
& operator<<(std::ostream
& os
,
313 const MirrorImageSiteStatus
& status
) {
315 << "state=" << status
.state_to_string() << ", "
316 << "description=" << status
.description
<< ", "
317 << "last_update=" << status
.last_update
<< "]}";
321 void MirrorImageSiteStatusOnDisk::encode_meta(bufferlist
&bl
,
322 uint64_t features
) const {
323 ENCODE_START(1, 1, bl
);
324 auto sanitized_origin
= origin
;
325 sanitize_entity_inst(&sanitized_origin
);
326 encode(sanitized_origin
, bl
, features
);
330 void MirrorImageSiteStatusOnDisk::encode(bufferlist
&bl
,
331 uint64_t features
) const {
332 encode_meta(bl
, features
);
333 cls::rbd::MirrorImageSiteStatus::encode(bl
);
336 void MirrorImageSiteStatusOnDisk::decode_meta(bufferlist::const_iterator
&it
) {
339 sanitize_entity_inst(&origin
);
343 void MirrorImageSiteStatusOnDisk::decode(bufferlist::const_iterator
&it
) {
345 cls::rbd::MirrorImageSiteStatus::decode(it
);
348 void MirrorImageSiteStatusOnDisk::generate_test_instances(
349 std::list
<MirrorImageSiteStatusOnDisk
*> &o
) {
350 o
.push_back(new MirrorImageSiteStatusOnDisk());
351 o
.push_back(new MirrorImageSiteStatusOnDisk(
352 {"", MIRROR_IMAGE_STATUS_STATE_ERROR
, "error"}));
353 o
.push_back(new MirrorImageSiteStatusOnDisk(
354 {"siteA", MIRROR_IMAGE_STATUS_STATE_STOPPED
, ""}));
357 int MirrorImageStatus::get_local_mirror_image_site_status(
358 MirrorImageSiteStatus
* status
) const {
359 auto it
= std::find_if(
360 mirror_image_site_statuses
.begin(),
361 mirror_image_site_statuses
.end(),
362 [](const MirrorImageSiteStatus
& status
) {
363 return status
.mirror_uuid
== MirrorImageSiteStatus::LOCAL_MIRROR_UUID
;
365 if (it
== mirror_image_site_statuses
.end()) {
373 void MirrorImageStatus::encode(bufferlist
&bl
) const {
374 // don't break compatibility for extra site statuses
375 ENCODE_START(2, 1, bl
);
378 MirrorImageSiteStatus local_status
;
379 int r
= get_local_mirror_image_site_status(&local_status
);
380 local_status
.encode_meta(1, bl
);
382 bool local_status_valid
= (r
>= 0);
383 encode(local_status_valid
, bl
);
385 // remote site statuses
386 __u32 n
= mirror_image_site_statuses
.size();
387 if (local_status_valid
) {
392 for (auto& status
: mirror_image_site_statuses
) {
393 if (status
.mirror_uuid
== MirrorImageSiteStatus::LOCAL_MIRROR_UUID
) {
396 status
.encode_meta(2, bl
);
401 void MirrorImageStatus::decode(bufferlist::const_iterator
&it
) {
405 MirrorImageSiteStatus local_status
;
406 local_status
.decode_meta(1, it
);
409 mirror_image_site_statuses
.push_back(local_status
);
411 bool local_status_valid
;
412 decode(local_status_valid
, it
);
416 if (local_status_valid
) {
420 mirror_image_site_statuses
.resize(n
);
421 for (auto status_it
= mirror_image_site_statuses
.begin();
422 status_it
!= mirror_image_site_statuses
.end(); ++status_it
) {
423 if (local_status_valid
&&
424 status_it
== mirror_image_site_statuses
.begin()) {
425 *status_it
= local_status
;
429 // remote site status
430 status_it
->decode_meta(struct_v
, it
);
436 void MirrorImageStatus::dump(Formatter
*f
) const {
437 MirrorImageSiteStatus local_status
;
438 int r
= get_local_mirror_image_site_status(&local_status
);
440 local_status
.dump(f
);
443 f
->open_array_section("remotes");
444 for (auto& status
: mirror_image_site_statuses
) {
445 if (status
.mirror_uuid
== MirrorImageSiteStatus::LOCAL_MIRROR_UUID
) {
449 f
->open_object_section("remote");
456 bool MirrorImageStatus::operator==(const MirrorImageStatus
&rhs
) const {
457 return (mirror_image_site_statuses
== rhs
.mirror_image_site_statuses
);
460 void MirrorImageStatus::generate_test_instances(
461 std::list
<MirrorImageStatus
*> &o
) {
462 o
.push_back(new MirrorImageStatus());
463 o
.push_back(new MirrorImageStatus({{"", MIRROR_IMAGE_STATUS_STATE_ERROR
, ""}}));
464 o
.push_back(new MirrorImageStatus({{"", MIRROR_IMAGE_STATUS_STATE_STOPPED
, ""},
465 {"siteA", MIRROR_IMAGE_STATUS_STATE_REPLAYING
, ""}}));
468 std::ostream
& operator<<(std::ostream
& os
,
469 const MirrorImageStatus
& status
) {
471 MirrorImageSiteStatus local_status
;
472 int r
= status
.get_local_mirror_image_site_status(&local_status
);
474 os
<< "state=" << local_status
.state_to_string() << ", "
475 << "description=" << local_status
.description
<< ", "
476 << "last_update=" << local_status
.last_update
<< ", ";
480 for (auto& remote_status
: status
.mirror_image_site_statuses
) {
481 if (remote_status
.mirror_uuid
== MirrorImageSiteStatus::LOCAL_MIRROR_UUID
) {
486 << "mirror_uuid=" << remote_status
.mirror_uuid
<< ", "
487 << "state=" << remote_status
.state_to_string() << ", "
488 << "description=" << remote_status
.description
<< ", "
489 << "last_update=" << remote_status
.last_update
496 void ParentImageSpec::encode(bufferlist
& bl
) const {
497 ENCODE_START(1, 1, bl
);
499 encode(pool_namespace
, bl
);
500 encode(image_id
, bl
);
505 void ParentImageSpec::decode(bufferlist::const_iterator
& bl
) {
508 decode(pool_namespace
, bl
);
509 decode(image_id
, bl
);
514 void ParentImageSpec::dump(Formatter
*f
) const {
515 f
->dump_int("pool_id", pool_id
);
516 f
->dump_string("pool_namespace", pool_namespace
);
517 f
->dump_string("image_id", image_id
);
518 f
->dump_unsigned("snap_id", snap_id
);
521 void ParentImageSpec::generate_test_instances(std::list
<ParentImageSpec
*>& o
) {
522 o
.push_back(new ParentImageSpec
{});
523 o
.push_back(new ParentImageSpec
{1, "", "foo", 3});
524 o
.push_back(new ParentImageSpec
{1, "ns", "foo", 3});
527 std::ostream
& operator<<(std::ostream
& os
, const ParentImageSpec
& rhs
) {
529 << "pool_id=" << rhs
.pool_id
<< ", "
530 << "pool_namespace=" << rhs
.pool_namespace
<< ", "
531 << "image_id=" << rhs
.image_id
<< ", "
532 << "snap_id=" << rhs
.snap_id
537 void ChildImageSpec::encode(bufferlist
&bl
) const {
538 ENCODE_START(2, 1, bl
);
540 encode(image_id
, bl
);
541 encode(pool_namespace
, bl
);
545 void ChildImageSpec::decode(bufferlist::const_iterator
&it
) {
548 decode(image_id
, it
);
550 decode(pool_namespace
, it
);
555 void ChildImageSpec::dump(Formatter
*f
) const {
556 f
->dump_int("pool_id", pool_id
);
557 f
->dump_string("pool_namespace", pool_namespace
);
558 f
->dump_string("image_id", image_id
);
561 void ChildImageSpec::generate_test_instances(std::list
<ChildImageSpec
*> &o
) {
562 o
.push_back(new ChildImageSpec());
563 o
.push_back(new ChildImageSpec(123, "", "abc"));
564 o
.push_back(new ChildImageSpec(123, "ns", "abc"));
567 std::ostream
& operator<<(std::ostream
& os
, const ChildImageSpec
& rhs
) {
569 << "pool_id=" << rhs
.pool_id
<< ", "
570 << "pool_namespace=" << rhs
.pool_namespace
<< ", "
571 << "image_id=" << rhs
.image_id
576 void GroupImageSpec::encode(bufferlist
&bl
) const {
577 ENCODE_START(1, 1, bl
);
578 encode(image_id
, bl
);
583 void GroupImageSpec::decode(bufferlist::const_iterator
&it
) {
585 decode(image_id
, it
);
590 void GroupImageSpec::dump(Formatter
*f
) const {
591 f
->dump_string("image_id", image_id
);
592 f
->dump_int("pool_id", pool_id
);
595 int GroupImageSpec::from_key(const std::string
&image_key
,
596 GroupImageSpec
*spec
) {
597 if (nullptr == spec
) return -EINVAL
;
598 int prefix_len
= cls::rbd::RBD_GROUP_IMAGE_KEY_PREFIX
.size();
599 std::string data_string
= image_key
.substr(prefix_len
,
600 image_key
.size() - prefix_len
);
601 size_t p
= data_string
.find("_");
602 if (std::string::npos
== p
) {
605 data_string
[p
] = ' ';
607 istringstream
iss(data_string
);
610 iss
>> std::hex
>> pool_id
>> image_id
;
612 spec
->image_id
= image_id
;
613 spec
->pool_id
= pool_id
;
617 std::string
GroupImageSpec::image_key() {
622 oss
<< RBD_GROUP_IMAGE_KEY_PREFIX
<< std::setw(16)
623 << std::setfill('0') << std::hex
<< pool_id
<< "_" << image_id
;
628 void GroupImageSpec::generate_test_instances(std::list
<GroupImageSpec
*> &o
) {
629 o
.push_back(new GroupImageSpec("10152ae8944a", 0));
630 o
.push_back(new GroupImageSpec("1018643c9869", 3));
633 void GroupImageStatus::encode(bufferlist
&bl
) const {
634 ENCODE_START(1, 1, bl
);
640 void GroupImageStatus::decode(bufferlist::const_iterator
&it
) {
647 std::string
GroupImageStatus::state_to_string() const {
648 std::stringstream ss
;
649 if (state
== GROUP_IMAGE_LINK_STATE_INCOMPLETE
) {
652 if (state
== GROUP_IMAGE_LINK_STATE_ATTACHED
) {
658 void GroupImageStatus::dump(Formatter
*f
) const {
660 f
->dump_string("state", state_to_string());
663 void GroupImageStatus::generate_test_instances(std::list
<GroupImageStatus
*> &o
) {
664 o
.push_back(new GroupImageStatus(GroupImageSpec("10152ae8944a", 0), GROUP_IMAGE_LINK_STATE_ATTACHED
));
665 o
.push_back(new GroupImageStatus(GroupImageSpec("1018643c9869", 3), GROUP_IMAGE_LINK_STATE_ATTACHED
));
666 o
.push_back(new GroupImageStatus(GroupImageSpec("10152ae8944a", 0), GROUP_IMAGE_LINK_STATE_INCOMPLETE
));
667 o
.push_back(new GroupImageStatus(GroupImageSpec("1018643c9869", 3), GROUP_IMAGE_LINK_STATE_INCOMPLETE
));
671 void GroupSpec::encode(bufferlist
&bl
) const {
672 ENCODE_START(1, 1, bl
);
674 encode(group_id
, bl
);
678 void GroupSpec::decode(bufferlist::const_iterator
&it
) {
681 decode(group_id
, it
);
685 void GroupSpec::dump(Formatter
*f
) const {
686 f
->dump_string("group_id", group_id
);
687 f
->dump_int("pool_id", pool_id
);
690 bool GroupSpec::is_valid() const {
691 return (!group_id
.empty()) && (pool_id
!= -1);
694 void GroupSpec::generate_test_instances(std::list
<GroupSpec
*> &o
) {
695 o
.push_back(new GroupSpec("10152ae8944a", 0));
696 o
.push_back(new GroupSpec("1018643c9869", 3));
699 void GroupSnapshotNamespace::encode(bufferlist
& bl
) const {
701 encode(group_pool
, bl
);
702 encode(group_id
, bl
);
703 encode(group_snapshot_id
, bl
);
706 void GroupSnapshotNamespace::decode(bufferlist::const_iterator
& it
) {
708 decode(group_pool
, it
);
709 decode(group_id
, it
);
710 decode(group_snapshot_id
, it
);
713 void GroupSnapshotNamespace::dump(Formatter
*f
) const {
714 f
->dump_int("group_pool", group_pool
);
715 f
->dump_string("group_id", group_id
);
716 f
->dump_string("group_snapshot_id", group_snapshot_id
);
719 void TrashSnapshotNamespace::encode(bufferlist
& bl
) const {
721 encode(original_name
, bl
);
722 encode(static_cast<uint32_t>(original_snapshot_namespace_type
), bl
);
725 void TrashSnapshotNamespace::decode(bufferlist::const_iterator
& it
) {
727 decode(original_name
, it
);
729 decode(snap_type
, it
);
730 original_snapshot_namespace_type
= static_cast<SnapshotNamespaceType
>(
734 void TrashSnapshotNamespace::dump(Formatter
*f
) const {
735 f
->dump_string("original_name", original_name
);
736 f
->dump_stream("original_snapshot_namespace")
737 << original_snapshot_namespace_type
;
740 void MirrorSnapshotNamespace::encode(bufferlist
& bl
) const {
743 encode(complete
, bl
);
744 encode(mirror_peer_uuids
, bl
);
745 encode(primary_mirror_uuid
, bl
);
746 encode(primary_snap_id
, bl
);
747 encode(last_copied_object_number
, bl
);
748 encode(snap_seqs
, bl
);
751 void MirrorSnapshotNamespace::decode(bufferlist::const_iterator
& it
) {
754 decode(complete
, it
);
755 decode(mirror_peer_uuids
, it
);
756 decode(primary_mirror_uuid
, it
);
757 decode(primary_snap_id
, it
);
758 decode(last_copied_object_number
, it
);
759 decode(snap_seqs
, it
);
762 void MirrorSnapshotNamespace::dump(Formatter
*f
) const {
763 f
->dump_stream("state") << state
;
764 f
->dump_bool("complete", complete
);
765 f
->open_array_section("mirror_peer_uuids");
766 for (auto &peer
: mirror_peer_uuids
) {
767 f
->dump_string("mirror_peer_uuid", peer
);
770 f
->dump_string("primary_mirror_uuid", primary_mirror_uuid
);
771 f
->dump_unsigned("primary_snap_id", primary_snap_id
);
772 f
->dump_unsigned("last_copied_object_number", last_copied_object_number
);
773 f
->dump_stream("snap_seqs") << snap_seqs
;
776 class EncodeSnapshotNamespaceVisitor
: public boost::static_visitor
<void> {
778 explicit EncodeSnapshotNamespaceVisitor(bufferlist
&bl
) : m_bl(bl
) {
781 template <typename T
>
782 inline void operator()(const T
& t
) const {
784 encode(static_cast<uint32_t>(T::SNAPSHOT_NAMESPACE_TYPE
), m_bl
);
792 class DecodeSnapshotNamespaceVisitor
: public boost::static_visitor
<void> {
794 DecodeSnapshotNamespaceVisitor(bufferlist::const_iterator
&iter
)
798 template <typename T
>
799 inline void operator()(T
& t
) const {
803 bufferlist::const_iterator
&m_iter
;
806 class DumpSnapshotNamespaceVisitor
: public boost::static_visitor
<void> {
808 explicit DumpSnapshotNamespaceVisitor(Formatter
*formatter
, const std::string
&key
)
809 : m_formatter(formatter
), m_key(key
) {}
811 template <typename T
>
812 inline void operator()(const T
& t
) const {
813 auto type
= T::SNAPSHOT_NAMESPACE_TYPE
;
814 m_formatter
->dump_string(m_key
.c_str(), stringify(type
));
818 ceph::Formatter
*m_formatter
;
822 class GetTypeVisitor
: public boost::static_visitor
<SnapshotNamespaceType
> {
824 template <typename T
>
825 inline SnapshotNamespaceType
operator()(const T
&) const {
826 return static_cast<SnapshotNamespaceType
>(T::SNAPSHOT_NAMESPACE_TYPE
);
830 SnapshotNamespaceType
get_snap_namespace_type(
831 const SnapshotNamespace
& snapshot_namespace
) {
832 return static_cast<SnapshotNamespaceType
>(boost::apply_visitor(
833 GetTypeVisitor(), snapshot_namespace
));
836 void SnapshotInfo::encode(bufferlist
& bl
) const {
837 ENCODE_START(1, 1, bl
);
839 encode(snapshot_namespace
, bl
);
841 encode(image_size
, bl
);
842 encode(timestamp
, bl
);
843 encode(child_count
, bl
);
847 void SnapshotInfo::decode(bufferlist::const_iterator
& it
) {
850 decode(snapshot_namespace
, it
);
852 decode(image_size
, it
);
853 decode(timestamp
, it
);
854 decode(child_count
, it
);
858 void SnapshotInfo::dump(Formatter
*f
) const {
859 f
->dump_unsigned("id", id
);
860 f
->open_object_section("namespace");
861 boost::apply_visitor(DumpSnapshotNamespaceVisitor(f
, "type"),
864 f
->dump_string("name", name
);
865 f
->dump_unsigned("image_size", image_size
);
866 f
->dump_stream("timestamp") << timestamp
;
869 void SnapshotInfo::generate_test_instances(std::list
<SnapshotInfo
*> &o
) {
870 o
.push_back(new SnapshotInfo(1ULL, UserSnapshotNamespace
{}, "snap1", 123,
872 o
.push_back(new SnapshotInfo(2ULL,
873 GroupSnapshotNamespace
{567, "group1", "snap1"},
874 "snap1", 123, {123456, 0}, 987));
875 o
.push_back(new SnapshotInfo(3ULL,
876 TrashSnapshotNamespace
{
877 SNAPSHOT_NAMESPACE_TYPE_USER
, "snap1"},
878 "12345", 123, {123456, 0}, 429));
879 o
.push_back(new SnapshotInfo(1ULL,
880 MirrorSnapshotNamespace
{MIRROR_SNAPSHOT_STATE_PRIMARY
,
881 {"1", "2"}, "", CEPH_NOSNAP
},
882 "snap1", 123, {123456, 0}, 12));
883 o
.push_back(new SnapshotInfo(1ULL,
884 MirrorSnapshotNamespace
{MIRROR_SNAPSHOT_STATE_NON_PRIMARY
,
885 {"1", "2"}, "uuid", 123},
886 "snap1", 123, {123456, 0}, 12));
889 void SnapshotNamespace::encode(bufferlist
& bl
) const {
890 ENCODE_START(1, 1, bl
);
891 boost::apply_visitor(EncodeSnapshotNamespaceVisitor(bl
), *this);
895 void SnapshotNamespace::decode(bufferlist::const_iterator
&p
)
899 decode(snap_type
, p
);
901 case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_USER
:
902 *this = UserSnapshotNamespace();
904 case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_GROUP
:
905 *this = GroupSnapshotNamespace();
907 case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_TRASH
:
908 *this = TrashSnapshotNamespace();
910 case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR
:
911 *this = MirrorSnapshotNamespace();
914 *this = UnknownSnapshotNamespace();
917 boost::apply_visitor(DecodeSnapshotNamespaceVisitor(p
), *this);
921 void SnapshotNamespace::dump(Formatter
*f
) const {
922 boost::apply_visitor(
923 DumpSnapshotNamespaceVisitor(f
, "snapshot_namespace_type"), *this);
926 void SnapshotNamespace::generate_test_instances(std::list
<SnapshotNamespace
*> &o
) {
927 o
.push_back(new SnapshotNamespace(UserSnapshotNamespace()));
928 o
.push_back(new SnapshotNamespace(GroupSnapshotNamespace(0, "10152ae8944a",
930 o
.push_back(new SnapshotNamespace(GroupSnapshotNamespace(5, "1018643c9869",
932 o
.push_back(new SnapshotNamespace(TrashSnapshotNamespace()));
933 o
.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_PRIMARY
,
936 o
.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_PRIMARY_DEMOTED
,
939 o
.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_NON_PRIMARY
,
942 o
.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED
,
947 std::ostream
& operator<<(std::ostream
& os
, const SnapshotNamespaceType
& type
) {
949 case SNAPSHOT_NAMESPACE_TYPE_USER
:
952 case SNAPSHOT_NAMESPACE_TYPE_GROUP
:
955 case SNAPSHOT_NAMESPACE_TYPE_TRASH
:
958 case SNAPSHOT_NAMESPACE_TYPE_MIRROR
:
968 std::ostream
& operator<<(std::ostream
& os
, const UserSnapshotNamespace
& ns
) {
969 os
<< "[" << SNAPSHOT_NAMESPACE_TYPE_USER
<< "]";
973 std::ostream
& operator<<(std::ostream
& os
, const GroupSnapshotNamespace
& ns
) {
974 os
<< "[" << SNAPSHOT_NAMESPACE_TYPE_GROUP
<< " "
975 << "group_pool=" << ns
.group_pool
<< ", "
976 << "group_id=" << ns
.group_id
<< ", "
977 << "group_snapshot_id=" << ns
.group_snapshot_id
<< "]";
981 std::ostream
& operator<<(std::ostream
& os
, const TrashSnapshotNamespace
& ns
) {
982 os
<< "[" << SNAPSHOT_NAMESPACE_TYPE_TRASH
<< " "
983 << "original_name=" << ns
.original_name
<< ", "
984 << "original_snapshot_namespace=" << ns
.original_snapshot_namespace_type
989 std::ostream
& operator<<(std::ostream
& os
, const MirrorSnapshotNamespace
& ns
) {
990 os
<< "[" << SNAPSHOT_NAMESPACE_TYPE_MIRROR
<< " "
991 << "state=" << ns
.state
<< ", "
992 << "complete=" << ns
.complete
<< ", "
993 << "mirror_peer_uuids=" << ns
.mirror_peer_uuids
<< ", "
994 << "primary_mirror_uuid=" << ns
.primary_mirror_uuid
<< ", "
995 << "primary_snap_id=" << ns
.primary_snap_id
<< ", "
996 << "last_copied_object_number=" << ns
.last_copied_object_number
<< ", "
997 << "snap_seqs=" << ns
.snap_seqs
1002 std::ostream
& operator<<(std::ostream
& os
, const UnknownSnapshotNamespace
& ns
) {
1007 std::ostream
& operator<<(std::ostream
& os
, MirrorSnapshotState type
) {
1009 case MIRROR_SNAPSHOT_STATE_PRIMARY
:
1012 case MIRROR_SNAPSHOT_STATE_PRIMARY_DEMOTED
:
1013 os
<< "primary (demoted)";
1015 case MIRROR_SNAPSHOT_STATE_NON_PRIMARY
:
1016 os
<< "non-primary";
1018 case MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED
:
1019 os
<< "non-primary (demoted)";
1028 void ImageSnapshotSpec::encode(bufferlist
& bl
) const {
1030 ENCODE_START(1, 1, bl
);
1032 encode(image_id
, bl
);
1033 encode(snap_id
, bl
);
1037 void ImageSnapshotSpec::decode(bufferlist::const_iterator
& it
) {
1039 DECODE_START(1, it
);
1041 decode(image_id
, it
);
1042 decode(snap_id
, it
);
1046 void ImageSnapshotSpec::dump(Formatter
*f
) const {
1047 f
->dump_int("pool", pool
);
1048 f
->dump_string("image_id", image_id
);
1049 f
->dump_int("snap_id", snap_id
);
1052 void ImageSnapshotSpec::generate_test_instances(std::list
<ImageSnapshotSpec
*> &o
) {
1053 o
.push_back(new ImageSnapshotSpec(0, "myimage", 2));
1054 o
.push_back(new ImageSnapshotSpec(1, "testimage", 7));
1057 void GroupSnapshot::encode(bufferlist
& bl
) const {
1059 ENCODE_START(1, 1, bl
);
1067 void GroupSnapshot::decode(bufferlist::const_iterator
& it
) {
1069 DECODE_START(1, it
);
1077 void GroupSnapshot::dump(Formatter
*f
) const {
1078 f
->dump_string("id", id
);
1079 f
->dump_string("name", name
);
1080 f
->dump_int("state", state
);
1083 void GroupSnapshot::generate_test_instances(std::list
<GroupSnapshot
*> &o
) {
1084 o
.push_back(new GroupSnapshot("10152ae8944a", "groupsnapshot1", GROUP_SNAPSHOT_STATE_INCOMPLETE
));
1085 o
.push_back(new GroupSnapshot("1018643c9869", "groupsnapshot2", GROUP_SNAPSHOT_STATE_COMPLETE
));
1087 void TrashImageSpec::encode(bufferlist
& bl
) const {
1088 ENCODE_START(2, 1, bl
);
1091 encode(deletion_time
, bl
);
1092 encode(deferment_end_time
, bl
);
1097 void TrashImageSpec::decode(bufferlist::const_iterator
&it
) {
1098 DECODE_START(2, it
);
1101 decode(deletion_time
, it
);
1102 decode(deferment_end_time
, it
);
1103 if (struct_v
>= 2) {
1109 void TrashImageSpec::dump(Formatter
*f
) const {
1110 f
->dump_stream("source") << source
;
1111 f
->dump_string("name", name
);
1112 f
->dump_unsigned("deletion_time", deletion_time
);
1113 f
->dump_unsigned("deferment_end_time", deferment_end_time
);
1116 void MirrorImageMap::encode(bufferlist
&bl
) const {
1117 ENCODE_START(1, 1, bl
);
1118 encode(instance_id
, bl
);
1119 encode(mapped_time
, bl
);
1124 void MirrorImageMap::decode(bufferlist::const_iterator
&it
) {
1125 DECODE_START(1, it
);
1126 decode(instance_id
, it
);
1127 decode(mapped_time
, it
);
1132 void MirrorImageMap::dump(Formatter
*f
) const {
1133 f
->dump_string("instance_id", instance_id
);
1134 f
->dump_stream("mapped_time") << mapped_time
;
1136 std::stringstream data_ss
;
1137 data
.hexdump(data_ss
);
1138 f
->dump_string("data", data_ss
.str());
1141 void MirrorImageMap::generate_test_instances(
1142 std::list
<MirrorImageMap
*> &o
) {
1144 data
.append(std::string(128, '1'));
1146 o
.push_back(new MirrorImageMap("uuid-123", utime_t(), data
));
1147 o
.push_back(new MirrorImageMap("uuid-abc", utime_t(), data
));
1150 bool MirrorImageMap::operator==(const MirrorImageMap
&rhs
) const {
1151 return instance_id
== rhs
.instance_id
&& mapped_time
== rhs
.mapped_time
&&
1152 data
.contents_equal(rhs
.data
);
1155 bool MirrorImageMap::operator<(const MirrorImageMap
&rhs
) const {
1156 return instance_id
< rhs
.instance_id
||
1157 (instance_id
== rhs
.instance_id
&& mapped_time
< rhs
.mapped_time
);
1160 std::ostream
& operator<<(std::ostream
& os
,
1161 const MirrorImageMap
&image_map
) {
1162 return os
<< "[" << "instance_id=" << image_map
.instance_id
<< ", mapped_time="
1163 << image_map
.mapped_time
<< "]";
1166 std::ostream
& operator<<(std::ostream
& os
,
1167 const MigrationHeaderType
& type
) {
1169 case MIGRATION_HEADER_TYPE_SRC
:
1172 case MIGRATION_HEADER_TYPE_DST
:
1173 os
<< "destination";
1176 os
<< "unknown (" << static_cast<uint32_t>(type
) << ")";
1182 std::ostream
& operator<<(std::ostream
& os
,
1183 const MigrationState
& migration_state
) {
1184 switch (migration_state
) {
1185 case MIGRATION_STATE_ERROR
:
1188 case MIGRATION_STATE_PREPARING
:
1191 case MIGRATION_STATE_PREPARED
:
1194 case MIGRATION_STATE_EXECUTING
:
1197 case MIGRATION_STATE_EXECUTED
:
1201 os
<< "unknown (" << static_cast<uint32_t>(migration_state
) << ")";
1207 void MigrationSpec::encode(bufferlist
& bl
) const {
1208 ENCODE_START(2, 1, bl
);
1209 encode(header_type
, bl
);
1210 encode(pool_id
, bl
);
1211 encode(pool_namespace
, bl
);
1212 encode(image_name
, bl
);
1213 encode(image_id
, bl
);
1214 encode(snap_seqs
, bl
);
1215 encode(overlap
, bl
);
1216 encode(flatten
, bl
);
1217 encode(mirroring
, bl
);
1219 encode(state_description
, bl
);
1220 encode(static_cast<uint8_t>(mirror_image_mode
), bl
);
1224 void MigrationSpec::decode(bufferlist::const_iterator
& bl
) {
1225 DECODE_START(2, bl
);
1226 decode(header_type
, bl
);
1227 decode(pool_id
, bl
);
1228 decode(pool_namespace
, bl
);
1229 decode(image_name
, bl
);
1230 decode(image_id
, bl
);
1231 decode(snap_seqs
, bl
);
1232 decode(overlap
, bl
);
1233 decode(flatten
, bl
);
1234 decode(mirroring
, bl
);
1236 decode(state_description
, bl
);
1237 if (struct_v
>= 2) {
1239 decode(int_mode
, bl
);
1240 mirror_image_mode
= static_cast<MirrorImageMode
>(int_mode
);
1245 std::ostream
& operator<<(std::ostream
& os
,
1246 const std::map
<uint64_t, uint64_t>& snap_seqs
) {
1249 for (auto &it
: snap_seqs
) {
1250 os
<< (count
++ > 0 ? ", " : "") << "(" << it
.first
<< ", " << it
.second
1257 void MigrationSpec::dump(Formatter
*f
) const {
1258 f
->dump_stream("header_type") << header_type
;
1259 f
->dump_int("pool_id", pool_id
);
1260 f
->dump_string("pool_namespace", pool_namespace
);
1261 f
->dump_string("image_name", image_name
);
1262 f
->dump_string("image_id", image_id
);
1263 f
->dump_stream("snap_seqs") << snap_seqs
;
1264 f
->dump_unsigned("overlap", overlap
);
1265 f
->dump_bool("mirroring", mirroring
);
1266 f
->dump_stream("mirror_image_mode") << mirror_image_mode
;
1269 void MigrationSpec::generate_test_instances(std::list
<MigrationSpec
*> &o
) {
1270 o
.push_back(new MigrationSpec());
1271 o
.push_back(new MigrationSpec(MIGRATION_HEADER_TYPE_SRC
, 1, "ns",
1272 "image_name", "image_id", {{1, 2}}, 123, true,
1273 MIRROR_IMAGE_MODE_SNAPSHOT
, true,
1274 MIGRATION_STATE_PREPARED
, "description"));
1277 std::ostream
& operator<<(std::ostream
& os
,
1278 const MigrationSpec
& migration_spec
) {
1280 << "header_type=" << migration_spec
.header_type
<< ", "
1281 << "pool_id=" << migration_spec
.pool_id
<< ", "
1282 << "pool_namespace=" << migration_spec
.pool_namespace
<< ", "
1283 << "image_name=" << migration_spec
.image_name
<< ", "
1284 << "image_id=" << migration_spec
.image_id
<< ", "
1285 << "snap_seqs=" << migration_spec
.snap_seqs
<< ", "
1286 << "overlap=" << migration_spec
.overlap
<< ", "
1287 << "flatten=" << migration_spec
.flatten
<< ", "
1288 << "mirroring=" << migration_spec
.mirroring
<< ", "
1289 << "mirror_image_mode=" << migration_spec
.mirror_image_mode
<< ", "
1290 << "state=" << migration_spec
.state
<< ", "
1291 << "state_description=" << migration_spec
.state_description
<< "]";
1295 std::ostream
& operator<<(std::ostream
& os
, const AssertSnapcSeqState
& state
) {
1297 case ASSERT_SNAPC_SEQ_GT_SNAPSET_SEQ
:
1300 case ASSERT_SNAPC_SEQ_LE_SNAPSET_SEQ
:
1304 os
<< "unknown (" << static_cast<uint32_t>(state
) << ")";
1310 void sanitize_entity_inst(entity_inst_t
* entity_inst
) {
1311 // make all addrs of type ANY because the type isn't what uniquely
1312 // identifies them and clients and on-disk formats can be encoded
1313 // with different backwards compatibility settings.
1314 entity_inst
->addr
.set_type(entity_addr_t::TYPE_ANY
);