1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_LIBRBD_JOURNAL_TYPES_H
5 #define CEPH_LIBRBD_JOURNAL_TYPES_H
7 #include "cls/rbd/cls_rbd_types.h"
8 #include "include/int_types.h"
9 #include "include/buffer.h"
10 #include "include/encoding.h"
11 #include "include/types.h"
12 #include "include/utime.h"
13 #include "librbd/Types.h"
16 #include <boost/none.hpp>
17 #include <boost/optional.hpp>
18 #include <boost/variant.hpp>
19 #include <boost/mpl/vector.hpp>
29 EVENT_TYPE_AIO_DISCARD
= 0,
30 EVENT_TYPE_AIO_WRITE
= 1,
31 EVENT_TYPE_AIO_FLUSH
= 2,
32 EVENT_TYPE_OP_FINISH
= 3,
33 EVENT_TYPE_SNAP_CREATE
= 4,
34 EVENT_TYPE_SNAP_REMOVE
= 5,
35 EVENT_TYPE_SNAP_RENAME
= 6,
36 EVENT_TYPE_SNAP_PROTECT
= 7,
37 EVENT_TYPE_SNAP_UNPROTECT
= 8,
38 EVENT_TYPE_SNAP_ROLLBACK
= 9,
39 EVENT_TYPE_RENAME
= 10,
40 EVENT_TYPE_RESIZE
= 11,
41 EVENT_TYPE_FLATTEN
= 12,
42 EVENT_TYPE_DEMOTE_PROMOTE
= 13,
43 EVENT_TYPE_SNAP_LIMIT
= 14,
44 EVENT_TYPE_UPDATE_FEATURES
= 15,
45 EVENT_TYPE_METADATA_SET
= 16,
46 EVENT_TYPE_METADATA_REMOVE
= 17,
47 EVENT_TYPE_AIO_WRITESAME
= 18,
48 EVENT_TYPE_AIO_COMPARE_AND_WRITE
= 19,
51 struct AioDiscardEvent
{
52 static const EventType TYPE
= EVENT_TYPE_AIO_DISCARD
;
56 uint32_t discard_granularity_bytes
= 0;
60 AioDiscardEvent(uint64_t _offset
, uint64_t _length
,
61 uint32_t discard_granularity_bytes
)
62 : offset(_offset
), length(_length
),
63 discard_granularity_bytes(discard_granularity_bytes
) {
66 void encode(bufferlist
& bl
) const;
67 void decode(__u8 version
, bufferlist::const_iterator
& it
);
68 void dump(Formatter
*f
) const;
71 struct AioWriteEvent
{
72 static const EventType TYPE
= EVENT_TYPE_AIO_WRITE
;
78 static uint32_t get_fixed_size();
80 AioWriteEvent() : offset(0), length(0) {
82 AioWriteEvent(uint64_t _offset
, uint64_t _length
, const bufferlist
&_data
)
83 : offset(_offset
), length(_length
), data(_data
) {
86 void encode(bufferlist
& bl
) const;
87 void decode(__u8 version
, bufferlist::const_iterator
& it
);
88 void dump(Formatter
*f
) const;
91 struct AioWriteSameEvent
{
92 static const EventType TYPE
= EVENT_TYPE_AIO_WRITESAME
;
98 AioWriteSameEvent() : offset(0), length(0) {
100 AioWriteSameEvent(uint64_t _offset
, uint64_t _length
,
101 const bufferlist
&_data
)
102 : offset(_offset
), length(_length
), data(_data
) {
105 void encode(bufferlist
& bl
) const;
106 void decode(__u8 version
, bufferlist::const_iterator
& it
);
107 void dump(Formatter
*f
) const;
110 struct AioCompareAndWriteEvent
{
111 static const EventType TYPE
= EVENT_TYPE_AIO_COMPARE_AND_WRITE
;
116 bufferlist write_data
;
118 static uint32_t get_fixed_size();
120 AioCompareAndWriteEvent() : offset(0), length(0) {
122 AioCompareAndWriteEvent(uint64_t _offset
, uint64_t _length
,
123 const bufferlist
&_cmp_data
, const bufferlist
&_write_data
)
124 : offset(_offset
), length(_length
), cmp_data(_cmp_data
), write_data(_write_data
) {
127 void encode(bufferlist
& bl
) const;
128 void decode(__u8 version
, bufferlist::const_iterator
& it
);
129 void dump(Formatter
*f
) const;
132 struct AioFlushEvent
{
133 static const EventType TYPE
= EVENT_TYPE_AIO_FLUSH
;
135 void encode(bufferlist
& bl
) const;
136 void decode(__u8 version
, bufferlist::const_iterator
& it
);
137 void dump(Formatter
*f
) const;
144 OpEventBase() : op_tid(0) {
146 OpEventBase(uint64_t op_tid
) : op_tid(op_tid
) {
149 void encode(bufferlist
& bl
) const;
150 void decode(__u8 version
, bufferlist::const_iterator
& it
);
151 void dump(Formatter
*f
) const;
154 struct OpFinishEvent
: public OpEventBase
{
155 static const EventType TYPE
= EVENT_TYPE_OP_FINISH
;
159 OpFinishEvent() : r(0) {
161 OpFinishEvent(uint64_t op_tid
, int r
) : OpEventBase(op_tid
), r(r
) {
164 void encode(bufferlist
& bl
) const;
165 void decode(__u8 version
, bufferlist::const_iterator
& it
);
166 void dump(Formatter
*f
) const;
169 struct SnapEventBase
: public OpEventBase
{
170 cls::rbd::SnapshotNamespace snap_namespace
;
171 std::string snap_name
;
176 SnapEventBase(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& _snap_namespace
,
177 const std::string
&_snap_name
)
178 : OpEventBase(op_tid
),
179 snap_namespace(_snap_namespace
),
180 snap_name(_snap_name
) {
183 void encode(bufferlist
& bl
) const;
184 void decode(__u8 version
, bufferlist::const_iterator
& it
);
185 void dump(Formatter
*f
) const;
188 struct SnapCreateEvent
: public SnapEventBase
{
189 static const EventType TYPE
= EVENT_TYPE_SNAP_CREATE
;
193 SnapCreateEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& snap_namespace
,
194 const std::string
&snap_name
)
195 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
198 void encode(bufferlist
& bl
) const;
199 void decode(__u8 version
, bufferlist::const_iterator
& it
);
200 void dump(Formatter
*f
) const;
203 struct SnapRemoveEvent
: public SnapEventBase
{
204 static const EventType TYPE
= EVENT_TYPE_SNAP_REMOVE
;
208 SnapRemoveEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& snap_namespace
,
209 const std::string
&snap_name
)
210 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
213 using SnapEventBase::encode
;
214 using SnapEventBase::decode
;
215 using SnapEventBase::dump
;
218 struct SnapRenameEvent
: public OpEventBase
{
219 static const EventType TYPE
= EVENT_TYPE_SNAP_RENAME
;
222 std::string src_snap_name
;
223 std::string dst_snap_name
;
225 SnapRenameEvent() : snap_id(CEPH_NOSNAP
) {
227 SnapRenameEvent(uint64_t op_tid
, uint64_t src_snap_id
,
228 const std::string
&src_snap_name
,
229 const std::string
&dest_snap_name
)
230 : OpEventBase(op_tid
),
231 snap_id(src_snap_id
),
232 src_snap_name(src_snap_name
),
233 dst_snap_name(dest_snap_name
) {
236 void encode(bufferlist
& bl
) const;
237 void decode(__u8 version
, bufferlist::const_iterator
& it
);
238 void dump(Formatter
*f
) const;
241 struct SnapProtectEvent
: public SnapEventBase
{
242 static const EventType TYPE
= EVENT_TYPE_SNAP_PROTECT
;
246 SnapProtectEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& snap_namespace
,
247 const std::string
&snap_name
)
248 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
251 using SnapEventBase::encode
;
252 using SnapEventBase::decode
;
253 using SnapEventBase::dump
;
256 struct SnapUnprotectEvent
: public SnapEventBase
{
257 static const EventType TYPE
= EVENT_TYPE_SNAP_UNPROTECT
;
259 SnapUnprotectEvent() {
261 SnapUnprotectEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
&snap_namespace
,
262 const std::string
&snap_name
)
263 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
266 using SnapEventBase::encode
;
267 using SnapEventBase::decode
;
268 using SnapEventBase::dump
;
271 struct SnapLimitEvent
: public OpEventBase
{
272 static const EventType TYPE
= EVENT_TYPE_SNAP_LIMIT
;
277 SnapLimitEvent(uint64_t op_tid
, const uint64_t _limit
)
278 : OpEventBase(op_tid
), limit(_limit
) {
281 void encode(bufferlist
& bl
) const;
282 void decode(__u8 version
, bufferlist::const_iterator
& it
);
283 void dump(Formatter
*f
) const;
286 struct SnapRollbackEvent
: public SnapEventBase
{
287 static const EventType TYPE
= EVENT_TYPE_SNAP_ROLLBACK
;
289 SnapRollbackEvent() {
291 SnapRollbackEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& snap_namespace
,
292 const std::string
&snap_name
)
293 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
296 using SnapEventBase::encode
;
297 using SnapEventBase::decode
;
298 using SnapEventBase::dump
;
301 struct RenameEvent
: public OpEventBase
{
302 static const EventType TYPE
= EVENT_TYPE_RENAME
;
304 std::string image_name
;
308 RenameEvent(uint64_t op_tid
, const std::string
&_image_name
)
309 : OpEventBase(op_tid
), image_name(_image_name
) {
312 void encode(bufferlist
& bl
) const;
313 void decode(__u8 version
, bufferlist::const_iterator
& it
);
314 void dump(Formatter
*f
) const;
317 struct ResizeEvent
: public OpEventBase
{
318 static const EventType TYPE
= EVENT_TYPE_RESIZE
;
322 ResizeEvent() : size(0) {
324 ResizeEvent(uint64_t op_tid
, uint64_t _size
)
325 : OpEventBase(op_tid
), size(_size
) {
328 void encode(bufferlist
& bl
) const;
329 void decode(__u8 version
, bufferlist::const_iterator
& it
);
330 void dump(Formatter
*f
) const;
333 struct FlattenEvent
: public OpEventBase
{
334 static const EventType TYPE
= EVENT_TYPE_FLATTEN
;
338 FlattenEvent(uint64_t op_tid
) : OpEventBase(op_tid
) {
341 using OpEventBase::encode
;
342 using OpEventBase::decode
;
343 using OpEventBase::dump
;
346 struct DemotePromoteEvent
{
347 static const EventType TYPE
= static_cast<EventType
>(
348 EVENT_TYPE_DEMOTE_PROMOTE
);
350 void encode(bufferlist
& bl
) const;
351 void decode(__u8 version
, bufferlist::const_iterator
& it
);
352 void dump(Formatter
*f
) const;
355 struct UpdateFeaturesEvent
: public OpEventBase
{
356 static const EventType TYPE
= EVENT_TYPE_UPDATE_FEATURES
;
361 UpdateFeaturesEvent() : features(0), enabled(false) {
363 UpdateFeaturesEvent(uint64_t op_tid
, uint64_t _features
, bool _enabled
)
364 : OpEventBase(op_tid
), features(_features
), enabled(_enabled
) {
367 void encode(bufferlist
& bl
) const;
368 void decode(__u8 version
, bufferlist::const_iterator
& it
);
369 void dump(Formatter
*f
) const;
372 struct MetadataSetEvent
: public OpEventBase
{
373 static const EventType TYPE
= EVENT_TYPE_METADATA_SET
;
380 MetadataSetEvent(uint64_t op_tid
, const std::string
&_key
, const std::string
&_value
)
381 : OpEventBase(op_tid
), key(_key
), value(_value
) {
384 void encode(bufferlist
& bl
) const;
385 void decode(__u8 version
, bufferlist::const_iterator
& it
);
386 void dump(Formatter
*f
) const;
389 struct MetadataRemoveEvent
: public OpEventBase
{
390 static const EventType TYPE
= EVENT_TYPE_METADATA_REMOVE
;
394 MetadataRemoveEvent() {
396 MetadataRemoveEvent(uint64_t op_tid
, const std::string
&_key
)
397 : OpEventBase(op_tid
), key(_key
) {
400 void encode(bufferlist
& bl
) const;
401 void decode(__u8 version
, bufferlist::const_iterator
& it
);
402 void dump(Formatter
*f
) const;
405 struct UnknownEvent
{
406 static const EventType TYPE
= static_cast<EventType
>(-1);
408 void encode(bufferlist
& bl
) const;
409 void decode(__u8 version
, bufferlist::const_iterator
& it
);
410 void dump(Formatter
*f
) const;
413 typedef boost::mpl::vector
<AioDiscardEvent
,
432 AioCompareAndWriteEvent
,
433 UnknownEvent
> EventVector
;
434 typedef boost::make_variant_over
<EventVector
>::type Event
;
437 static uint32_t get_fixed_size() {
438 return EVENT_FIXED_SIZE
+ METADATA_FIXED_SIZE
;
441 EventEntry() : event(UnknownEvent()) {
443 EventEntry(const Event
&_event
, const utime_t
&_timestamp
= utime_t())
444 : event(_event
), timestamp(_timestamp
) {
450 EventType
get_event_type() const;
452 void encode(bufferlist
& bl
) const;
453 void decode(bufferlist::const_iterator
& it
);
454 void dump(Formatter
*f
) const;
456 static void generate_test_instances(std::list
<EventEntry
*> &o
);
459 static const uint32_t EVENT_FIXED_SIZE
= 14; /// version encoding, type
460 static const uint32_t METADATA_FIXED_SIZE
= 14; /// version encoding, timestamp
462 void encode_metadata(bufferlist
& bl
) const;
463 void decode_metadata(bufferlist::const_iterator
& it
);
466 // Journal Client data structures
468 enum ClientMetaType
{
469 IMAGE_CLIENT_META_TYPE
= 0,
470 MIRROR_PEER_CLIENT_META_TYPE
= 1,
471 CLI_CLIENT_META_TYPE
= 2
474 struct ImageClientMeta
{
475 static const ClientMetaType TYPE
= IMAGE_CLIENT_META_TYPE
;
477 uint64_t tag_class
= 0;
478 bool resync_requested
= false;
482 ImageClientMeta(uint64_t tag_class
) : tag_class(tag_class
) {
485 void encode(bufferlist
& bl
) const;
486 void decode(__u8 version
, bufferlist::const_iterator
& it
);
487 void dump(Formatter
*f
) const;
490 struct MirrorPeerSyncPoint
{
491 typedef boost::optional
<uint64_t> ObjectNumber
;
493 cls::rbd::SnapshotNamespace snap_namespace
;
494 std::string snap_name
;
495 std::string from_snap_name
;
496 ObjectNumber object_number
;
498 MirrorPeerSyncPoint() : MirrorPeerSyncPoint({}, "", "", boost::none
) {
500 MirrorPeerSyncPoint(const cls::rbd::SnapshotNamespace
& snap_namespace
,
501 const std::string
&snap_name
,
502 const ObjectNumber
&object_number
)
503 : MirrorPeerSyncPoint(snap_namespace
, snap_name
, "", object_number
) {
505 MirrorPeerSyncPoint(const cls::rbd::SnapshotNamespace
& snap_namespace
,
506 const std::string
&snap_name
,
507 const std::string
&from_snap_name
,
508 const ObjectNumber
&object_number
)
509 : snap_namespace(snap_namespace
), snap_name(snap_name
),
510 from_snap_name(from_snap_name
), object_number(object_number
) {
513 inline bool operator==(const MirrorPeerSyncPoint
&sync
) const {
514 return (snap_name
== sync
.snap_name
&&
515 from_snap_name
== sync
.from_snap_name
&&
516 object_number
== sync
.object_number
&&
517 snap_namespace
== sync
.snap_namespace
);
520 void encode(bufferlist
& bl
) const;
521 void decode(__u8 version
, bufferlist::const_iterator
& it
);
522 void dump(Formatter
*f
) const;
525 enum MirrorPeerState
{
526 MIRROR_PEER_STATE_SYNCING
,
527 MIRROR_PEER_STATE_REPLAYING
530 struct MirrorPeerClientMeta
{
531 typedef std::list
<MirrorPeerSyncPoint
> SyncPoints
;
533 static const ClientMetaType TYPE
= MIRROR_PEER_CLIENT_META_TYPE
;
535 std::string image_id
;
536 MirrorPeerState state
= MIRROR_PEER_STATE_SYNCING
; ///< replay state
537 uint64_t sync_object_count
= 0; ///< maximum number of objects ever sync'ed
538 SyncPoints sync_points
; ///< max two in-use snapshots for sync
539 SnapSeqs snap_seqs
; ///< local to peer snap seq mapping
541 MirrorPeerClientMeta() {
543 MirrorPeerClientMeta(const std::string
&image_id
,
544 const SyncPoints
&sync_points
= SyncPoints(),
545 const SnapSeqs
&snap_seqs
= SnapSeqs())
546 : image_id(image_id
), sync_points(sync_points
), snap_seqs(snap_seqs
) {
549 inline bool operator==(const MirrorPeerClientMeta
&meta
) const {
550 return (image_id
== meta
.image_id
&&
551 state
== meta
.state
&&
552 sync_object_count
== meta
.sync_object_count
&&
553 sync_points
== meta
.sync_points
&&
554 snap_seqs
== meta
.snap_seqs
);
557 void encode(bufferlist
& bl
) const;
558 void decode(__u8 version
, bufferlist::const_iterator
& it
);
559 void dump(Formatter
*f
) const;
562 struct CliClientMeta
{
563 static const ClientMetaType TYPE
= CLI_CLIENT_META_TYPE
;
565 void encode(bufferlist
& bl
) const;
566 void decode(__u8 version
, bufferlist::const_iterator
& it
);
567 void dump(Formatter
*f
) const;
570 struct UnknownClientMeta
{
571 static const ClientMetaType TYPE
= static_cast<ClientMetaType
>(-1);
573 void encode(bufferlist
& bl
) const;
574 void decode(__u8 version
, bufferlist::const_iterator
& it
);
575 void dump(Formatter
*f
) const;
578 typedef boost::variant
<ImageClientMeta
,
579 MirrorPeerClientMeta
,
581 UnknownClientMeta
> ClientMeta
;
586 ClientData(const ClientMeta
&client_meta
) : client_meta(client_meta
) {
589 ClientMeta client_meta
;
591 ClientMetaType
get_client_meta_type() const;
593 void encode(bufferlist
& bl
) const;
594 void decode(bufferlist::const_iterator
& it
);
595 void dump(Formatter
*f
) const;
597 static void generate_test_instances(std::list
<ClientData
*> &o
);
600 // Journal Tag data structures
602 struct TagPredecessor
{
603 std::string mirror_uuid
; // empty if local
604 bool commit_valid
= false;
605 uint64_t tag_tid
= 0;
606 uint64_t entry_tid
= 0;
610 TagPredecessor(const std::string
&mirror_uuid
, bool commit_valid
,
611 uint64_t tag_tid
, uint64_t entry_tid
)
612 : mirror_uuid(mirror_uuid
), commit_valid(commit_valid
), tag_tid(tag_tid
),
613 entry_tid(entry_tid
) {
616 inline bool operator==(const TagPredecessor
&rhs
) const {
617 return (mirror_uuid
== rhs
.mirror_uuid
&&
618 commit_valid
== rhs
.commit_valid
&&
619 tag_tid
== rhs
.tag_tid
&&
620 entry_tid
== rhs
.entry_tid
);
623 void encode(bufferlist
& bl
) const;
624 void decode(bufferlist::const_iterator
& it
);
625 void dump(Formatter
*f
) const;
629 // owner of the tag (exclusive lock epoch)
630 std::string mirror_uuid
; // empty if local
632 // mapping to last committed record of previous tag
633 TagPredecessor predecessor
;
637 TagData(const std::string
&mirror_uuid
) : mirror_uuid(mirror_uuid
) {
639 TagData(const std::string
&mirror_uuid
,
640 const std::string
&predecessor_mirror_uuid
,
641 bool predecessor_commit_valid
,
642 uint64_t predecessor_tag_tid
, uint64_t predecessor_entry_tid
)
643 : mirror_uuid(mirror_uuid
),
644 predecessor(predecessor_mirror_uuid
, predecessor_commit_valid
,
645 predecessor_tag_tid
, predecessor_entry_tid
) {
648 void encode(bufferlist
& bl
) const;
649 void decode(bufferlist::const_iterator
& it
);
650 void dump(Formatter
*f
) const;
652 static void generate_test_instances(std::list
<TagData
*> &o
);
655 std::ostream
&operator<<(std::ostream
&out
, const EventType
&type
);
656 std::ostream
&operator<<(std::ostream
&out
, const ClientMetaType
&type
);
657 std::ostream
&operator<<(std::ostream
&out
, const ImageClientMeta
&meta
);
658 std::ostream
&operator<<(std::ostream
&out
, const MirrorPeerSyncPoint
&sync
);
659 std::ostream
&operator<<(std::ostream
&out
, const MirrorPeerState
&meta
);
660 std::ostream
&operator<<(std::ostream
&out
, const MirrorPeerClientMeta
&meta
);
661 std::ostream
&operator<<(std::ostream
&out
, const TagPredecessor
&predecessor
);
662 std::ostream
&operator<<(std::ostream
&out
, const TagData
&tag_data
);
665 virtual ~Listener() {
668 /// invoked when journal close is requested
669 virtual void handle_close() = 0;
671 /// invoked when journal is promoted to primary
672 virtual void handle_promoted() = 0;
674 /// invoked when journal resync is requested
675 virtual void handle_resync() = 0;
678 WRITE_CLASS_ENCODER(EventEntry
);
679 WRITE_CLASS_ENCODER(ClientData
);
680 WRITE_CLASS_ENCODER(TagData
);
682 } // namespace journal
683 } // namespace librbd
685 #endif // CEPH_LIBRBD_JOURNAL_TYPES_H