From: Jason Dillaman Date: Thu, 30 Jul 2015 18:08:00 +0000 (-0400) Subject: librbd: new watch/notify types for snap protect/unprotect and rename X-Git-Tag: v10.0.2~193^2~20 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=01abb20f7a67c2224cb3b216ee4770e56481dcd3;p=ceph.git librbd: new watch/notify types for snap protect/unprotect and rename When journaling is enabled, these actions will need to be executed via the lock owner to ensure that they are journaled for RBD mirroring. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/ImageWatcher.cc b/src/librbd/ImageWatcher.cc index 0065cac9348..66382dccd44 100644 --- a/src/librbd/ImageWatcher.cc +++ b/src/librbd/ImageWatcher.cc @@ -554,6 +554,24 @@ int ImageWatcher::notify_snap_remove(const std::string &snap_name) { return notify_lock_owner(bl); } +int ImageWatcher::notify_snap_protect(const std::string &snap_name) { + assert(m_image_ctx.owner_lock.is_locked()); + assert(!is_lock_owner()); + + bufferlist bl; + ::encode(NotifyMessage(SnapProtectPayload(snap_name)), bl); + return notify_lock_owner(bl); +} + +int ImageWatcher::notify_snap_unprotect(const std::string &snap_name) { + assert(m_image_ctx.owner_lock.is_locked()); + assert(!is_lock_owner()); + + bufferlist bl; + ::encode(NotifyMessage(SnapUnprotectPayload(snap_name)), bl); + return notify_lock_owner(bl); +} + int ImageWatcher::notify_rebuild_object_map(uint64_t request_id, ProgressContext &prog_ctx) { assert(m_image_ctx.owner_lock.is_locked()); @@ -567,6 +585,15 @@ int ImageWatcher::notify_rebuild_object_map(uint64_t request_id, return notify_async_request(async_request_id, bl, prog_ctx); } +int ImageWatcher::notify_rename(const std::string &image_name) { + assert(m_image_ctx.owner_lock.is_locked()); + assert(!is_lock_owner()); + + bufferlist bl; + ::encode(NotifyMessage(RenamePayload(image_name)), bl); + return notify_lock_owner(bl); +} + void ImageWatcher::notify_lock_state() { RWLock::RLocker owner_locker(m_image_ctx.owner_lock); if (m_lock_owner_state == LOCK_OWNER_STATE_LOCKED) { @@ -1053,11 +1080,11 @@ void ImageWatcher::handle_payload(const SnapRenamePayload &payload, if (m_lock_owner_state == LOCK_OWNER_STATE_LOCKED) { ldout(m_image_ctx.cct, 10) << this << " remote snap_rename request: " << payload.src_snap_id << " to " - << payload.dst_snap_name << dendl; + << payload.snap_name << dendl; C_SaferCond cond_ctx; int r = librbd::snap_rename_helper(&m_image_ctx, &cond_ctx, payload.src_snap_id, - payload.dst_snap_name.c_str()); + payload.snap_name.c_str()); if (r == 0) { r = cond_ctx.wait(); } @@ -1082,6 +1109,30 @@ void ImageWatcher::handle_payload(const SnapRemovePayload &payload, } } +void ImageWatcher::handle_payload(const SnapProtectPayload& payload, + bufferlist *out) { + RWLock::RLocker owner_locker(m_image_ctx.owner_lock); + if (m_lock_owner_state == LOCK_OWNER_STATE_LOCKED) { + ldout(m_image_ctx.cct, 10) << this << " remote snap_protect request: " + << payload.snap_name << dendl; + + // TODO + ::encode(ResponseMessage(-EOPNOTSUPP), *out); + } +} + +void ImageWatcher::handle_payload(const SnapUnprotectPayload& payload, + bufferlist *out) { + RWLock::RLocker owner_locker(m_image_ctx.owner_lock); + if (m_lock_owner_state == LOCK_OWNER_STATE_LOCKED) { + ldout(m_image_ctx.cct, 10) << this << " remote snap_unprotect request: " + << payload.snap_name << dendl; + + // TODO + ::encode(ResponseMessage(-EOPNOTSUPP), *out); + } +} + void ImageWatcher::handle_payload(const RebuildObjectMapPayload& payload, bufferlist *out) { RWLock::RLocker l(m_image_ctx.owner_lock); @@ -1108,6 +1159,18 @@ void ImageWatcher::handle_payload(const RebuildObjectMapPayload& payload, } } +void ImageWatcher::handle_payload(const RenamePayload& payload, + bufferlist *out) { + RWLock::RLocker owner_locker(m_image_ctx.owner_lock); + if (m_lock_owner_state == LOCK_OWNER_STATE_LOCKED) { + ldout(m_image_ctx.cct, 10) << this << " remote rename request: " + << payload.image_name << dendl; + + // TODO + ::encode(ResponseMessage(-EOPNOTSUPP), *out); + } +} + void ImageWatcher::handle_payload(const UnknownPayload &payload, bufferlist *out) { RWLock::RLocker l(m_image_ctx.owner_lock); diff --git a/src/librbd/ImageWatcher.h b/src/librbd/ImageWatcher.h index 2611b552177..6e2a4c5eb34 100644 --- a/src/librbd/ImageWatcher.h +++ b/src/librbd/ImageWatcher.h @@ -69,8 +69,11 @@ public: int notify_snap_rename(const snapid_t &src_snap_id, const std::string &dst_snap_name); int notify_snap_remove(const std::string &snap_name); + int notify_snap_protect(const std::string &snap_name); + int notify_snap_unprotect(const std::string &snap_name); int notify_rebuild_object_map(uint64_t request_id, ProgressContext &prog_ctx); + int notify_rename(const std::string &image_name); void notify_lock_state(); static void notify_header_update(librados::IoCtx &io_ctx, @@ -293,8 +296,14 @@ private: bufferlist *out); void handle_payload(const watch_notify::SnapRemovePayload& payload, bufferlist *out); + void handle_payload(const watch_notify::SnapProtectPayload& payload, + bufferlist *out); + void handle_payload(const watch_notify::SnapUnprotectPayload& payload, + bufferlist *out); void handle_payload(const watch_notify::RebuildObjectMapPayload& payload, bufferlist *out); + void handle_payload(const watch_notify::RenamePayload& payload, + bufferlist *out); void handle_payload(const watch_notify::UnknownPayload& payload, bufferlist *out); diff --git a/src/librbd/WatchNotifyTypes.cc b/src/librbd/WatchNotifyTypes.cc index a21b233937d..93b12ee40dd 100644 --- a/src/librbd/WatchNotifyTypes.cc +++ b/src/librbd/WatchNotifyTypes.cc @@ -146,124 +146,105 @@ void HeaderUpdatePayload::decode(__u8 version, bufferlist::iterator &iter) { void HeaderUpdatePayload::dump(Formatter *f) const { } -void AsyncProgressPayload::encode(bufferlist &bl) const { +void AsyncRequestPayloadBase::encode(bufferlist &bl) const { ::encode(async_request_id, bl); +} + +void AsyncRequestPayloadBase::decode(__u8 version, bufferlist::iterator &iter) { + ::decode(async_request_id, iter); +} + +void AsyncRequestPayloadBase::dump(Formatter *f) const { + f->open_object_section("async_request_id"); + async_request_id.dump(f); + f->close_section(); +} + +void AsyncProgressPayload::encode(bufferlist &bl) const { + AsyncRequestPayloadBase::encode(bl); ::encode(offset, bl); ::encode(total, bl); } void AsyncProgressPayload::decode(__u8 version, bufferlist::iterator &iter) { - ::decode(async_request_id, iter); + AsyncRequestPayloadBase::decode(version, iter); ::decode(offset, iter); ::decode(total, iter); } void AsyncProgressPayload::dump(Formatter *f) const { - f->open_object_section("async_request_id"); - async_request_id.dump(f); - f->close_section(); + AsyncRequestPayloadBase::dump(f); f->dump_unsigned("offset", offset); f->dump_unsigned("total", total); } void AsyncCompletePayload::encode(bufferlist &bl) const { - ::encode(async_request_id, bl); + AsyncRequestPayloadBase::encode(bl); ::encode(result, bl); } void AsyncCompletePayload::decode(__u8 version, bufferlist::iterator &iter) { - ::decode(async_request_id, iter); + AsyncRequestPayloadBase::decode(version, iter); ::decode(result, iter); } void AsyncCompletePayload::dump(Formatter *f) const { - f->open_object_section("async_request_id"); - async_request_id.dump(f); - f->close_section(); + AsyncRequestPayloadBase::dump(f); f->dump_int("result", result); } -void FlattenPayload::encode(bufferlist &bl) const { - ::encode(async_request_id, bl); -} - -void FlattenPayload::decode(__u8 version, bufferlist::iterator &iter) { - ::decode(async_request_id, iter); -} - -void FlattenPayload::dump(Formatter *f) const { - f->open_object_section("async_request_id"); - async_request_id.dump(f); - f->close_section(); -} - void ResizePayload::encode(bufferlist &bl) const { ::encode(size, bl); - ::encode(async_request_id, bl); + AsyncRequestPayloadBase::encode(bl); } void ResizePayload::decode(__u8 version, bufferlist::iterator &iter) { ::decode(size, iter); - ::decode(async_request_id, iter); + AsyncRequestPayloadBase::decode(version, iter); } void ResizePayload::dump(Formatter *f) const { f->dump_unsigned("size", size); - f->open_object_section("async_request_id"); - async_request_id.dump(f); - f->close_section(); + AsyncRequestPayloadBase::dump(f); } -void SnapCreatePayload::encode(bufferlist &bl) const { +void SnapPayloadBase::encode(bufferlist &bl) const { ::encode(snap_name, bl); } -void SnapCreatePayload::decode(__u8 version, bufferlist::iterator &iter) { +void SnapPayloadBase::decode(__u8 version, bufferlist::iterator &iter) { ::decode(snap_name, iter); } -void SnapCreatePayload::dump(Formatter *f) const { +void SnapPayloadBase::dump(Formatter *f) const { f->dump_string("snap_name", snap_name); } void SnapRenamePayload::encode(bufferlist &bl) const { - ::encode(src_snap_id, bl); - ::encode(dst_snap_name, bl); + ::encode(snap_id, bl); + SnapPayloadBase::encode(bl); } void SnapRenamePayload::decode(__u8 version, bufferlist::iterator &iter) { - ::decode(src_snap_id, iter); - ::decode(dst_snap_name, iter); + ::decode(snap_id, iter); + SnapPayloadBase::decode(version, iter); } void SnapRenamePayload::dump(Formatter *f) const { - f->dump_unsigned("src_snap_id", src_snap_id); - f->dump_string("dst_snap_name", dst_snap_name); -} -void SnapRemovePayload::encode(bufferlist &bl) const { - ::encode(snap_name, bl); -} - -void SnapRemovePayload::decode(__u8 version, bufferlist::iterator &iter) { - ::decode(snap_name, iter); + f->dump_unsigned("src_snap_id", snap_id); + SnapPayloadBase::dump(f); } -void SnapRemovePayload::dump(Formatter *f) const { - f->dump_string("snap_name", snap_name); +void RenamePayload::encode(bufferlist &bl) const { + ::encode(image_name, bl); } -void RebuildObjectMapPayload::encode(bufferlist &bl) const { - ::encode(async_request_id, bl); +void RenamePayload::decode(__u8 version, bufferlist::iterator &iter) { + ::decode(image_name, iter); } -void RebuildObjectMapPayload::decode(__u8 version, bufferlist::iterator &iter) { - ::decode(async_request_id, iter); -} - -void RebuildObjectMapPayload::dump(Formatter *f) const { - f->open_object_section("async_request_id"); - async_request_id.dump(f); - f->close_section(); +void RenamePayload::dump(Formatter *f) const { + f->dump_string("image_name", image_name); } void UnknownPayload::encode(bufferlist &bl) const { @@ -323,9 +304,18 @@ void NotifyMessage::decode(bufferlist::iterator& iter) { case NOTIFY_OP_SNAP_RENAME: payload = SnapRenamePayload(); break; + case NOTIFY_OP_SNAP_PROTECT: + payload = SnapProtectPayload(); + break; + case NOTIFY_OP_SNAP_UNPROTECT: + payload = SnapUnprotectPayload(); + break; case NOTIFY_OP_REBUILD_OBJECT_MAP: payload = RebuildObjectMapPayload(); break; + case NOTIFY_OP_RENAME: + payload = RenamePayload(); + break; default: payload = UnknownPayload(); break; @@ -350,7 +340,10 @@ void NotifyMessage::generate_test_instances(std::list &o) { o.push_back(new NotifyMessage(ResizePayload(123, AsyncRequestId(ClientId(0, 1), 2)))); o.push_back(new NotifyMessage(SnapCreatePayload("foo"))); o.push_back(new NotifyMessage(SnapRemovePayload("foo"))); + o.push_back(new NotifyMessage(SnapProtectPayload("foo"))); + o.push_back(new NotifyMessage(SnapUnprotectPayload("foo"))); o.push_back(new NotifyMessage(RebuildObjectMapPayload(AsyncRequestId(ClientId(0, 1), 2)))); + o.push_back(new NotifyMessage(RenamePayload("foo"))); } void ResponseMessage::encode(bufferlist& bl) const { @@ -414,9 +407,18 @@ std::ostream &operator<<(std::ostream &out, case NOTIFY_OP_SNAP_RENAME: out << "SnapRename"; break; + case NOTIFY_OP_SNAP_PROTECT: + out << "SnapProtect"; + break; + case NOTIFY_OP_SNAP_UNPROTECT: + out << "SnapUnprotect"; + break; case NOTIFY_OP_REBUILD_OBJECT_MAP: out << "RebuildObjectMap"; break; + case NOTIFY_OP_RENAME: + out << "Rename"; + break; default: out << "Unknown (" << static_cast(op) << ")"; break; diff --git a/src/librbd/WatchNotifyTypes.h b/src/librbd/WatchNotifyTypes.h index e7ba50d32e3..30ab2d01638 100644 --- a/src/librbd/WatchNotifyTypes.h +++ b/src/librbd/WatchNotifyTypes.h @@ -84,7 +84,10 @@ enum NotifyOp { NOTIFY_OP_SNAP_CREATE = 8, NOTIFY_OP_SNAP_REMOVE = 9, NOTIFY_OP_REBUILD_OBJECT_MAP = 10, - NOTIFY_OP_SNAP_RENAME = 11 + NOTIFY_OP_SNAP_RENAME = 11, + NOTIFY_OP_SNAP_PROTECT = 12, + NOTIFY_OP_SNAP_UNPROTECT = 13, + NOTIFY_OP_RENAME = 14 }; struct AcquiredLockPayload { @@ -134,14 +137,26 @@ struct HeaderUpdatePayload { void dump(Formatter *f) const; }; -struct AsyncProgressPayload { +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; AsyncProgressPayload() : offset(0), total(0) {} AsyncProgressPayload(const AsyncRequestId &id, uint64_t offset_, uint64_t total_) - : async_request_id(id), offset(offset_), total(total_) {} + : AsyncRequestPayloadBase(id), offset(offset_), total(total_) {} - AsyncRequestId async_request_id; uint64_t offset; uint64_t total; @@ -150,14 +165,13 @@ struct AsyncProgressPayload { void dump(Formatter *f) const; }; -struct AsyncCompletePayload { +struct AsyncCompletePayload : public AsyncRequestPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_ASYNC_COMPLETE; AsyncCompletePayload() {} AsyncCompletePayload(const AsyncRequestId &id, int r) - : async_request_id(id), result(r) {} + : AsyncRequestPayloadBase(id), result(r) {} - AsyncRequestId async_request_id; int result; void encode(bufferlist &bl) const; @@ -165,82 +179,97 @@ struct AsyncCompletePayload { void dump(Formatter *f) const; }; -struct FlattenPayload { +struct FlattenPayload : public AsyncRequestPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_FLATTEN; FlattenPayload() {} - FlattenPayload(const AsyncRequestId &id) : async_request_id(id) {} - - AsyncRequestId async_request_id; - - void encode(bufferlist &bl) const; - void decode(__u8 version, bufferlist::iterator &iter); - void dump(Formatter *f) const; + FlattenPayload(const AsyncRequestId &id) : AsyncRequestPayloadBase(id) {} }; -struct ResizePayload { +struct ResizePayload : public AsyncRequestPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_RESIZE; ResizePayload() : size(0) {} ResizePayload(uint64_t size_, const AsyncRequestId &id) - : size(size_), async_request_id(id) {} + : AsyncRequestPayloadBase(id), size(size_) {} uint64_t size; - AsyncRequestId async_request_id; void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; }; -struct SnapCreatePayload { - static const NotifyOp NOTIFY_OP = NOTIFY_OP_SNAP_CREATE; - - SnapCreatePayload() {} - SnapCreatePayload(const std::string &name) : snap_name(name) {} - +struct SnapPayloadBase { +public: 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 std::string &name) : snap_name(name) {} +}; + +struct SnapCreatePayload : public SnapPayloadBase { + static const NotifyOp NOTIFY_OP = NOTIFY_OP_SNAP_CREATE; + + SnapCreatePayload() {} + SnapCreatePayload(const std::string &name) : SnapPayloadBase(name) {} }; -struct SnapRenamePayload { +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) - : src_snap_id(src_snap_id), dst_snap_name(dst_name) {} + : SnapPayloadBase(dst_name), snap_id(src_snap_id) {} - uint64_t src_snap_id; - std::string dst_snap_name; + uint64_t snap_id; void encode(bufferlist &bl) const; void decode(__u8 version, bufferlist::iterator &iter); void dump(Formatter *f) const; }; -struct SnapRemovePayload { +struct SnapRemovePayload : public SnapPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_SNAP_REMOVE; SnapRemovePayload() {} - SnapRemovePayload(const std::string &name) : snap_name(name) {} + SnapRemovePayload(const std::string &name) : SnapPayloadBase(name) {} +}; - std::string snap_name; +struct SnapProtectPayload : public SnapPayloadBase { + static const NotifyOp NOTIFY_OP = NOTIFY_OP_SNAP_PROTECT; - void encode(bufferlist &bl) const; - void decode(__u8 version, bufferlist::iterator &iter); - void dump(Formatter *f) const; + SnapProtectPayload() {} + SnapProtectPayload(const std::string &name) : SnapPayloadBase(name) {} +}; + +struct SnapUnprotectPayload : public SnapPayloadBase { + static const NotifyOp NOTIFY_OP = NOTIFY_OP_SNAP_UNPROTECT; + + SnapUnprotectPayload() {} + SnapUnprotectPayload(const std::string &name) : SnapPayloadBase(name) {} }; -struct RebuildObjectMapPayload { +struct RebuildObjectMapPayload : public AsyncRequestPayloadBase { static const NotifyOp NOTIFY_OP = NOTIFY_OP_REBUILD_OBJECT_MAP; RebuildObjectMapPayload() {} - RebuildObjectMapPayload(const AsyncRequestId &id) : async_request_id(id) {} + RebuildObjectMapPayload(const AsyncRequestId &id) + : AsyncRequestPayloadBase(id) {} +}; - AsyncRequestId async_request_id; +struct RenamePayload { + static const NotifyOp NOTIFY_OP = NOTIFY_OP_RENAME; + + 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); @@ -266,7 +295,10 @@ typedef boost::variant Payload; struct NotifyMessage {