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>
18 #include <boost/mpl/vector.hpp>
28 EVENT_TYPE_AIO_DISCARD
= 0,
29 EVENT_TYPE_AIO_WRITE
= 1,
30 EVENT_TYPE_AIO_FLUSH
= 2,
31 EVENT_TYPE_OP_FINISH
= 3,
32 EVENT_TYPE_SNAP_CREATE
= 4,
33 EVENT_TYPE_SNAP_REMOVE
= 5,
34 EVENT_TYPE_SNAP_RENAME
= 6,
35 EVENT_TYPE_SNAP_PROTECT
= 7,
36 EVENT_TYPE_SNAP_UNPROTECT
= 8,
37 EVENT_TYPE_SNAP_ROLLBACK
= 9,
38 EVENT_TYPE_RENAME
= 10,
39 EVENT_TYPE_RESIZE
= 11,
40 EVENT_TYPE_FLATTEN
= 12,
41 EVENT_TYPE_DEMOTE_PROMOTE
= 13,
42 EVENT_TYPE_SNAP_LIMIT
= 14,
43 EVENT_TYPE_UPDATE_FEATURES
= 15,
44 EVENT_TYPE_METADATA_SET
= 16,
45 EVENT_TYPE_METADATA_REMOVE
= 17,
46 EVENT_TYPE_AIO_WRITESAME
= 18,
47 EVENT_TYPE_AIO_COMPARE_AND_WRITE
= 19,
50 struct AioDiscardEvent
{
51 static const EventType TYPE
= EVENT_TYPE_AIO_DISCARD
;
55 bool skip_partial_discard
;
57 AioDiscardEvent() : offset(0), length(0), skip_partial_discard(false) {
59 AioDiscardEvent(uint64_t _offset
, uint64_t _length
, bool _skip_partial_discard
)
60 : offset(_offset
), length(_length
), skip_partial_discard(_skip_partial_discard
) {
63 void encode(bufferlist
& bl
) const;
64 void decode(__u8 version
, bufferlist::iterator
& it
);
65 void dump(Formatter
*f
) const;
68 struct AioWriteEvent
{
69 static const EventType TYPE
= EVENT_TYPE_AIO_WRITE
;
75 static uint32_t get_fixed_size();
77 AioWriteEvent() : offset(0), length(0) {
79 AioWriteEvent(uint64_t _offset
, uint64_t _length
, const bufferlist
&_data
)
80 : offset(_offset
), length(_length
), data(_data
) {
83 void encode(bufferlist
& bl
) const;
84 void decode(__u8 version
, bufferlist::iterator
& it
);
85 void dump(Formatter
*f
) const;
88 struct AioWriteSameEvent
{
89 static const EventType TYPE
= EVENT_TYPE_AIO_WRITESAME
;
95 AioWriteSameEvent() : offset(0), length(0) {
97 AioWriteSameEvent(uint64_t _offset
, uint64_t _length
,
98 const bufferlist
&_data
)
99 : offset(_offset
), length(_length
), data(_data
) {
102 void encode(bufferlist
& bl
) const;
103 void decode(__u8 version
, bufferlist::iterator
& it
);
104 void dump(Formatter
*f
) const;
107 struct AioCompareAndWriteEvent
{
108 static const EventType TYPE
= EVENT_TYPE_AIO_COMPARE_AND_WRITE
;
113 bufferlist write_data
;
115 static uint32_t get_fixed_size();
117 AioCompareAndWriteEvent() : offset(0), length(0) {
119 AioCompareAndWriteEvent(uint64_t _offset
, uint64_t _length
,
120 const bufferlist
&_cmp_data
, const bufferlist
&_write_data
)
121 : offset(_offset
), length(_length
), cmp_data(_cmp_data
), write_data(_write_data
) {
124 void encode(bufferlist
& bl
) const;
125 void decode(__u8 version
, bufferlist::iterator
& it
);
126 void dump(Formatter
*f
) const;
129 struct AioFlushEvent
{
130 static const EventType TYPE
= EVENT_TYPE_AIO_FLUSH
;
132 void encode(bufferlist
& bl
) const;
133 void decode(__u8 version
, bufferlist::iterator
& it
);
134 void dump(Formatter
*f
) const;
141 OpEventBase() : op_tid(0) {
143 OpEventBase(uint64_t op_tid
) : op_tid(op_tid
) {
146 void encode(bufferlist
& bl
) const;
147 void decode(__u8 version
, bufferlist::iterator
& it
);
148 void dump(Formatter
*f
) const;
151 struct OpFinishEvent
: public OpEventBase
{
152 static const EventType TYPE
= EVENT_TYPE_OP_FINISH
;
156 OpFinishEvent() : r(0) {
158 OpFinishEvent(uint64_t op_tid
, int r
) : OpEventBase(op_tid
), r(r
) {
161 void encode(bufferlist
& bl
) const;
162 void decode(__u8 version
, bufferlist::iterator
& it
);
163 void dump(Formatter
*f
) const;
166 struct SnapEventBase
: public OpEventBase
{
167 cls::rbd::SnapshotNamespace snap_namespace
;
168 std::string snap_name
;
173 SnapEventBase(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& _snap_namespace
,
174 const std::string
&_snap_name
)
175 : OpEventBase(op_tid
),
176 snap_namespace(_snap_namespace
),
177 snap_name(_snap_name
) {
180 void encode(bufferlist
& bl
) const;
181 void decode(__u8 version
, bufferlist::iterator
& it
);
182 void dump(Formatter
*f
) const;
185 struct SnapCreateEvent
: public SnapEventBase
{
186 static const EventType TYPE
= EVENT_TYPE_SNAP_CREATE
;
190 SnapCreateEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& snap_namespace
,
191 const std::string
&snap_name
)
192 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
195 void encode(bufferlist
& bl
) const;
196 void decode(__u8 version
, bufferlist::iterator
& it
);
197 void dump(Formatter
*f
) const;
200 struct SnapRemoveEvent
: public SnapEventBase
{
201 static const EventType TYPE
= EVENT_TYPE_SNAP_REMOVE
;
205 SnapRemoveEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& snap_namespace
,
206 const std::string
&snap_name
)
207 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
210 using SnapEventBase::encode
;
211 using SnapEventBase::decode
;
212 using SnapEventBase::dump
;
215 struct SnapRenameEvent
: public OpEventBase
{
216 static const EventType TYPE
= EVENT_TYPE_SNAP_RENAME
;
219 std::string src_snap_name
;
220 std::string dst_snap_name
;
222 SnapRenameEvent() : snap_id(CEPH_NOSNAP
) {
224 SnapRenameEvent(uint64_t op_tid
, uint64_t src_snap_id
,
225 const std::string
&src_snap_name
,
226 const std::string
&dest_snap_name
)
227 : OpEventBase(op_tid
),
228 snap_id(src_snap_id
),
229 src_snap_name(src_snap_name
),
230 dst_snap_name(dest_snap_name
) {
233 void encode(bufferlist
& bl
) const;
234 void decode(__u8 version
, bufferlist::iterator
& it
);
235 void dump(Formatter
*f
) const;
238 struct SnapProtectEvent
: public SnapEventBase
{
239 static const EventType TYPE
= EVENT_TYPE_SNAP_PROTECT
;
243 SnapProtectEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& snap_namespace
,
244 const std::string
&snap_name
)
245 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
248 using SnapEventBase::encode
;
249 using SnapEventBase::decode
;
250 using SnapEventBase::dump
;
253 struct SnapUnprotectEvent
: public SnapEventBase
{
254 static const EventType TYPE
= EVENT_TYPE_SNAP_UNPROTECT
;
256 SnapUnprotectEvent() {
258 SnapUnprotectEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
&snap_namespace
,
259 const std::string
&snap_name
)
260 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
263 using SnapEventBase::encode
;
264 using SnapEventBase::decode
;
265 using SnapEventBase::dump
;
268 struct SnapLimitEvent
: public OpEventBase
{
269 static const EventType TYPE
= EVENT_TYPE_SNAP_LIMIT
;
274 SnapLimitEvent(uint64_t op_tid
, const uint64_t _limit
)
275 : OpEventBase(op_tid
), limit(_limit
) {
278 void encode(bufferlist
& bl
) const;
279 void decode(__u8 version
, bufferlist::iterator
& it
);
280 void dump(Formatter
*f
) const;
283 struct SnapRollbackEvent
: public SnapEventBase
{
284 static const EventType TYPE
= EVENT_TYPE_SNAP_ROLLBACK
;
286 SnapRollbackEvent() {
288 SnapRollbackEvent(uint64_t op_tid
, const cls::rbd::SnapshotNamespace
& snap_namespace
,
289 const std::string
&snap_name
)
290 : SnapEventBase(op_tid
, snap_namespace
, snap_name
) {
293 using SnapEventBase::encode
;
294 using SnapEventBase::decode
;
295 using SnapEventBase::dump
;
298 struct RenameEvent
: public OpEventBase
{
299 static const EventType TYPE
= EVENT_TYPE_RENAME
;
301 std::string image_name
;
305 RenameEvent(uint64_t op_tid
, const std::string
&_image_name
)
306 : OpEventBase(op_tid
), image_name(_image_name
) {
309 void encode(bufferlist
& bl
) const;
310 void decode(__u8 version
, bufferlist::iterator
& it
);
311 void dump(Formatter
*f
) const;
314 struct ResizeEvent
: public OpEventBase
{
315 static const EventType TYPE
= EVENT_TYPE_RESIZE
;
319 ResizeEvent() : size(0) {
321 ResizeEvent(uint64_t op_tid
, uint64_t _size
)
322 : OpEventBase(op_tid
), size(_size
) {
325 void encode(bufferlist
& bl
) const;
326 void decode(__u8 version
, bufferlist::iterator
& it
);
327 void dump(Formatter
*f
) const;
330 struct FlattenEvent
: public OpEventBase
{
331 static const EventType TYPE
= EVENT_TYPE_FLATTEN
;
335 FlattenEvent(uint64_t op_tid
) : OpEventBase(op_tid
) {
338 using OpEventBase::encode
;
339 using OpEventBase::decode
;
340 using OpEventBase::dump
;
343 struct DemotePromoteEvent
{
344 static const EventType TYPE
= static_cast<EventType
>(
345 EVENT_TYPE_DEMOTE_PROMOTE
);
347 void encode(bufferlist
& bl
) const;
348 void decode(__u8 version
, bufferlist::iterator
& it
);
349 void dump(Formatter
*f
) const;
352 struct UpdateFeaturesEvent
: public OpEventBase
{
353 static const EventType TYPE
= EVENT_TYPE_UPDATE_FEATURES
;
358 UpdateFeaturesEvent() : features(0), enabled(false) {
360 UpdateFeaturesEvent(uint64_t op_tid
, uint64_t _features
, bool _enabled
)
361 : OpEventBase(op_tid
), features(_features
), enabled(_enabled
) {
364 void encode(bufferlist
& bl
) const;
365 void decode(__u8 version
, bufferlist::iterator
& it
);
366 void dump(Formatter
*f
) const;
369 struct MetadataSetEvent
: public OpEventBase
{
370 static const EventType TYPE
= EVENT_TYPE_METADATA_SET
;
377 MetadataSetEvent(uint64_t op_tid
, const string
&_key
, const string
&_value
)
378 : OpEventBase(op_tid
), key(_key
), value(_value
) {
381 void encode(bufferlist
& bl
) const;
382 void decode(__u8 version
, bufferlist::iterator
& it
);
383 void dump(Formatter
*f
) const;
386 struct MetadataRemoveEvent
: public OpEventBase
{
387 static const EventType TYPE
= EVENT_TYPE_METADATA_REMOVE
;
391 MetadataRemoveEvent() {
393 MetadataRemoveEvent(uint64_t op_tid
, const string
&_key
)
394 : OpEventBase(op_tid
), key(_key
) {
397 void encode(bufferlist
& bl
) const;
398 void decode(__u8 version
, bufferlist::iterator
& it
);
399 void dump(Formatter
*f
) const;
402 struct UnknownEvent
{
403 static const EventType TYPE
= static_cast<EventType
>(-1);
405 void encode(bufferlist
& bl
) const;
406 void decode(__u8 version
, bufferlist::iterator
& it
);
407 void dump(Formatter
*f
) const;
410 typedef boost::mpl::vector
<AioDiscardEvent
,
429 AioCompareAndWriteEvent
,
430 UnknownEvent
> EventVector
;
431 typedef boost::make_variant_over
<EventVector
>::type Event
;
434 static uint32_t get_fixed_size() {
435 return EVENT_FIXED_SIZE
+ METADATA_FIXED_SIZE
;
438 EventEntry() : event(UnknownEvent()) {
440 EventEntry(const Event
&_event
, const utime_t
&_timestamp
= utime_t())
441 : event(_event
), timestamp(_timestamp
) {
447 EventType
get_event_type() const;
449 void encode(bufferlist
& bl
) const;
450 void decode(bufferlist::iterator
& it
);
451 void dump(Formatter
*f
) const;
453 static void generate_test_instances(std::list
<EventEntry
*> &o
);
456 static const uint32_t EVENT_FIXED_SIZE
= 14; /// version encoding, type
457 static const uint32_t METADATA_FIXED_SIZE
= 14; /// version encoding, timestamp
459 void encode_metadata(bufferlist
& bl
) const;
460 void decode_metadata(bufferlist::iterator
& it
);
463 // Journal Client data structures
465 enum ClientMetaType
{
466 IMAGE_CLIENT_META_TYPE
= 0,
467 MIRROR_PEER_CLIENT_META_TYPE
= 1,
468 CLI_CLIENT_META_TYPE
= 2
471 struct ImageClientMeta
{
472 static const ClientMetaType TYPE
= IMAGE_CLIENT_META_TYPE
;
474 uint64_t tag_class
= 0;
475 bool resync_requested
= false;
479 ImageClientMeta(uint64_t tag_class
) : tag_class(tag_class
) {
482 void encode(bufferlist
& bl
) const;
483 void decode(__u8 version
, bufferlist::iterator
& it
);
484 void dump(Formatter
*f
) const;
487 struct MirrorPeerSyncPoint
{
488 typedef boost::optional
<uint64_t> ObjectNumber
;
490 cls::rbd::SnapshotNamespace snap_namespace
;
491 std::string snap_name
;
492 std::string from_snap_name
;
493 ObjectNumber object_number
;
495 MirrorPeerSyncPoint() : MirrorPeerSyncPoint({}, "", "", boost::none
) {
497 MirrorPeerSyncPoint(const cls::rbd::SnapshotNamespace
& snap_namespace
,
498 const std::string
&snap_name
,
499 const ObjectNumber
&object_number
)
500 : MirrorPeerSyncPoint(snap_namespace
, snap_name
, "", object_number
) {
502 MirrorPeerSyncPoint(const cls::rbd::SnapshotNamespace
& snap_namespace
,
503 const std::string
&snap_name
,
504 const std::string
&from_snap_name
,
505 const ObjectNumber
&object_number
)
506 : snap_namespace(snap_namespace
), snap_name(snap_name
),
507 from_snap_name(from_snap_name
), object_number(object_number
) {
510 inline bool operator==(const MirrorPeerSyncPoint
&sync
) const {
511 return (snap_name
== sync
.snap_name
&&
512 from_snap_name
== sync
.from_snap_name
&&
513 object_number
== sync
.object_number
&&
514 snap_namespace
== sync
.snap_namespace
);
517 void encode(bufferlist
& bl
) const;
518 void decode(__u8 version
, bufferlist::iterator
& it
);
519 void dump(Formatter
*f
) const;
522 enum MirrorPeerState
{
523 MIRROR_PEER_STATE_SYNCING
,
524 MIRROR_PEER_STATE_REPLAYING
527 struct MirrorPeerClientMeta
{
528 typedef std::list
<MirrorPeerSyncPoint
> SyncPoints
;
529 typedef std::map
<uint64_t, uint64_t> SnapSeqs
;
531 static const ClientMetaType TYPE
= MIRROR_PEER_CLIENT_META_TYPE
;
533 std::string image_id
;
534 MirrorPeerState state
= MIRROR_PEER_STATE_SYNCING
; ///< replay state
535 uint64_t sync_object_count
= 0; ///< maximum number of objects ever sync'ed
536 SyncPoints sync_points
; ///< max two in-use snapshots for sync
537 SnapSeqs snap_seqs
; ///< local to peer snap seq mapping
539 MirrorPeerClientMeta() {
541 MirrorPeerClientMeta(const std::string
&image_id
,
542 const SyncPoints
&sync_points
= SyncPoints(),
543 const SnapSeqs
&snap_seqs
= SnapSeqs())
544 : image_id(image_id
), sync_points(sync_points
), snap_seqs(snap_seqs
) {
547 inline bool operator==(const MirrorPeerClientMeta
&meta
) const {
548 return (image_id
== meta
.image_id
&&
549 state
== meta
.state
&&
550 sync_object_count
== meta
.sync_object_count
&&
551 sync_points
== meta
.sync_points
&&
552 snap_seqs
== meta
.snap_seqs
);
555 void encode(bufferlist
& bl
) const;
556 void decode(__u8 version
, bufferlist::iterator
& it
);
557 void dump(Formatter
*f
) const;
560 struct CliClientMeta
{
561 static const ClientMetaType TYPE
= CLI_CLIENT_META_TYPE
;
563 void encode(bufferlist
& bl
) const;
564 void decode(__u8 version
, bufferlist::iterator
& it
);
565 void dump(Formatter
*f
) const;
568 struct UnknownClientMeta
{
569 static const ClientMetaType TYPE
= static_cast<ClientMetaType
>(-1);
571 void encode(bufferlist
& bl
) const;
572 void decode(__u8 version
, bufferlist::iterator
& it
);
573 void dump(Formatter
*f
) const;
576 typedef boost::variant
<ImageClientMeta
,
577 MirrorPeerClientMeta
,
579 UnknownClientMeta
> ClientMeta
;
584 ClientData(const ClientMeta
&client_meta
) : client_meta(client_meta
) {
587 ClientMeta client_meta
;
589 ClientMetaType
get_client_meta_type() const;
591 void encode(bufferlist
& bl
) const;
592 void decode(bufferlist::iterator
& it
);
593 void dump(Formatter
*f
) const;
595 static void generate_test_instances(std::list
<ClientData
*> &o
);
598 // Journal Tag data structures
600 struct TagPredecessor
{
601 std::string mirror_uuid
; // empty if local
602 bool commit_valid
= false;
603 uint64_t tag_tid
= 0;
604 uint64_t entry_tid
= 0;
608 TagPredecessor(const std::string
&mirror_uuid
, bool commit_valid
,
609 uint64_t tag_tid
, uint64_t entry_tid
)
610 : mirror_uuid(mirror_uuid
), commit_valid(commit_valid
), tag_tid(tag_tid
),
611 entry_tid(entry_tid
) {
614 inline bool operator==(const TagPredecessor
&rhs
) const {
615 return (mirror_uuid
== rhs
.mirror_uuid
&&
616 commit_valid
== rhs
.commit_valid
&&
617 tag_tid
== rhs
.tag_tid
&&
618 entry_tid
== rhs
.entry_tid
);
621 void encode(bufferlist
& bl
) const;
622 void decode(bufferlist::iterator
& it
);
623 void dump(Formatter
*f
) const;
627 // owner of the tag (exclusive lock epoch)
628 std::string mirror_uuid
; // empty if local
630 // mapping to last committed record of previous tag
631 TagPredecessor predecessor
;
635 TagData(const std::string
&mirror_uuid
) : mirror_uuid(mirror_uuid
) {
637 TagData(const std::string
&mirror_uuid
,
638 const std::string
&predecessor_mirror_uuid
,
639 bool predecessor_commit_valid
,
640 uint64_t predecessor_tag_tid
, uint64_t predecessor_entry_tid
)
641 : mirror_uuid(mirror_uuid
),
642 predecessor(predecessor_mirror_uuid
, predecessor_commit_valid
,
643 predecessor_tag_tid
, predecessor_entry_tid
) {
646 void encode(bufferlist
& bl
) const;
647 void decode(bufferlist::iterator
& it
);
648 void dump(Formatter
*f
) const;
650 static void generate_test_instances(std::list
<TagData
*> &o
);
653 std::ostream
&operator<<(std::ostream
&out
, const EventType
&type
);
654 std::ostream
&operator<<(std::ostream
&out
, const ClientMetaType
&type
);
655 std::ostream
&operator<<(std::ostream
&out
, const ImageClientMeta
&meta
);
656 std::ostream
&operator<<(std::ostream
&out
, const MirrorPeerSyncPoint
&sync
);
657 std::ostream
&operator<<(std::ostream
&out
, const MirrorPeerState
&meta
);
658 std::ostream
&operator<<(std::ostream
&out
, const MirrorPeerClientMeta
&meta
);
659 std::ostream
&operator<<(std::ostream
&out
, const TagPredecessor
&predecessor
);
660 std::ostream
&operator<<(std::ostream
&out
, const TagData
&tag_data
);
663 virtual ~Listener() {
666 /// invoked when journal close is requested
667 virtual void handle_close() = 0;
669 /// invoked when journal is promoted to primary
670 virtual void handle_promoted() = 0;
672 /// invoked when journal resync is requested
673 virtual void handle_resync() = 0;
676 } // namespace journal
677 } // namespace librbd
679 WRITE_CLASS_ENCODER(librbd::journal::EventEntry
);
680 WRITE_CLASS_ENCODER(librbd::journal::ClientData
);
681 WRITE_CLASS_ENCODER(librbd::journal::TagData
);
683 #endif // CEPH_LIBRBD_JOURNAL_TYPES_H