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"
15 #include <boost/none.hpp>
16 #include <boost/optional.hpp>
17 #include <boost/variant.hpp>
27 EVENT_TYPE_AIO_DISCARD
= 0,
28 EVENT_TYPE_AIO_WRITE
= 1,
29 EVENT_TYPE_AIO_FLUSH
= 2,
30 EVENT_TYPE_OP_FINISH
= 3,
31 EVENT_TYPE_SNAP_CREATE
= 4,
32 EVENT_TYPE_SNAP_REMOVE
= 5,
33 EVENT_TYPE_SNAP_RENAME
= 6,
34 EVENT_TYPE_SNAP_PROTECT
= 7,
35 EVENT_TYPE_SNAP_UNPROTECT
= 8,
36 EVENT_TYPE_SNAP_ROLLBACK
= 9,
37 EVENT_TYPE_RENAME
= 10,
38 EVENT_TYPE_RESIZE
= 11,
39 EVENT_TYPE_FLATTEN
= 12,
40 EVENT_TYPE_DEMOTE_PROMOTE
= 13,
41 EVENT_TYPE_SNAP_LIMIT
= 14,
42 EVENT_TYPE_UPDATE_FEATURES
= 15,
43 EVENT_TYPE_METADATA_SET
= 16,
44 EVENT_TYPE_METADATA_REMOVE
= 17,
45 EVENT_TYPE_AIO_WRITESAME
= 18,
48 struct AioDiscardEvent
{
49 static const EventType TYPE
= EVENT_TYPE_AIO_DISCARD
;
53 bool skip_partial_discard
;
55 AioDiscardEvent() : offset(0), length(0), skip_partial_discard(false) {
57 AioDiscardEvent(uint64_t _offset
, uint64_t _length
, bool _skip_partial_discard
)
58 : offset(_offset
), length(_length
), skip_partial_discard(_skip_partial_discard
) {
61 void encode(bufferlist
& bl
) const;
62 void decode(__u8 version
, bufferlist::iterator
& it
);
63 void dump(Formatter
*f
) const;
66 struct AioWriteEvent
{
67 static const EventType TYPE
= EVENT_TYPE_AIO_WRITE
;
73 static uint32_t get_fixed_size();
75 AioWriteEvent() : offset(0), length(0) {
77 AioWriteEvent(uint64_t _offset
, uint64_t _length
, const bufferlist
&_data
)
78 : offset(_offset
), length(_length
), data(_data
) {
81 void encode(bufferlist
& bl
) const;
82 void decode(__u8 version
, bufferlist::iterator
& it
);
83 void dump(Formatter
*f
) const;
86 struct AioWriteSameEvent
{
87 static const EventType TYPE
= EVENT_TYPE_AIO_WRITESAME
;
93 AioWriteSameEvent() : offset(0), length(0) {
95 AioWriteSameEvent(uint64_t _offset
, uint64_t _length
,
96 const bufferlist
&_data
)
97 : offset(_offset
), length(_length
), data(_data
) {
100 void encode(bufferlist
& bl
) const;
101 void decode(__u8 version
, bufferlist::iterator
& it
);
102 void dump(Formatter
*f
) const;
105 struct AioFlushEvent
{
106 static const EventType TYPE
= EVENT_TYPE_AIO_FLUSH
;
108 void encode(bufferlist
& bl
) const;
109 void decode(__u8 version
, bufferlist::iterator
& it
);
110 void dump(Formatter
*f
) const;
117 OpEventBase() : op_tid(0) {
119 OpEventBase(uint64_t op_tid
) : op_tid(op_tid
) {
122 void encode(bufferlist
& bl
) const;
123 void decode(__u8 version
, bufferlist::iterator
& it
);
124 void dump(Formatter
*f
) const;
127 struct OpFinishEvent
: public OpEventBase
{
128 static const EventType TYPE
= EVENT_TYPE_OP_FINISH
;
132 OpFinishEvent() : r(0) {
134 OpFinishEvent(uint64_t op_tid
, int r
) : OpEventBase(op_tid
), r(r
) {
137 void encode(bufferlist
& bl
) const;
138 void decode(__u8 version
, bufferlist::iterator
& it
);
139 void dump(Formatter
*f
) const;
142 struct SnapEventBase
: public OpEventBase
{
143 cls::rbd::SnapshotNamespace snap_namespace
;
144 std::string snap_name
;
149 SnapEventBase(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& _snap_namespace
,
150 const std::string
&_snap_name
)
151 : OpEventBase(op_tid
),
152 snap_namespace(_snap_namespace
),
153 snap_name(_snap_name
) {
156 void encode(bufferlist
& bl
) const;
157 void decode(__u8 version
, bufferlist::iterator
& it
);
158 void dump(Formatter
*f
) const;
161 struct SnapCreateEvent
: public SnapEventBase
{
162 static const EventType TYPE
= EVENT_TYPE_SNAP_CREATE
;
166 SnapCreateEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& snap_namespace
,
167 const std::string
&snap_name
)
168 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
171 void encode(bufferlist
& bl
) const;
172 void decode(__u8 version
, bufferlist::iterator
& it
);
173 void dump(Formatter
*f
) const;
176 struct SnapRemoveEvent
: public SnapEventBase
{
177 static const EventType TYPE
= EVENT_TYPE_SNAP_REMOVE
;
181 SnapRemoveEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& snap_namespace
,
182 const std::string
&snap_name
)
183 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
186 using SnapEventBase::encode
;
187 using SnapEventBase::decode
;
188 using SnapEventBase::dump
;
191 struct SnapRenameEvent
: public OpEventBase
{
192 static const EventType TYPE
= EVENT_TYPE_SNAP_RENAME
;
195 std::string src_snap_name
;
196 std::string dst_snap_name
;
198 SnapRenameEvent() : snap_id(CEPH_NOSNAP
) {
200 SnapRenameEvent(uint64_t op_tid
, uint64_t src_snap_id
,
201 const std::string
&src_snap_name
,
202 const std::string
&dest_snap_name
)
203 : OpEventBase(op_tid
),
204 snap_id(src_snap_id
),
205 src_snap_name(src_snap_name
),
206 dst_snap_name(dest_snap_name
) {
209 void encode(bufferlist
& bl
) const;
210 void decode(__u8 version
, bufferlist::iterator
& it
);
211 void dump(Formatter
*f
) const;
214 struct SnapProtectEvent
: public SnapEventBase
{
215 static const EventType TYPE
= EVENT_TYPE_SNAP_PROTECT
;
219 SnapProtectEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& snap_namespace
,
220 const std::string
&snap_name
)
221 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
224 using SnapEventBase::encode
;
225 using SnapEventBase::decode
;
226 using SnapEventBase::dump
;
229 struct SnapUnprotectEvent
: public SnapEventBase
{
230 static const EventType TYPE
= EVENT_TYPE_SNAP_UNPROTECT
;
232 SnapUnprotectEvent() {
234 SnapUnprotectEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
&snap_namespace
,
235 const std::string
&snap_name
)
236 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
239 using SnapEventBase::encode
;
240 using SnapEventBase::decode
;
241 using SnapEventBase::dump
;
244 struct SnapLimitEvent
: public OpEventBase
{
245 static const EventType TYPE
= EVENT_TYPE_SNAP_LIMIT
;
250 SnapLimitEvent(uint64_t op_tid
, const uint64_t _limit
)
251 : OpEventBase(op_tid
), limit(_limit
) {
254 void encode(bufferlist
& bl
) const;
255 void decode(__u8 version
, bufferlist::iterator
& it
);
256 void dump(Formatter
*f
) const;
259 struct SnapRollbackEvent
: public SnapEventBase
{
260 static const EventType TYPE
= EVENT_TYPE_SNAP_ROLLBACK
;
262 SnapRollbackEvent() {
264 SnapRollbackEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& snap_namespace
,
265 const std::string
&snap_name
)
266 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
269 using SnapEventBase::encode
;
270 using SnapEventBase::decode
;
271 using SnapEventBase::dump
;
274 struct RenameEvent
: public OpEventBase
{
275 static const EventType TYPE
= EVENT_TYPE_RENAME
;
277 std::string image_name
;
281 RenameEvent(uint64_t op_tid
, const std::string
&_image_name
)
282 : OpEventBase(op_tid
), image_name(_image_name
) {
285 void encode(bufferlist
& bl
) const;
286 void decode(__u8 version
, bufferlist::iterator
& it
);
287 void dump(Formatter
*f
) const;
290 struct ResizeEvent
: public OpEventBase
{
291 static const EventType TYPE
= EVENT_TYPE_RESIZE
;
295 ResizeEvent() : size(0) {
297 ResizeEvent(uint64_t op_tid
, uint64_t _size
)
298 : OpEventBase(op_tid
), size(_size
) {
301 void encode(bufferlist
& bl
) const;
302 void decode(__u8 version
, bufferlist::iterator
& it
);
303 void dump(Formatter
*f
) const;
306 struct FlattenEvent
: public OpEventBase
{
307 static const EventType TYPE
= EVENT_TYPE_FLATTEN
;
311 FlattenEvent(uint64_t op_tid
) : OpEventBase(op_tid
) {
314 using OpEventBase::encode
;
315 using OpEventBase::decode
;
316 using OpEventBase::dump
;
319 struct DemotePromoteEvent
{
320 static const EventType TYPE
= static_cast<EventType
>(
321 EVENT_TYPE_DEMOTE_PROMOTE
);
323 void encode(bufferlist
& bl
) const;
324 void decode(__u8 version
, bufferlist::iterator
& it
);
325 void dump(Formatter
*f
) const;
328 struct UpdateFeaturesEvent
: public OpEventBase
{
329 static const EventType TYPE
= EVENT_TYPE_UPDATE_FEATURES
;
334 UpdateFeaturesEvent() : features(0), enabled(false) {
336 UpdateFeaturesEvent(uint64_t op_tid
, uint64_t _features
, bool _enabled
)
337 : OpEventBase(op_tid
), features(_features
), enabled(_enabled
) {
340 void encode(bufferlist
& bl
) const;
341 void decode(__u8 version
, bufferlist::iterator
& it
);
342 void dump(Formatter
*f
) const;
345 struct MetadataSetEvent
: public OpEventBase
{
346 static const EventType TYPE
= EVENT_TYPE_METADATA_SET
;
353 MetadataSetEvent(uint64_t op_tid
, const string
&_key
, const string
&_value
)
354 : OpEventBase(op_tid
), key(_key
), value(_value
) {
357 void encode(bufferlist
& bl
) const;
358 void decode(__u8 version
, bufferlist::iterator
& it
);
359 void dump(Formatter
*f
) const;
362 struct MetadataRemoveEvent
: public OpEventBase
{
363 static const EventType TYPE
= EVENT_TYPE_METADATA_REMOVE
;
367 MetadataRemoveEvent() {
369 MetadataRemoveEvent(uint64_t op_tid
, const string
&_key
)
370 : OpEventBase(op_tid
), key(_key
) {
373 void encode(bufferlist
& bl
) const;
374 void decode(__u8 version
, bufferlist::iterator
& it
);
375 void dump(Formatter
*f
) const;
378 struct UnknownEvent
{
379 static const EventType TYPE
= static_cast<EventType
>(-1);
381 void encode(bufferlist
& bl
) const;
382 void decode(__u8 version
, bufferlist::iterator
& it
);
383 void dump(Formatter
*f
) const;
386 typedef boost::variant
<AioDiscardEvent
,
408 static uint32_t get_fixed_size() {
409 return EVENT_FIXED_SIZE
+ METADATA_FIXED_SIZE
;
412 EventEntry() : event(UnknownEvent()) {
414 EventEntry(const Event
&_event
, const utime_t
&_timestamp
= utime_t())
415 : event(_event
), timestamp(_timestamp
) {
421 EventType
get_event_type() const;
423 void encode(bufferlist
& bl
) const;
424 void decode(bufferlist::iterator
& it
);
425 void dump(Formatter
*f
) const;
427 static void generate_test_instances(std::list
<EventEntry
*> &o
);
430 static const uint32_t EVENT_FIXED_SIZE
= 14; /// version encoding, type
431 static const uint32_t METADATA_FIXED_SIZE
= 14; /// version encoding, timestamp
433 void encode_metadata(bufferlist
& bl
) const;
434 void decode_metadata(bufferlist::iterator
& it
);
437 // Journal Client data structures
439 enum ClientMetaType
{
440 IMAGE_CLIENT_META_TYPE
= 0,
441 MIRROR_PEER_CLIENT_META_TYPE
= 1,
442 CLI_CLIENT_META_TYPE
= 2
445 struct ImageClientMeta
{
446 static const ClientMetaType TYPE
= IMAGE_CLIENT_META_TYPE
;
448 uint64_t tag_class
= 0;
449 bool resync_requested
= false;
453 ImageClientMeta(uint64_t tag_class
) : tag_class(tag_class
) {
456 void encode(bufferlist
& bl
) const;
457 void decode(__u8 version
, bufferlist::iterator
& it
);
458 void dump(Formatter
*f
) const;
461 struct MirrorPeerSyncPoint
{
462 typedef boost::optional
<uint64_t> ObjectNumber
;
464 cls::rbd::SnapshotNamespace snap_namespace
;
465 std::string snap_name
;
466 std::string from_snap_name
;
467 ObjectNumber object_number
;
469 MirrorPeerSyncPoint() : MirrorPeerSyncPoint({}, "", "", boost::none
) {
471 MirrorPeerSyncPoint(const cls::rbd::SnapshotNamespace
& snap_namespace
,
472 const std::string
&snap_name
,
473 const ObjectNumber
&object_number
)
474 : MirrorPeerSyncPoint(snap_namespace
, snap_name
, "", object_number
) {
476 MirrorPeerSyncPoint(const cls::rbd::SnapshotNamespace
& snap_namespace
,
477 const std::string
&snap_name
,
478 const std::string
&from_snap_name
,
479 const ObjectNumber
&object_number
)
480 : snap_namespace(snap_namespace
), snap_name(snap_name
),
481 from_snap_name(from_snap_name
), object_number(object_number
) {
484 inline bool operator==(const MirrorPeerSyncPoint
&sync
) const {
485 return (snap_name
== sync
.snap_name
&&
486 from_snap_name
== sync
.from_snap_name
&&
487 object_number
== sync
.object_number
&&
488 snap_namespace
== sync
.snap_namespace
);
491 void encode(bufferlist
& bl
) const;
492 void decode(__u8 version
, bufferlist::iterator
& it
);
493 void dump(Formatter
*f
) const;
496 enum MirrorPeerState
{
497 MIRROR_PEER_STATE_SYNCING
,
498 MIRROR_PEER_STATE_REPLAYING
501 struct MirrorPeerClientMeta
{
502 typedef std::list
<MirrorPeerSyncPoint
> SyncPoints
;
503 typedef std::map
<uint64_t, uint64_t> SnapSeqs
;
505 static const ClientMetaType TYPE
= MIRROR_PEER_CLIENT_META_TYPE
;
507 std::string image_id
;
508 MirrorPeerState state
= MIRROR_PEER_STATE_SYNCING
; ///< replay state
509 uint64_t sync_object_count
= 0; ///< maximum number of objects ever sync'ed
510 SyncPoints sync_points
; ///< max two in-use snapshots for sync
511 SnapSeqs snap_seqs
; ///< local to peer snap seq mapping
513 MirrorPeerClientMeta() {
515 MirrorPeerClientMeta(const std::string
&image_id
,
516 const SyncPoints
&sync_points
= SyncPoints(),
517 const SnapSeqs
&snap_seqs
= SnapSeqs())
518 : image_id(image_id
), sync_points(sync_points
), snap_seqs(snap_seqs
) {
521 inline bool operator==(const MirrorPeerClientMeta
&meta
) const {
522 return (image_id
== meta
.image_id
&&
523 state
== meta
.state
&&
524 sync_object_count
== meta
.sync_object_count
&&
525 sync_points
== meta
.sync_points
&&
526 snap_seqs
== meta
.snap_seqs
);
529 void encode(bufferlist
& bl
) const;
530 void decode(__u8 version
, bufferlist::iterator
& it
);
531 void dump(Formatter
*f
) const;
534 struct CliClientMeta
{
535 static const ClientMetaType TYPE
= CLI_CLIENT_META_TYPE
;
537 void encode(bufferlist
& bl
) const;
538 void decode(__u8 version
, bufferlist::iterator
& it
);
539 void dump(Formatter
*f
) const;
542 struct UnknownClientMeta
{
543 static const ClientMetaType TYPE
= static_cast<ClientMetaType
>(-1);
545 void encode(bufferlist
& bl
) const;
546 void decode(__u8 version
, bufferlist::iterator
& it
);
547 void dump(Formatter
*f
) const;
550 typedef boost::variant
<ImageClientMeta
,
551 MirrorPeerClientMeta
,
553 UnknownClientMeta
> ClientMeta
;
558 ClientData(const ClientMeta
&client_meta
) : client_meta(client_meta
) {
561 ClientMeta client_meta
;
563 ClientMetaType
get_client_meta_type() const;
565 void encode(bufferlist
& bl
) const;
566 void decode(bufferlist::iterator
& it
);
567 void dump(Formatter
*f
) const;
569 static void generate_test_instances(std::list
<ClientData
*> &o
);
572 // Journal Tag data structures
574 struct TagPredecessor
{
575 std::string mirror_uuid
; // empty if local
576 bool commit_valid
= false;
577 uint64_t tag_tid
= 0;
578 uint64_t entry_tid
= 0;
582 TagPredecessor(const std::string
&mirror_uuid
, bool commit_valid
,
583 uint64_t tag_tid
, uint64_t entry_tid
)
584 : mirror_uuid(mirror_uuid
), commit_valid(commit_valid
), tag_tid(tag_tid
),
585 entry_tid(entry_tid
) {
588 inline bool operator==(const TagPredecessor
&rhs
) const {
589 return (mirror_uuid
== rhs
.mirror_uuid
&&
590 commit_valid
== rhs
.commit_valid
&&
591 tag_tid
== rhs
.tag_tid
&&
592 entry_tid
== rhs
.entry_tid
);
595 void encode(bufferlist
& bl
) const;
596 void decode(bufferlist::iterator
& it
);
597 void dump(Formatter
*f
) const;
601 // owner of the tag (exclusive lock epoch)
602 std::string mirror_uuid
; // empty if local
604 // mapping to last committed record of previous tag
605 TagPredecessor predecessor
;
609 TagData(const std::string
&mirror_uuid
) : mirror_uuid(mirror_uuid
) {
611 TagData(const std::string
&mirror_uuid
,
612 const std::string
&predecessor_mirror_uuid
,
613 bool predecessor_commit_valid
,
614 uint64_t predecessor_tag_tid
, uint64_t predecessor_entry_tid
)
615 : mirror_uuid(mirror_uuid
),
616 predecessor(predecessor_mirror_uuid
, predecessor_commit_valid
,
617 predecessor_tag_tid
, predecessor_entry_tid
) {
620 void encode(bufferlist
& bl
) const;
621 void decode(bufferlist::iterator
& it
);
622 void dump(Formatter
*f
) const;
624 static void generate_test_instances(std::list
<TagData
*> &o
);
627 std::ostream
&operator<<(std::ostream
&out
, const EventType
&type
);
628 std::ostream
&operator<<(std::ostream
&out
, const ClientMetaType
&type
);
629 std::ostream
&operator<<(std::ostream
&out
, const ImageClientMeta
&meta
);
630 std::ostream
&operator<<(std::ostream
&out
, const MirrorPeerSyncPoint
&sync
);
631 std::ostream
&operator<<(std::ostream
&out
, const MirrorPeerState
&meta
);
632 std::ostream
&operator<<(std::ostream
&out
, const MirrorPeerClientMeta
&meta
);
633 std::ostream
&operator<<(std::ostream
&out
, const TagPredecessor
&predecessor
);
634 std::ostream
&operator<<(std::ostream
&out
, const TagData
&tag_data
);
637 virtual ~Listener() {
640 /// invoked when journal close is requested
641 virtual void handle_close() = 0;
643 /// invoked when journal is promoted to primary
644 virtual void handle_promoted() = 0;
646 /// invoked when journal resync is requested
647 virtual void handle_resync() = 0;
650 } // namespace journal
651 } // namespace librbd
653 WRITE_CLASS_ENCODER(librbd::journal::EventEntry
);
654 WRITE_CLASS_ENCODER(librbd::journal::ClientData
);
655 WRITE_CLASS_ENCODER(librbd::journal::TagData
);
657 #endif // CEPH_LIBRBD_JOURNAL_TYPES_H