// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab #ifndef LIBRBD_WATCH_NOTIFY_TYPES_H #define LIBRBD_WATCH_NOTIFY_TYPES_H #include "cls/rbd/cls_rbd_types.h" #include "include/int_types.h" #include "include/buffer_fwd.h" #include "include/encoding.h" #include "librbd/watcher/Types.h" #include #include #include #include namespace ceph { class Formatter; } namespace librbd { namespace watch_notify { using librbd::watcher::ClientId; WRITE_CLASS_ENCODER(ClientId); struct AsyncRequestId { ClientId client_id; uint64_t request_id; AsyncRequestId() : request_id() {} AsyncRequestId(const ClientId &client_id_, uint64_t request_id_) : client_id(client_id_), request_id(request_id_) {} void encode(bufferlist& bl) const; void decode(bufferlist::iterator& it); void dump(Formatter *f) const; inline bool operator<(const AsyncRequestId &rhs) const { if (client_id != rhs.client_id) { return client_id < rhs.client_id; } else { return request_id < rhs.request_id; } } inline bool operator!=(const AsyncRequestId &rhs) const { return (client_id != rhs.client_id || request_id != rhs.request_id); } }; enum NotifyOp { NOTIFY_OP_ACQUIRED_LOCK = 0, NOTIFY_OP_RELEASED_LOCK = 1, NOTIFY_OP_REQUEST_LOCK = 2, NOTIFY_OP_HEADER_UPDATE = 3, NOTIFY_OP_ASYNC_PROGRESS = 4, NOTIFY_OP_ASYNC_COMPLETE = 5, NOTIFY_OP_FLATTEN = 6, NOTIFY_OP_RESIZE = 7, NOTIFY_OP_SNAP_CREATE = 8, NOTIFY_OP_SNAP_REMOVE = 9, NOTIFY_OP_REBUILD_OBJECT_MAP = 10, NOTIFY_OP_SNAP_RENAME = 11, NOTIFY_OP_SNAP_PROTECT = 12, NOTIFY_OP_SNAP_UNPROTECT = 13, NOTIFY_OP_RENAME = 14, NOTIFY_OP_UPDATE_FEATURES = 15, }; struct AcquiredLockPayload { static const NotifyOp NOTIFY_OP = NOTIFY_OP_ACQUIRED_LOCK; static const bool CHECK_FOR_REFRESH = false; ClientId client_id; AcquiredLockPayload() {} AcquiredLockPayload(const ClientId &client_id_) : client_id(client_id_) {} void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; }; struct ReleasedLockPayload { static const NotifyOp NOTIFY_OP = NOTIFY_OP_RELEASED_LOCK; static const bool CHECK_FOR_REFRESH = false; ClientId client_id; ReleasedLockPayload() {} ReleasedLockPayload(const ClientId &client_id_) : client_id(client_id_) {} void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; }; struct RequestLockPayload { static const NotifyOp NOTIFY_OP = NOTIFY_OP_REQUEST_LOCK; static const bool CHECK_FOR_REFRESH = false; ClientId client_id; bool force = false; RequestLockPayload() {} RequestLockPayload(const ClientId &client_id_, bool force_) : client_id(client_id_), force(force_) { } void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; }; struct HeaderUpdatePayload { static const NotifyOp NOTIFY_OP = NOTIFY_OP_HEADER_UPDATE; static const bool CHECK_FOR_REFRESH = false; void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; }; struct AsyncRequestPayloadBase { public: AsyncRequestId async_request_id; void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; protected: AsyncRequestPayloadBase() {} AsyncRequestPayloadBase(const AsyncRequestId &id) : async_request_id(id) {} }; struct AsyncProgressPayload : public AsyncRequestPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_ASYNC_PROGRESS; static const bool CHECK_FOR_REFRESH = false; AsyncProgressPayload() : offset(0), total(0) {} AsyncProgressPayload(const AsyncRequestId &id, uint64_t offset_, uint64_t total_) : AsyncRequestPayloadBase(id), offset(offset_), total(total_) {} uint64_t offset; uint64_t total; void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; }; struct AsyncCompletePayload : public AsyncRequestPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_ASYNC_COMPLETE; static const bool CHECK_FOR_REFRESH = false; AsyncCompletePayload() : result(0) {} AsyncCompletePayload(const AsyncRequestId &id, int r) : AsyncRequestPayloadBase(id), result(r) {} int result; void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; }; struct FlattenPayload : public AsyncRequestPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_FLATTEN; static const bool CHECK_FOR_REFRESH = true; FlattenPayload() {} FlattenPayload(const AsyncRequestId &id) : AsyncRequestPayloadBase(id) {} }; struct ResizePayload : public AsyncRequestPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_RESIZE; static const bool CHECK_FOR_REFRESH = true; ResizePayload() : size(0), allow_shrink(true) {} ResizePayload(uint64_t size_, bool allow_shrink_, const AsyncRequestId &id) : AsyncRequestPayloadBase(id), size(size_), allow_shrink(allow_shrink_) {} uint64_t size; bool allow_shrink; void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; }; struct SnapPayloadBase { public: static const bool CHECK_FOR_REFRESH = true; cls::rbd::SnapshotNamespace snap_namespace; std::string snap_name; void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; protected: SnapPayloadBase() {} SnapPayloadBase(const cls::rbd::SnapshotNamespace& _snap_namespace, const std::string &name) : snap_namespace(_snap_namespace), snap_name(name) {} }; struct SnapCreatePayload : public SnapPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_SNAP_CREATE; SnapCreatePayload() {} SnapCreatePayload(const cls::rbd::SnapshotNamespace &_snap_namespace, const std::string &name) : SnapPayloadBase(_snap_namespace, name) {} void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; }; struct SnapRenamePayload : public SnapPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_SNAP_RENAME; SnapRenamePayload() {} SnapRenamePayload(const uint64_t &src_snap_id, const std::string &dst_name) : SnapPayloadBase(cls::rbd::UserSnapshotNamespace(), dst_name), snap_id(src_snap_id) {} uint64_t snap_id; void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; }; struct SnapRemovePayload : public SnapPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_SNAP_REMOVE; SnapRemovePayload() {} SnapRemovePayload(const cls::rbd::SnapshotNamespace& snap_namespace, const std::string &name) : SnapPayloadBase(snap_namespace, name) {} }; struct SnapProtectPayload : public SnapPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_SNAP_PROTECT; SnapProtectPayload() {} SnapProtectPayload(const cls::rbd::SnapshotNamespace& snap_namespace, const std::string &name) : SnapPayloadBase(snap_namespace, name) {} }; struct SnapUnprotectPayload : public SnapPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_SNAP_UNPROTECT; SnapUnprotectPayload() {} SnapUnprotectPayload(const cls::rbd::SnapshotNamespace& snap_namespace, const std::string &name) : SnapPayloadBase(snap_namespace, name) {} }; struct RebuildObjectMapPayload : public AsyncRequestPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_REBUILD_OBJECT_MAP; static const bool CHECK_FOR_REFRESH = true; RebuildObjectMapPayload() {} RebuildObjectMapPayload(const AsyncRequestId &id) : AsyncRequestPayloadBase(id) {} }; struct RenamePayload { static const NotifyOp NOTIFY_OP = NOTIFY_OP_RENAME; static const bool CHECK_FOR_REFRESH = true; RenamePayload() {} RenamePayload(const std::string _image_name) : image_name(_image_name) {} std::string image_name; void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; }; struct UpdateFeaturesPayload { static const NotifyOp NOTIFY_OP = NOTIFY_OP_UPDATE_FEATURES; static const bool CHECK_FOR_REFRESH = true; UpdateFeaturesPayload() : features(0), enabled(false) {} UpdateFeaturesPayload(uint64_t features_, bool enabled_) : features(features_), enabled(enabled_) {} uint64_t features; bool enabled; void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; }; struct UnknownPayload { static const NotifyOp NOTIFY_OP = static_cast(-1); static const bool CHECK_FOR_REFRESH = false; void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; }; typedef boost::variant Payload; struct NotifyMessage { NotifyMessage() : payload(UnknownPayload()) {} NotifyMessage(const Payload &payload_) : payload(payload_) {} Payload payload; bool check_for_refresh() const; void encode(bufferlist& bl) const; void decode(bufferlist::iterator& it); void dump(Formatter *f) const; static void generate_test_instances(std::list &o); }; struct ResponseMessage { ResponseMessage() : result(0) {} ResponseMessage(int result_) : result(result_) {} int result; void encode(bufferlist& bl) const; void decode(bufferlist::iterator& it); void dump(Formatter *f) const; static void generate_test_instances(std::list &o); }; } // namespace watch_notify } // namespace librbd std::ostream &operator<<(std::ostream &out, const librbd::watch_notify::NotifyOp &op); std::ostream &operator<<(std::ostream &out, const librbd::watch_notify::AsyncRequestId &request); WRITE_CLASS_ENCODER(librbd::watch_notify::AsyncRequestId); WRITE_CLASS_ENCODER(librbd::watch_notify::NotifyMessage); WRITE_CLASS_ENCODER(librbd::watch_notify::ResponseMessage); #endif // LIBRBD_WATCH_NOTIFY_TYPES_H