]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: new watch/notify types for snap protect/unprotect and rename
authorJason Dillaman <dillaman@redhat.com>
Thu, 30 Jul 2015 18:08:00 +0000 (14:08 -0400)
committerJason Dillaman <dillaman@redhat.com>
Thu, 19 Nov 2015 01:34:38 +0000 (20:34 -0500)
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 <dillaman@redhat.com>
src/librbd/ImageWatcher.cc
src/librbd/ImageWatcher.h
src/librbd/WatchNotifyTypes.cc
src/librbd/WatchNotifyTypes.h

index 0065cac9348f966b4a51d4c7f205b56adc4ba8a7..66382dccd44e4dec0b2dd704374a07df2d460ddc 100644 (file)
@@ -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);
index 2611b552177b2009ad59e8b82f91b2b9ebc65c30..6e2a4c5eb3463165d7ed190738edf8e290b293b8 100644 (file)
@@ -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);
 
index a21b233937d483f4066a9974aa8170960de6e23a..93b12ee40dd63a0313b1375d8e2affa485f23a64 100644 (file)
@@ -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<NotifyMessage *> &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<uint32_t>(op) << ")";
     break;
index e7ba50d32e3aebd99ee50a870c974d7b0bebe11c..30ab2d016389290719bdd236f1c9d2ab1769ef0a 100644 (file)
@@ -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<AcquiredLockPayload,
                        SnapCreatePayload,
                        SnapRemovePayload,
                        SnapRenamePayload,
+                       SnapProtectPayload,
+                       SnapUnprotectPayload,
                        RebuildObjectMapPayload,
+                       RenamePayload,
                        UnknownPayload> Payload;
 
 struct NotifyMessage {