]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: refactor watcher types
authorMykola Golub <mgolub@mirantis.com>
Tue, 28 Mar 2017 10:59:08 +0000 (12:59 +0200)
committerMykola Golub <mgolub@mirantis.com>
Tue, 28 Mar 2017 14:07:29 +0000 (16:07 +0200)
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
14 files changed:
src/librbd/CMakeLists.txt
src/librbd/ImageWatcher.cc
src/librbd/ImageWatcher.h
src/librbd/MirroringWatcher.cc
src/librbd/MirroringWatcher.h
src/librbd/WatchNotifyTypes.cc
src/librbd/WatchNotifyTypes.h
src/librbd/Watcher.cc
src/librbd/Watcher.h
src/librbd/mirroring_watcher/Types.cc
src/librbd/watcher/Types.cc
src/librbd/watcher/Types.h
src/librbd/watcher/Utils.h [new file with mode: 0644]
src/tools/rbd_mirror/LeaderWatcher.cc

index f8973e8b2ea583800ff66cd50e6960aa5200f6eb..52cfbd8ac182638589f4fc5b06891f3b8d071e83 100644 (file)
@@ -1,6 +1,7 @@
 add_library(rbd_types STATIC
   journal/Types.cc
   mirroring_watcher/Types.cc
+  watcher/Types.cc
   WatchNotifyTypes.cc)
 
 set(librbd_internal_srcs
@@ -100,7 +101,6 @@ set(librbd_internal_srcs
   operation/TrimRequest.cc
   watcher/Notifier.cc
   watcher/RewatchRequest.cc
-  watcher/Types.cc
   ${CMAKE_SOURCE_DIR}/src/common/ContextCompletion.cc)
 
 add_library(rbd_api STATIC librbd.cc)
index 18b55a0c070e5f30c4d9405bf6027069812ca5b3..0e85a6a4c42700095de36645fa79e51ec2ca771f 100644 (file)
@@ -12,6 +12,7 @@
 #include "librbd/exclusive_lock/Policy.h"
 #include "librbd/image_watcher/NotifyLockOwner.h"
 #include "librbd/io/AioCompletion.h"
+#include "librbd/watcher/Utils.h"
 #include "include/encoding.h"
 #include "common/errno.h"
 #include "common/WorkQueue.h"
@@ -28,8 +29,7 @@ using namespace watch_notify;
 using util::create_async_context_callback;
 using util::create_context_callback;
 using util::create_rados_callback;
-using librbd::watcher::HandlePayloadVisitor;
-using librbd::watcher::C_NotifyAck;
+using librbd::watcher::util::HandlePayloadVisitor;
 
 static const double    RETRY_DELAY_SECONDS = 1.0;
 
index 9e899eb7885637d272a054f557f2b3902a6b290e..838e0e3d0122aedef422e982ca5bd870dcbb3504 100644 (file)
@@ -20,15 +20,17 @@ class entity_name_t;
 namespace librbd {
 
 namespace watcher {
+namespace util {
 template <typename> struct HandlePayloadVisitor;
 }
+}
 
 class ImageCtx;
 template <typename> class TaskFinisher;
 
 template <typename ImageCtxT = ImageCtx>
 class ImageWatcher : public Watcher {
-  friend struct watcher::HandlePayloadVisitor<ImageWatcher<ImageCtxT>>;
+  friend struct watcher::util::HandlePayloadVisitor<ImageWatcher<ImageCtxT>>;
 
 public:
   ImageWatcher(ImageCtxT& image_ctx);
@@ -161,9 +163,9 @@ private:
   };
 
   struct C_ResponseMessage : public Context {
-    watcher::C_NotifyAck *notify_ack;
+    C_NotifyAck *notify_ack;
 
-    C_ResponseMessage(watcher::C_NotifyAck *notify_ack) : notify_ack(notify_ack) {
+    C_ResponseMessage(C_NotifyAck *notify_ack) : notify_ack(notify_ack) {
     }
     void finish(int r) override;
   };
@@ -215,41 +217,41 @@ private:
                             ProgressContext** prog_ctx);
 
   bool handle_payload(const watch_notify::HeaderUpdatePayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::AcquiredLockPayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::ReleasedLockPayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::RequestLockPayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::AsyncProgressPayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::AsyncCompletePayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::FlattenPayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::ResizePayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::SnapCreatePayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::SnapRenamePayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::SnapRemovePayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::SnapProtectPayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::SnapUnprotectPayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::RebuildObjectMapPayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::RenamePayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::UpdateFeaturesPayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   bool handle_payload(const watch_notify::UnknownPayload& payload,
-                      watcher::C_NotifyAck *ctx);
+                      C_NotifyAck *ctx);
   void process_payload(uint64_t notify_id, uint64_t handle,
-                             const watch_notify::Payload &payload, int r);
+                       const watch_notify::Payload &payload, int r);
 
   void handle_notify(uint64_t notify_id, uint64_t handle,
                      uint64_t notifier_id, bufferlist &bl) override;
index 753ca91f44b7af4268550c9a74270acf9d2a39ff..df287506f096b725f9f7bbd5aa1a7aa933db4843 100644 (file)
@@ -6,6 +6,7 @@
 #include "include/rados/librados.hpp"
 #include "common/errno.h"
 #include "librbd/Utils.h"
+#include "librbd/watcher/Utils.h"
 
 #define dout_subsys ceph_subsys_rbd
 #undef dout_prefix
@@ -16,6 +17,8 @@ namespace librbd {
 using namespace mirroring_watcher;
 using namespace watcher;
 
+using librbd::util::create_rados_callback;
+
 namespace {
 
 static const uint64_t NOTIFY_TIMEOUT_MS = 5000;
@@ -46,7 +49,7 @@ void MirroringWatcher<I>::notify_mode_updated(librados::IoCtx &io_ctx,
   bufferlist bl;
   ::encode(NotifyMessage{ModeUpdatedPayload{mirror_mode}}, bl);
 
-  librados::AioCompletion *comp = util::create_rados_callback(on_finish);
+  librados::AioCompletion *comp = create_rados_callback(on_finish);
   int r = io_ctx.aio_notify(RBD_MIRRORING, comp, bl, NOTIFY_TIMEOUT_MS,
                             nullptr);
   assert(r == 0);
@@ -76,7 +79,7 @@ void MirroringWatcher<I>::notify_image_updated(
   ::encode(NotifyMessage{ImageUpdatedPayload{
       mirror_image_state, image_id, global_image_id}}, bl);
 
-  librados::AioCompletion *comp = util::create_rados_callback(on_finish);
+  librados::AioCompletion *comp = create_rados_callback(on_finish);
   int r = io_ctx.aio_notify(RBD_MIRRORING, comp, bl, NOTIFY_TIMEOUT_MS,
                             nullptr);
   assert(r == 0);
@@ -104,9 +107,8 @@ void MirroringWatcher<I>::handle_notify(uint64_t notify_id, uint64_t handle,
     return;
   }
 
-  apply_visitor(HandlePayloadVisitor<MirroringWatcher<I>>(this, notify_id,
-                                                          handle),
-                notify_message.payload);
+  apply_visitor(watcher::util::HandlePayloadVisitor<MirroringWatcher<I>>(
+                  this, notify_id, handle), notify_message.payload);
 }
 
 template <typename I>
index ede06d8fe0878418a4ca91a845bddaff7ad1256e..90f43329de582ef03c9ca63dd298325046731d49 100644 (file)
@@ -17,12 +17,14 @@ namespace librados {
 namespace librbd {
 
 namespace watcher {
+namespace util {
 template <typename> struct HandlePayloadVisitor;
 }
+}
 
 template <typename ImageCtxT = librbd::ImageCtx>
 class MirroringWatcher : public Watcher {
-  friend struct watcher::HandlePayloadVisitor<MirroringWatcher<ImageCtxT>>;
+  friend struct watcher::util::HandlePayloadVisitor<MirroringWatcher<ImageCtxT>>;
 
 public:
   MirroringWatcher(librados::IoCtx &io_ctx, ContextWQ *work_queue);
index bef0b612f226171c25c626f6e654e4f3fea3a0af..4f7f1b0d7e55d546e53002c787908119e56134ef 100644 (file)
@@ -2,11 +2,11 @@
 // vim: ts=8 sw=2 smarttab
 
 #include "cls/rbd/cls_rbd_types.h"
-#include "librbd/WatchNotifyTypes.h"
-#include "librbd/watcher/Types.h"
+#include "common/Formatter.h"
 #include "include/assert.h"
 #include "include/stringify.h"
-#include "common/Formatter.h"
+#include "librbd/WatchNotifyTypes.h"
+#include "librbd/watcher/Utils.h"
 
 namespace librbd {
 namespace watch_notify {
@@ -38,21 +38,6 @@ private:
 
 } // anonymous namespace
 
-void ClientId::encode(bufferlist &bl) const {
-  ::encode(gid, bl);
-  ::encode(handle, bl);
-}
-
-void ClientId::decode(bufferlist::iterator &iter) {
-  ::decode(gid, iter);
-  ::decode(handle, iter);
-}
-
-void ClientId::dump(Formatter *f) const {
-  f->dump_unsigned("gid", gid);
-  f->dump_unsigned("handle", handle);
-}
-
 void AsyncRequestId::encode(bufferlist &bl) const {
   ::encode(client_id, bl);
   ::encode(request_id, bl);
@@ -295,7 +280,7 @@ bool NotifyMessage::check_for_refresh() const {
 
 void NotifyMessage::encode(bufferlist& bl) const {
   ENCODE_START(6, 1, bl);
-  boost::apply_visitor(watcher::EncodePayloadVisitor(bl), payload);
+  boost::apply_visitor(watcher::util::EncodePayloadVisitor(bl), payload);
   ENCODE_FINISH(bl);
 }
 
@@ -360,7 +345,7 @@ void NotifyMessage::decode(bufferlist::iterator& iter) {
     break;
   }
 
-  apply_visitor(watcher::DecodePayloadVisitor(struct_v, iter), payload);
+  apply_visitor(watcher::util::DecodePayloadVisitor(struct_v, iter), payload);
   DECODE_FINISH(iter);
 }
 
@@ -470,12 +455,6 @@ std::ostream &operator<<(std::ostream &out,
   return out;
 }
 
-std::ostream &operator<<(std::ostream &out,
-                         const librbd::watch_notify::ClientId &client_id) {
-  out << "[" << client_id.gid << "," << client_id.handle << "]";
-  return out;
-}
-
 std::ostream &operator<<(std::ostream &out,
                          const librbd::watch_notify::AsyncRequestId &request) {
   out << "[" << request.client_id.gid << "," << request.client_id.handle << ","
index 439ae8c415148b1efa730d7a460aa7096e9ab5c2..6cd94b3959b04681f52f2a80898d2daa432b4f1e 100644 (file)
@@ -7,6 +7,7 @@
 #include "include/int_types.h"
 #include "include/buffer_fwd.h"
 #include "include/encoding.h"
+#include "librbd/watcher/Types.h"
 #include <iosfwd>
 #include <list>
 #include <string>
@@ -19,35 +20,7 @@ class Formatter;
 namespace librbd {
 namespace watch_notify {
 
-struct ClientId {
-  uint64_t gid;
-  uint64_t handle;
-
-  ClientId() : gid(0), handle(0) {}
-  ClientId(uint64_t gid_, uint64_t handle_) : gid(gid_), handle(handle_) {}
-
-  void encode(bufferlist& bl) const;
-  void decode(bufferlist::iterator& it);
-  void dump(Formatter *f) const;
-
-  inline bool is_valid() const {
-    return (*this != ClientId());
-  }
-
-  inline bool operator==(const ClientId &rhs) const {
-    return (gid == rhs.gid && handle == rhs.handle);
-  }
-  inline bool operator!=(const ClientId &rhs) const {
-    return !(*this == rhs);
-  }
-  inline bool operator<(const ClientId &rhs) const {
-    if (gid != rhs.gid) {
-      return gid < rhs.gid;
-    } else {
-      return handle < rhs.handle;
-    }
-  }
-};
+using librbd::watcher::ClientId;
 
 struct AsyncRequestId {
   ClientId client_id;
@@ -386,12 +359,9 @@ struct ResponseMessage {
 
 std::ostream &operator<<(std::ostream &out,
                          const librbd::watch_notify::NotifyOp &op);
-std::ostream &operator<<(std::ostream &out,
-                         const librbd::watch_notify::ClientId &client);
 std::ostream &operator<<(std::ostream &out,
                          const librbd::watch_notify::AsyncRequestId &request);
 
-WRITE_CLASS_ENCODER(librbd::watch_notify::ClientId);
 WRITE_CLASS_ENCODER(librbd::watch_notify::AsyncRequestId);
 WRITE_CLASS_ENCODER(librbd::watch_notify::NotifyMessage);
 WRITE_CLASS_ENCODER(librbd::watch_notify::ResponseMessage);
index 9d986a1a5782a2d86b3ac7e5a1e5ca27d3f2a439..d678ffba80914e8f1ffdb7ccad7c8bca75320fd8 100644 (file)
@@ -11,9 +11,6 @@
 #include <boost/bind.hpp>
 
 #define dout_subsys ceph_subsys_rbd
-#undef dout_prefix
-#define dout_prefix *_dout << "librbd::Watcher: " << this << " " << __func__ \
-                           << ": "
 
 namespace librbd {
 
@@ -66,6 +63,27 @@ struct C_UnwatchAndFlush : public Context {
 
 } // anonymous namespace
 
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::Watcher::C_NotifyAck " << this << " " \
+                           << __func__ << ": "
+
+Watcher::C_NotifyAck::C_NotifyAck(Watcher *watcher, uint64_t notify_id,
+                                  uint64_t handle)
+  : watcher(watcher), cct(watcher->m_cct), notify_id(notify_id),
+    handle(handle) {
+  ldout(cct, 10) << "id=" << notify_id << ", " << "handle=" << handle << dendl;
+}
+
+void Watcher::C_NotifyAck::finish(int r) {
+  ldout(cct, 10) << "r=" << r << dendl;
+  assert(r == 0);
+  watcher->acknowledge_notify(notify_id, handle, out);
+}
+
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::Watcher: " << this << " " << __func__ \
+                           << ": "
+
 Watcher::Watcher(librados::IoCtx& ioctx, ContextWQ *work_queue,
                           const string& oid)
   : m_ioctx(ioctx), m_work_queue(work_queue), m_oid(oid),
index 099b007b8f6e02ed42fe4e2b20b1056113a4db5c..7d50192e05743e59b02fc93ca43cd8bd6b19765b 100644 (file)
@@ -17,9 +17,18 @@ class ContextWQ;
 namespace librbd {
 
 class Watcher {
-  friend struct watcher::C_NotifyAck;
-
 public:
+  struct C_NotifyAck : public Context {
+    Watcher *watcher;
+    CephContext *cct;
+    uint64_t notify_id;
+    uint64_t handle;
+    bufferlist out;
+
+    C_NotifyAck(Watcher *watcher, uint64_t notify_id, uint64_t handle);
+    void finish(int r) override;
+  };
+
   Watcher(librados::IoCtx& ioctx, ContextWQ *work_queue,
           const std::string& oid);
   virtual ~Watcher();
index ffbc866fa21b9d124e3990ccc2356b0f80d68dae..dd0dc1de5cf145e6fafa1b582dad98fcdbe02770 100644 (file)
@@ -1,11 +1,11 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
-#include "librbd/mirroring_watcher/Types.h"
-#include "librbd/watcher/Types.h"
+#include "common/Formatter.h"
 #include "include/assert.h"
 #include "include/stringify.h"
-#include "common/Formatter.h"
+#include "librbd/mirroring_watcher/Types.h"
+#include "librbd/watcher/Utils.h"
 
 namespace librbd {
 namespace mirroring_watcher {
@@ -76,7 +76,7 @@ void UnknownPayload::dump(Formatter *f) const {
 
 void NotifyMessage::encode(bufferlist& bl) const {
   ENCODE_START(1, 1, bl);
-  boost::apply_visitor(watcher::EncodePayloadVisitor(bl), payload);
+  boost::apply_visitor(watcher::util::EncodePayloadVisitor(bl), payload);
   ENCODE_FINISH(bl);
 }
 
@@ -99,7 +99,7 @@ void NotifyMessage::decode(bufferlist::iterator& iter) {
     break;
   }
 
-  apply_visitor(watcher::DecodePayloadVisitor(struct_v, iter), payload);
+  apply_visitor(watcher::util::DecodePayloadVisitor(struct_v, iter), payload);
   DECODE_FINISH(iter);
 }
 
index 1ea07a2e23206f11af5ae2db8c4ac55cd52be859..e50cfdaf729f7dd056d82b2421165d72faa6c762 100644 (file)
@@ -2,40 +2,31 @@
 // vim: ts=8 sw=2 smarttab
 
 #include "librbd/watcher/Types.h"
-#include "librbd/Watcher.h"
-#include "common/dout.h"
-
-#include "librbd/ImageCtx.h"
-#include "librbd/MirroringWatcher.h"
-#include "librbd/ImageWatcher.h"
-
-#define dout_subsys ceph_subsys_rbd
-#undef dout_prefix
-#define dout_prefix *_dout << "librbd::Watcher: "
+#include "common/Formatter.h"
 
 namespace librbd {
 namespace watcher {
 
-C_NotifyAck::C_NotifyAck(Watcher *watcher, uint64_t notify_id,
-                         uint64_t handle)
-  : watcher(watcher), cct(watcher->m_cct), notify_id(notify_id),
-    handle(handle) {
-  ldout(cct, 10) << this << " C_NotifyAck start: id=" << notify_id << ", "
-                 << "handle=" << handle << dendl;
+void ClientId::encode(bufferlist &bl) const {
+  ::encode(gid, bl);
+  ::encode(handle, bl);
+}
+
+void ClientId::decode(bufferlist::iterator &iter) {
+  ::decode(gid, iter);
+  ::decode(handle, iter);
 }
 
-void C_NotifyAck::finish(int r) {
-  assert(r == 0);
-  ldout(cct, 10) << this << " C_NotifyAck finish: id=" << notify_id << ", "
-                 << "handle=" << handle << dendl;
-  watcher->acknowledge_notify(notify_id, handle, out);
+void ClientId::dump(Formatter *f) const {
+  f->dump_unsigned("gid", gid);
+  f->dump_unsigned("handle", handle);
 }
 
 } // namespace watcher
 } // namespace librbd
 
-template struct librbd::watcher::HandlePayloadVisitor<
-    librbd::MirroringWatcher<librbd::ImageCtx>>;
-
-template struct librbd::watcher::HandlePayloadVisitor<
-    librbd::ImageWatcher<librbd::ImageCtx>>;
+std::ostream &operator<<(std::ostream &out,
+                         const librbd::watcher::ClientId &client_id) {
+  out << "[" << client_id.gid << "," << client_id.handle << "]";
+  return out;
+}
index 504f8e4e781b428ee5185339ed4464ff71a4123d..0c65e32fe1230fb2eb1a11900ca32ef64793bbbb 100644 (file)
@@ -4,13 +4,11 @@
 #ifndef CEPH_LIBRBD_WATCHER_TYPES_H
 #define CEPH_LIBRBD_WATCHER_TYPES_H
 
+#include "include/int_types.h"
 #include "include/buffer_fwd.h"
 #include "include/encoding.h"
-#include "include/Context.h"
 
-namespace ceph {
-class Formatter;
-}
+namespace ceph { class Formatter; }
 
 namespace librbd {
 
@@ -18,65 +16,34 @@ class Watcher;
 
 namespace watcher {
 
-struct C_NotifyAck : public Context {
-  Watcher *watcher;
-  CephContext *cct;
-  uint64_t notify_id;
+struct ClientId {
+  uint64_t gid;
   uint64_t handle;
-  bufferlist out;
 
-  C_NotifyAck(Watcher *watcher, uint64_t notify_id, uint64_t handle);
-  void finish(int r) override;
-};
+  ClientId() : gid(0), handle(0) {}
+  ClientId(uint64_t gid, uint64_t handle) : gid(gid), handle(handle) {}
 
-template <typename Watcher>
-struct HandlePayloadVisitor : public boost::static_visitor<void> {
-  Watcher *watcher;
-  uint64_t notify_id;
-  uint64_t handle;
+  void encode(bufferlist& bl) const;
+  void decode(bufferlist::iterator& it);
+  void dump(Formatter *f) const;
 
-  HandlePayloadVisitor(Watcher *watcher_, uint64_t notify_id_,
-      uint64_t handle_)
-    : watcher(watcher_), notify_id(notify_id_), handle(handle_)
-  {
+  inline bool is_valid() const {
+    return (*this != ClientId());
   }
 
-  template <typename P>
-  inline void operator()(const P &payload) const {
-    C_NotifyAck *ctx = new C_NotifyAck(watcher, notify_id, handle);
-    if (watcher->handle_payload(payload, ctx)) {
-      ctx->complete(0);
-    }
+  inline bool operator==(const ClientId &rhs) const {
+    return (gid == rhs.gid && handle == rhs.handle);
   }
-};
-
-class EncodePayloadVisitor : public boost::static_visitor<void> {
-public:
-  explicit EncodePayloadVisitor(bufferlist &bl) : m_bl(bl) {}
-
-  template <typename P>
-  inline void operator()(const P &payload) const {
-    ::encode(static_cast<uint32_t>(P::NOTIFY_OP), m_bl);
-    payload.encode(m_bl);
+  inline bool operator!=(const ClientId &rhs) const {
+    return !(*this == rhs);
   }
-
-private:
-  bufferlist &m_bl;
-};
-
-class DecodePayloadVisitor : public boost::static_visitor<void> {
-public:
-  DecodePayloadVisitor(__u8 version, bufferlist::iterator &iter)
-    : m_version(version), m_iter(iter) {}
-
-  template <typename P>
-  inline void operator()(P &payload) const {
-    payload.decode(m_version, m_iter);
+  inline bool operator<(const ClientId &rhs) const {
+    if (gid != rhs.gid) {
+      return gid < rhs.gid;
+    } else {
+      return handle < rhs.handle;
+    }
   }
-
-private:
-  __u8 m_version;
-  bufferlist::iterator &m_iter;
 };
 
 template <typename ImageCtxT>
@@ -87,4 +54,9 @@ struct Traits {
 } // namespace watcher
 } // namespace librbd
 
+std::ostream &operator<<(std::ostream &out,
+                         const librbd::watcher::ClientId &client);
+
+WRITE_CLASS_ENCODER(librbd::watcher::ClientId);
+
 #endif // CEPH_LIBRBD_WATCHER_TYPES_H
diff --git a/src/librbd/watcher/Utils.h b/src/librbd/watcher/Utils.h
new file mode 100644 (file)
index 0000000..78966d6
--- /dev/null
@@ -0,0 +1,73 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_WATCHER_UTILS_H
+#define CEPH_LIBRBD_WATCHER_UTILS_H
+
+#include "include/buffer_fwd.h"
+#include "include/encoding.h"
+#include "include/Context.h"
+#include "librbd/Watcher.h"
+
+namespace ceph { class Formatter; }
+
+namespace librbd {
+namespace watcher {
+namespace util {
+
+template <typename Watcher>
+struct HandlePayloadVisitor : public boost::static_visitor<void> {
+  Watcher *watcher;
+  uint64_t notify_id;
+  uint64_t handle;
+
+  HandlePayloadVisitor(Watcher *watcher_, uint64_t notify_id_,
+      uint64_t handle_)
+    : watcher(watcher_), notify_id(notify_id_), handle(handle_)
+  {
+  }
+
+  template <typename P>
+  inline void operator()(const P &payload) const {
+    typename Watcher::C_NotifyAck *ctx =
+      new typename Watcher::C_NotifyAck(watcher, notify_id, handle);
+    if (watcher->handle_payload(payload, ctx)) {
+      ctx->complete(0);
+    }
+  }
+};
+
+class EncodePayloadVisitor : public boost::static_visitor<void> {
+public:
+  explicit EncodePayloadVisitor(bufferlist &bl) : m_bl(bl) {}
+
+  template <typename P>
+  inline void operator()(const P &payload) const {
+    ::encode(static_cast<uint32_t>(P::NOTIFY_OP), m_bl);
+    payload.encode(m_bl);
+  }
+
+private:
+  bufferlist &m_bl;
+};
+
+class DecodePayloadVisitor : public boost::static_visitor<void> {
+public:
+  DecodePayloadVisitor(__u8 version, bufferlist::iterator &iter)
+    : m_version(version), m_iter(iter) {}
+
+  template <typename P>
+  inline void operator()(P &payload) const {
+    payload.decode(m_version, m_iter);
+  }
+
+private:
+  __u8 m_version;
+  bufferlist::iterator &m_iter;
+};
+
+} // namespace util
+} // namespace watcher
+} // namespace librbd
+
+#endif // CEPH_LIBRBD_WATCHER_UTILS_H
index 10b0430bef4bd852a69c3dda52d131f1d0e82678..c23863dab44e4a61166619fd0581971c801f76ec 100644 (file)
@@ -1022,7 +1022,7 @@ void LeaderWatcher<I>::handle_notify(uint64_t notify_id, uint64_t handle,
   dout(20) << "notify_id=" << notify_id << ", handle=" << handle << ", "
            << "notifier_id=" << notifier_id << dendl;
 
-  Context *ctx = new librbd::watcher::C_NotifyAck(this, notify_id, handle);
+  Context *ctx = new C_NotifyAck(this, notify_id, handle);
 
   if (notifier_id == m_notifier_id) {
     dout(20) << "our own notification, ignoring" << dendl;