1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "librbd/journal/Types.h"
5 #include "include/ceph_assert.h"
6 #include "include/stringify.h"
7 #include "include/types.h"
8 #include "common/Formatter.h"
19 class GetTypeVisitor
: public boost::static_visitor
<E
> {
22 inline E
operator()(const T
&) const {
27 class EncodeVisitor
: public boost::static_visitor
<void> {
29 explicit EncodeVisitor(bufferlist
&bl
) : m_bl(bl
) {
33 inline void operator()(const T
& t
) const {
34 encode(static_cast<uint32_t>(T::TYPE
), m_bl
);
41 class DecodeVisitor
: public boost::static_visitor
<void> {
43 DecodeVisitor(__u8 version
, bufferlist::const_iterator
&iter
)
44 : m_version(version
), m_iter(iter
) {
48 inline void operator()(T
& t
) const {
49 t
.decode(m_version
, m_iter
);
53 bufferlist::const_iterator
&m_iter
;
56 class DumpVisitor
: public boost::static_visitor
<void> {
58 explicit DumpVisitor(Formatter
*formatter
, const std::string
&key
)
59 : m_formatter(formatter
), m_key(key
) {}
62 inline void operator()(const T
& t
) const {
64 m_formatter
->dump_string(m_key
.c_str(), stringify(type
));
68 ceph::Formatter
*m_formatter
;
72 } // anonymous namespace
74 void AioDiscardEvent::encode(bufferlist
& bl
) const {
78 bool skip_partial_discard
= (discard_granularity_bytes
> 0);
79 encode(skip_partial_discard
, bl
);
80 encode(discard_granularity_bytes
, bl
);
83 void AioDiscardEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
88 bool skip_partial_discard
= false;
90 decode(skip_partial_discard
, it
);
94 decode(discard_granularity_bytes
, it
);
96 if (skip_partial_discard
) {
97 // use a size larger than the maximum object size which will
98 // truncated down to object size during IO processing
99 discard_granularity_bytes
= std::numeric_limits
<uint32_t>::max();
101 discard_granularity_bytes
= 0;
106 void AioDiscardEvent::dump(Formatter
*f
) const {
107 f
->dump_unsigned("offset", offset
);
108 f
->dump_unsigned("length", length
);
109 f
->dump_unsigned("discard_granularity_bytes", discard_granularity_bytes
);
112 uint32_t AioWriteEvent::get_fixed_size() {
113 return EventEntry::get_fixed_size() + 16 /* offset, length */;
116 void AioWriteEvent::encode(bufferlist
& bl
) const {
123 void AioWriteEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
130 void AioWriteEvent::dump(Formatter
*f
) const {
131 f
->dump_unsigned("offset", offset
);
132 f
->dump_unsigned("length", length
);
135 void AioWriteSameEvent::encode(bufferlist
& bl
) const {
142 void AioWriteSameEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
149 void AioWriteSameEvent::dump(Formatter
*f
) const {
150 f
->dump_unsigned("offset", offset
);
151 f
->dump_unsigned("length", length
);
154 uint32_t AioCompareAndWriteEvent::get_fixed_size() {
155 return EventEntry::get_fixed_size() + 32 /* offset, length */;
158 void AioCompareAndWriteEvent::encode(bufferlist
& bl
) const {
162 encode(cmp_data
, bl
);
163 encode(write_data
, bl
);
166 void AioCompareAndWriteEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
170 decode(cmp_data
, it
);
171 decode(write_data
, it
);
174 void AioCompareAndWriteEvent::dump(Formatter
*f
) const {
175 f
->dump_unsigned("offset", offset
);
176 f
->dump_unsigned("length", length
);
179 void AioFlushEvent::encode(bufferlist
& bl
) const {
182 void AioFlushEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
185 void AioFlushEvent::dump(Formatter
*f
) const {
188 void OpEventBase::encode(bufferlist
& bl
) const {
193 void OpEventBase::decode(__u8 version
, bufferlist::const_iterator
& it
) {
198 void OpEventBase::dump(Formatter
*f
) const {
199 f
->dump_unsigned("op_tid", op_tid
);
202 void OpFinishEvent::encode(bufferlist
& bl
) const {
203 OpEventBase::encode(bl
);
209 void OpFinishEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
210 OpEventBase::decode(version
, it
);
216 void OpFinishEvent::dump(Formatter
*f
) const {
217 OpEventBase::dump(f
);
218 f
->dump_unsigned("op_tid", op_tid
);
219 f
->dump_int("result", r
);
222 void SnapEventBase::encode(bufferlist
& bl
) const {
224 OpEventBase::encode(bl
);
225 encode(snap_name
, bl
);
226 encode(snap_namespace
, bl
);
229 void SnapEventBase::decode(__u8 version
, bufferlist::const_iterator
& it
) {
231 OpEventBase::decode(version
, it
);
233 decode(snap_name
, it
);
235 decode(snap_namespace
, it
);
239 void SnapEventBase::dump(Formatter
*f
) const {
240 OpEventBase::dump(f
);
241 f
->dump_string("snap_name", snap_name
);
242 snap_namespace
.dump(f
);
245 void SnapCreateEvent::encode(bufferlist
&bl
) const {
246 SnapEventBase::encode(bl
);
249 void SnapCreateEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
251 SnapEventBase::decode(version
, it
);
253 decode(snap_namespace
, it
);
257 void SnapCreateEvent::dump(Formatter
*f
) const {
258 SnapEventBase::dump(f
);
261 void SnapLimitEvent::encode(bufferlist
&bl
) const {
262 OpEventBase::encode(bl
);
267 void SnapLimitEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
268 OpEventBase::decode(version
, it
);
273 void SnapLimitEvent::dump(Formatter
*f
) const {
274 OpEventBase::dump(f
);
275 f
->dump_unsigned("limit", limit
);
278 void SnapRenameEvent::encode(bufferlist
& bl
) const {
279 OpEventBase::encode(bl
);
281 encode(dst_snap_name
, bl
);
283 encode(src_snap_name
, bl
);
286 void SnapRenameEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
288 OpEventBase::decode(version
, it
);
289 decode(dst_snap_name
, it
);
292 decode(src_snap_name
, it
);
296 void SnapRenameEvent::dump(Formatter
*f
) const {
297 OpEventBase::dump(f
);
298 f
->dump_unsigned("src_snap_id", snap_id
);
299 f
->dump_string("src_snap_name", src_snap_name
);
300 f
->dump_string("dest_snap_name", dst_snap_name
);
303 void RenameEvent::encode(bufferlist
& bl
) const {
304 OpEventBase::encode(bl
);
306 encode(image_name
, bl
);
309 void RenameEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
310 OpEventBase::decode(version
, it
);
312 decode(image_name
, it
);
315 void RenameEvent::dump(Formatter
*f
) const {
316 OpEventBase::dump(f
);
317 f
->dump_string("image_name", image_name
);
320 void ResizeEvent::encode(bufferlist
& bl
) const {
321 OpEventBase::encode(bl
);
326 void ResizeEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
327 OpEventBase::decode(version
, it
);
332 void ResizeEvent::dump(Formatter
*f
) const {
333 OpEventBase::dump(f
);
334 f
->dump_unsigned("size", size
);
337 void DemotePromoteEvent::encode(bufferlist
& bl
) const {
340 void DemotePromoteEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
343 void DemotePromoteEvent::dump(Formatter
*f
) const {
346 void UpdateFeaturesEvent::encode(bufferlist
& bl
) const {
347 OpEventBase::encode(bl
);
349 encode(features
, bl
);
353 void UpdateFeaturesEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
354 OpEventBase::decode(version
, it
);
356 decode(features
, it
);
360 void UpdateFeaturesEvent::dump(Formatter
*f
) const {
361 OpEventBase::dump(f
);
362 f
->dump_unsigned("features", features
);
363 f
->dump_bool("enabled", enabled
);
366 void MetadataSetEvent::encode(bufferlist
& bl
) const {
367 OpEventBase::encode(bl
);
373 void MetadataSetEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
374 OpEventBase::decode(version
, it
);
380 void MetadataSetEvent::dump(Formatter
*f
) const {
381 OpEventBase::dump(f
);
382 f
->dump_string("key", key
);
383 f
->dump_string("value", value
);
386 void MetadataRemoveEvent::encode(bufferlist
& bl
) const {
387 OpEventBase::encode(bl
);
392 void MetadataRemoveEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
393 OpEventBase::decode(version
, it
);
398 void MetadataRemoveEvent::dump(Formatter
*f
) const {
399 OpEventBase::dump(f
);
400 f
->dump_string("key", key
);
403 void UnknownEvent::encode(bufferlist
& bl
) const {
407 void UnknownEvent::decode(__u8 version
, bufferlist::const_iterator
& it
) {
410 void UnknownEvent::dump(Formatter
*f
) const {
413 EventType
EventEntry::get_event_type() const {
414 return boost::apply_visitor(GetTypeVisitor
<EventType
>(), event
);
417 void EventEntry::encode(bufferlist
& bl
) const {
418 ENCODE_START(5, 1, bl
);
419 boost::apply_visitor(EncodeVisitor(bl
), event
);
424 void EventEntry::decode(bufferlist::const_iterator
& it
) {
428 decode(event_type
, it
);
430 // select the correct payload variant based upon the encoded op
431 switch (event_type
) {
432 case EVENT_TYPE_AIO_DISCARD
:
433 event
= AioDiscardEvent();
435 case EVENT_TYPE_AIO_WRITE
:
436 event
= AioWriteEvent();
438 case EVENT_TYPE_AIO_FLUSH
:
439 event
= AioFlushEvent();
441 case EVENT_TYPE_OP_FINISH
:
442 event
= OpFinishEvent();
444 case EVENT_TYPE_SNAP_CREATE
:
445 event
= SnapCreateEvent();
447 case EVENT_TYPE_SNAP_REMOVE
:
448 event
= SnapRemoveEvent();
450 case EVENT_TYPE_SNAP_RENAME
:
451 event
= SnapRenameEvent();
453 case EVENT_TYPE_SNAP_PROTECT
:
454 event
= SnapProtectEvent();
456 case EVENT_TYPE_SNAP_UNPROTECT
:
457 event
= SnapUnprotectEvent();
459 case EVENT_TYPE_SNAP_ROLLBACK
:
460 event
= SnapRollbackEvent();
462 case EVENT_TYPE_RENAME
:
463 event
= RenameEvent();
465 case EVENT_TYPE_RESIZE
:
466 event
= ResizeEvent();
468 case EVENT_TYPE_FLATTEN
:
469 event
= FlattenEvent();
471 case EVENT_TYPE_DEMOTE_PROMOTE
:
472 event
= DemotePromoteEvent();
474 case EVENT_TYPE_SNAP_LIMIT
:
475 event
= SnapLimitEvent();
477 case EVENT_TYPE_UPDATE_FEATURES
:
478 event
= UpdateFeaturesEvent();
480 case EVENT_TYPE_METADATA_SET
:
481 event
= MetadataSetEvent();
483 case EVENT_TYPE_METADATA_REMOVE
:
484 event
= MetadataRemoveEvent();
486 case EVENT_TYPE_AIO_WRITESAME
:
487 event
= AioWriteSameEvent();
489 case EVENT_TYPE_AIO_COMPARE_AND_WRITE
:
490 event
= AioCompareAndWriteEvent();
493 event
= UnknownEvent();
497 boost::apply_visitor(DecodeVisitor(struct_v
, it
), event
);
504 void EventEntry::dump(Formatter
*f
) const {
505 boost::apply_visitor(DumpVisitor(f
, "event_type"), event
);
506 f
->dump_stream("timestamp") << timestamp
;
509 void EventEntry::encode_metadata(bufferlist
& bl
) const {
510 ENCODE_START(1, 1, bl
);
511 encode(timestamp
, bl
);
515 void EventEntry::decode_metadata(bufferlist::const_iterator
& it
) {
517 decode(timestamp
, it
);
521 void EventEntry::generate_test_instances(std::list
<EventEntry
*> &o
) {
522 o
.push_back(new EventEntry(AioDiscardEvent()));
523 o
.push_back(new EventEntry(AioDiscardEvent(123, 345, 4096), utime_t(1, 1)));
526 bl
.append(std::string(32, '1'));
527 o
.push_back(new EventEntry(AioWriteEvent()));
528 o
.push_back(new EventEntry(AioWriteEvent(123, 456, bl
), utime_t(1, 1)));
530 o
.push_back(new EventEntry(AioFlushEvent()));
532 o
.push_back(new EventEntry(OpFinishEvent(123, -1), utime_t(1, 1)));
534 o
.push_back(new EventEntry(SnapCreateEvent(), utime_t(1, 1)));
535 o
.push_back(new EventEntry(SnapCreateEvent(234, cls::rbd::UserSnapshotNamespace(), "snap"), utime_t(1, 1)));
537 o
.push_back(new EventEntry(SnapRemoveEvent()));
538 o
.push_back(new EventEntry(SnapRemoveEvent(345, cls::rbd::UserSnapshotNamespace(), "snap"), utime_t(1, 1)));
540 o
.push_back(new EventEntry(SnapRenameEvent()));
541 o
.push_back(new EventEntry(SnapRenameEvent(456, 1, "src snap", "dest snap"),
544 o
.push_back(new EventEntry(SnapProtectEvent()));
545 o
.push_back(new EventEntry(SnapProtectEvent(567, cls::rbd::UserSnapshotNamespace(), "snap"), utime_t(1, 1)));
547 o
.push_back(new EventEntry(SnapUnprotectEvent()));
548 o
.push_back(new EventEntry(SnapUnprotectEvent(678, cls::rbd::UserSnapshotNamespace(), "snap"), utime_t(1, 1)));
550 o
.push_back(new EventEntry(SnapRollbackEvent()));
551 o
.push_back(new EventEntry(SnapRollbackEvent(789, cls::rbd::UserSnapshotNamespace(), "snap"), utime_t(1, 1)));
553 o
.push_back(new EventEntry(RenameEvent()));
554 o
.push_back(new EventEntry(RenameEvent(890, "image name"), utime_t(1, 1)));
556 o
.push_back(new EventEntry(ResizeEvent()));
557 o
.push_back(new EventEntry(ResizeEvent(901, 1234), utime_t(1, 1)));
559 o
.push_back(new EventEntry(FlattenEvent(123), utime_t(1, 1)));
561 o
.push_back(new EventEntry(DemotePromoteEvent()));
563 o
.push_back(new EventEntry(UpdateFeaturesEvent()));
564 o
.push_back(new EventEntry(UpdateFeaturesEvent(123, 127, true), utime_t(1, 1)));
566 o
.push_back(new EventEntry(MetadataSetEvent()));
567 o
.push_back(new EventEntry(MetadataSetEvent(123, "key", "value"), utime_t(1, 1)));
569 o
.push_back(new EventEntry(MetadataRemoveEvent()));
570 o
.push_back(new EventEntry(MetadataRemoveEvent(123, "key"), utime_t(1, 1)));
575 void ImageClientMeta::encode(bufferlist
& bl
) const {
577 encode(tag_class
, bl
);
578 encode(resync_requested
, bl
);
581 void ImageClientMeta::decode(__u8 version
, bufferlist::const_iterator
& it
) {
583 decode(tag_class
, it
);
584 decode(resync_requested
, it
);
587 void ImageClientMeta::dump(Formatter
*f
) const {
588 f
->dump_unsigned("tag_class", tag_class
);
589 f
->dump_bool("resync_requested", resync_requested
);
592 void MirrorPeerSyncPoint::encode(bufferlist
& bl
) const {
594 encode(snap_name
, bl
);
595 encode(from_snap_name
, bl
);
596 encode(object_number
, bl
);
597 encode(snap_namespace
, bl
);
600 void MirrorPeerSyncPoint::decode(__u8 version
, bufferlist::const_iterator
& it
) {
602 decode(snap_name
, it
);
603 decode(from_snap_name
, it
);
604 decode(object_number
, it
);
606 decode(snap_namespace
, it
);
610 void MirrorPeerSyncPoint::dump(Formatter
*f
) const {
611 f
->dump_string("snap_name", snap_name
);
612 f
->dump_string("from_snap_name", from_snap_name
);
614 f
->dump_unsigned("object_number", *object_number
);
616 snap_namespace
.dump(f
);
619 void MirrorPeerClientMeta::encode(bufferlist
& bl
) const {
621 encode(image_id
, bl
);
622 encode(static_cast<uint32_t>(state
), bl
);
623 encode(sync_object_count
, bl
);
624 encode(static_cast<uint32_t>(sync_points
.size()), bl
);
625 for (auto &sync_point
: sync_points
) {
626 sync_point
.encode(bl
);
628 encode(snap_seqs
, bl
);
631 void MirrorPeerClientMeta::decode(__u8 version
, bufferlist::const_iterator
& it
) {
633 decode(image_id
, it
);
635 uint32_t decode_state
;
636 decode(decode_state
, it
);
637 state
= static_cast<MirrorPeerState
>(decode_state
);
639 decode(sync_object_count
, it
);
641 uint32_t sync_point_count
;
642 decode(sync_point_count
, it
);
643 sync_points
.resize(sync_point_count
);
644 for (auto &sync_point
: sync_points
) {
645 sync_point
.decode(version
, it
);
648 decode(snap_seqs
, it
);
651 void MirrorPeerClientMeta::dump(Formatter
*f
) const {
652 f
->dump_string("image_id", image_id
);
653 f
->dump_stream("state") << state
;
654 f
->dump_unsigned("sync_object_count", sync_object_count
);
655 f
->open_array_section("sync_points");
656 for (auto &sync_point
: sync_points
) {
657 f
->open_object_section("sync_point");
662 f
->open_array_section("snap_seqs");
663 for (auto &pair
: snap_seqs
) {
664 f
->open_object_section("snap_seq");
665 f
->dump_unsigned("local_snap_seq", pair
.first
);
666 f
->dump_unsigned("peer_snap_seq", pair
.second
);
672 void CliClientMeta::encode(bufferlist
& bl
) const {
675 void CliClientMeta::decode(__u8 version
, bufferlist::const_iterator
& it
) {
678 void CliClientMeta::dump(Formatter
*f
) const {
681 void UnknownClientMeta::encode(bufferlist
& bl
) const {
685 void UnknownClientMeta::decode(__u8 version
, bufferlist::const_iterator
& it
) {
688 void UnknownClientMeta::dump(Formatter
*f
) const {
691 ClientMetaType
ClientData::get_client_meta_type() const {
692 return boost::apply_visitor(GetTypeVisitor
<ClientMetaType
>(), client_meta
);
695 void ClientData::encode(bufferlist
& bl
) const {
696 ENCODE_START(2, 1, bl
);
697 boost::apply_visitor(EncodeVisitor(bl
), client_meta
);
701 void ClientData::decode(bufferlist::const_iterator
& it
) {
704 uint32_t client_meta_type
;
705 decode(client_meta_type
, it
);
707 // select the correct payload variant based upon the encoded op
708 switch (client_meta_type
) {
709 case IMAGE_CLIENT_META_TYPE
:
710 client_meta
= ImageClientMeta();
712 case MIRROR_PEER_CLIENT_META_TYPE
:
713 client_meta
= MirrorPeerClientMeta();
715 case CLI_CLIENT_META_TYPE
:
716 client_meta
= CliClientMeta();
719 client_meta
= UnknownClientMeta();
723 boost::apply_visitor(DecodeVisitor(struct_v
, it
), client_meta
);
727 void ClientData::dump(Formatter
*f
) const {
728 boost::apply_visitor(DumpVisitor(f
, "client_meta_type"), client_meta
);
731 void ClientData::generate_test_instances(std::list
<ClientData
*> &o
) {
732 o
.push_back(new ClientData(ImageClientMeta()));
733 o
.push_back(new ClientData(ImageClientMeta(123)));
734 o
.push_back(new ClientData(MirrorPeerClientMeta()));
735 o
.push_back(new ClientData(MirrorPeerClientMeta("image_id",
736 {{{}, "snap 2", "snap 1", 123}},
738 o
.push_back(new ClientData(CliClientMeta()));
743 void TagPredecessor::encode(bufferlist
& bl
) const {
745 encode(mirror_uuid
, bl
);
746 encode(commit_valid
, bl
);
748 encode(entry_tid
, bl
);
751 void TagPredecessor::decode(bufferlist::const_iterator
& it
) {
753 decode(mirror_uuid
, it
);
754 decode(commit_valid
, it
);
756 decode(entry_tid
, it
);
759 void TagPredecessor::dump(Formatter
*f
) const {
760 f
->dump_string("mirror_uuid", mirror_uuid
);
761 f
->dump_string("commit_valid", commit_valid
? "true" : "false");
762 f
->dump_unsigned("tag_tid", tag_tid
);
763 f
->dump_unsigned("entry_tid", entry_tid
);
766 void TagData::encode(bufferlist
& bl
) const {
768 encode(mirror_uuid
, bl
);
769 predecessor
.encode(bl
);
772 void TagData::decode(bufferlist::const_iterator
& it
) {
774 decode(mirror_uuid
, it
);
775 predecessor
.decode(it
);
778 void TagData::dump(Formatter
*f
) const {
779 f
->dump_string("mirror_uuid", mirror_uuid
);
780 f
->open_object_section("predecessor");
785 void TagData::generate_test_instances(std::list
<TagData
*> &o
) {
786 o
.push_back(new TagData());
787 o
.push_back(new TagData("mirror-uuid"));
788 o
.push_back(new TagData("mirror-uuid", "remote-mirror-uuid", true, 123, 234));
791 std::ostream
&operator<<(std::ostream
&out
, const EventType
&type
) {
792 using namespace librbd::journal
;
795 case EVENT_TYPE_AIO_DISCARD
:
798 case EVENT_TYPE_AIO_WRITE
:
801 case EVENT_TYPE_AIO_FLUSH
:
804 case EVENT_TYPE_OP_FINISH
:
807 case EVENT_TYPE_SNAP_CREATE
:
810 case EVENT_TYPE_SNAP_REMOVE
:
813 case EVENT_TYPE_SNAP_RENAME
:
816 case EVENT_TYPE_SNAP_PROTECT
:
817 out
<< "SnapProtect";
819 case EVENT_TYPE_SNAP_UNPROTECT
:
820 out
<< "SnapUnprotect";
822 case EVENT_TYPE_SNAP_ROLLBACK
:
823 out
<< "SnapRollback";
825 case EVENT_TYPE_RENAME
:
828 case EVENT_TYPE_RESIZE
:
831 case EVENT_TYPE_FLATTEN
:
834 case EVENT_TYPE_DEMOTE_PROMOTE
:
835 out
<< "Demote/Promote";
837 case EVENT_TYPE_SNAP_LIMIT
:
840 case EVENT_TYPE_UPDATE_FEATURES
:
841 out
<< "UpdateFeatures";
843 case EVENT_TYPE_METADATA_SET
:
844 out
<< "MetadataSet";
846 case EVENT_TYPE_METADATA_REMOVE
:
847 out
<< "MetadataRemove";
849 case EVENT_TYPE_AIO_WRITESAME
:
850 out
<< "AioWriteSame";
852 case EVENT_TYPE_AIO_COMPARE_AND_WRITE
:
853 out
<< "AioCompareAndWrite";
856 out
<< "Unknown (" << static_cast<uint32_t>(type
) << ")";
862 std::ostream
&operator<<(std::ostream
&out
, const ClientMetaType
&type
) {
863 using namespace librbd::journal
;
866 case IMAGE_CLIENT_META_TYPE
:
867 out
<< "Master Image";
869 case MIRROR_PEER_CLIENT_META_TYPE
:
870 out
<< "Mirror Peer";
872 case CLI_CLIENT_META_TYPE
:
876 out
<< "Unknown (" << static_cast<uint32_t>(type
) << ")";
882 std::ostream
&operator<<(std::ostream
&out
, const ImageClientMeta
&meta
) {
883 out
<< "[tag_class=" << meta
.tag_class
<< "]";
887 std::ostream
&operator<<(std::ostream
&out
, const MirrorPeerSyncPoint
&sync
) {
888 out
<< "[snap_name=" << sync
.snap_name
<< ", "
889 << "from_snap_name=" << sync
.from_snap_name
;
890 if (sync
.object_number
) {
891 out
<< ", " << *sync
.object_number
;
897 std::ostream
&operator<<(std::ostream
&out
, const MirrorPeerState
&state
) {
899 case MIRROR_PEER_STATE_SYNCING
:
902 case MIRROR_PEER_STATE_REPLAYING
:
906 out
<< "Unknown (" << static_cast<uint32_t>(state
) << ")";
912 std::ostream
&operator<<(std::ostream
&out
, const MirrorPeerClientMeta
&meta
) {
913 out
<< "[image_id=" << meta
.image_id
<< ", "
914 << "state=" << meta
.state
<< ", "
915 << "sync_object_count=" << meta
.sync_object_count
<< ", "
917 std::string delimiter
;
918 for (auto &sync_point
: meta
.sync_points
) {
919 out
<< delimiter
<< "[" << sync_point
<< "]";
922 out
<< "], snap_seqs=[";
924 for (auto &pair
: meta
.snap_seqs
) {
925 out
<< delimiter
<< "["
926 << "local_snap_seq=" << pair
.first
<< ", "
927 << "peer_snap_seq" << pair
.second
<< "]";
934 std::ostream
&operator<<(std::ostream
&out
, const TagPredecessor
&predecessor
) {
936 << "mirror_uuid=" << predecessor
.mirror_uuid
;
937 if (predecessor
.commit_valid
) {
939 << "tag_tid=" << predecessor
.tag_tid
<< ", "
940 << "entry_tid=" << predecessor
.entry_tid
;
946 std::ostream
&operator<<(std::ostream
&out
, const TagData
&tag_data
) {
948 << "mirror_uuid=" << tag_data
.mirror_uuid
<< ", "
949 << "predecessor=" << tag_data
.predecessor
954 } // namespace journal
955 } // namespace librbd