add_library(rbd_types STATIC
journal/Types.cc
mirroring_watcher/Types.cc
+ watcher/Types.cc
WatchNotifyTypes.cc)
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)
#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"
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;
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);
};
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;
};
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;
#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
using namespace mirroring_watcher;
using namespace watcher;
+using librbd::util::create_rados_callback;
+
namespace {
static const uint64_t NOTIFY_TIMEOUT_MS = 5000;
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);
::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);
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>
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);
// 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 {
} // 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);
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);
}
break;
}
- apply_visitor(watcher::DecodePayloadVisitor(struct_v, iter), payload);
+ apply_visitor(watcher::util::DecodePayloadVisitor(struct_v, iter), payload);
DECODE_FINISH(iter);
}
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 << ","
#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>
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;
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);
#include <boost/bind.hpp>
#define dout_subsys ceph_subsys_rbd
-#undef dout_prefix
-#define dout_prefix *_dout << "librbd::Watcher: " << this << " " << __func__ \
- << ": "
namespace librbd {
} // 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),
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();
// -*- 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 {
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);
}
break;
}
- apply_visitor(watcher::DecodePayloadVisitor(struct_v, iter), payload);
+ apply_visitor(watcher::util::DecodePayloadVisitor(struct_v, iter), payload);
DECODE_FINISH(iter);
}
// 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;
+}
#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 {
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>
} // 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
--- /dev/null
+// -*- 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
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;