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