rbd-mirror HA: add new lock released/acquired and heartbeat messages

Fixes: http://tracker.ceph.com/issues/17018
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
This commit is contained in:
Mykola Golub 2017-01-23 15:17:54 +01:00
parent 8c991bf562
commit 16f7878517
5 changed files with 269 additions and 0 deletions

View File

@ -678,6 +678,7 @@ if(WITH_RBD)
set(DENCODER_EXTRALIBS
${DENCODER_EXTRALIBS}
cls_rbd_client
rbd_mirror_types
rbd_types
rbd_replay_types)
if(WITH_KRBD)

View File

@ -65,6 +65,13 @@
*/
#define RBD_MIRRORING "rbd_mirroring"
/**
* rbd_mirror_leader object is used for pool-level coordination
* between rbd-mirror daemons.
*/
#define RBD_MIRROR_LEADER "rbd_mirror_leader"
#define RBD_MAX_OBJ_NAME_SIZE 96
#define RBD_MAX_BLOCK_NAME_SIZE 24

View File

@ -1,3 +1,6 @@
add_library(rbd_mirror_types STATIC
leader_watcher/Types.cc)
set(rbd_mirror_internal
ClusterWatcher.cc
ImageReplayer.cc
@ -31,6 +34,7 @@ add_executable(rbd-mirror
main.cc)
target_link_libraries(rbd-mirror
rbd_mirror_internal
rbd_mirror_types
rbd_api
rbd_internal
rbd_types

View File

@ -0,0 +1,160 @@
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#include "Types.h"
#include "include/assert.h"
#include "include/stringify.h"
#include "common/Formatter.h"
namespace rbd {
namespace mirror {
namespace leader_watcher {
namespace {
class EncodePayloadVisitor : public boost::static_visitor<void> {
public:
explicit EncodePayloadVisitor(bufferlist &bl) : m_bl(bl) {}
template <typename Payload>
inline void operator()(const Payload &payload) const {
::encode(static_cast<uint32_t>(Payload::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 Payload>
inline void operator()(Payload &payload) const {
payload.decode(m_version, m_iter);
}
private:
__u8 m_version;
bufferlist::iterator &m_iter;
};
class DumpPayloadVisitor : public boost::static_visitor<void> {
public:
explicit DumpPayloadVisitor(Formatter *formatter) : m_formatter(formatter) {}
template <typename Payload>
inline void operator()(const Payload &payload) const {
NotifyOp notify_op = Payload::NOTIFY_OP;
m_formatter->dump_string("notify_op", stringify(notify_op));
payload.dump(m_formatter);
}
private:
ceph::Formatter *m_formatter;
};
} // anonymous namespace
void HeartbeatPayload::encode(bufferlist &bl) const {
}
void HeartbeatPayload::decode(__u8 version, bufferlist::iterator &iter) {
}
void HeartbeatPayload::dump(Formatter *f) const {
}
void LockAcquiredPayload::encode(bufferlist &bl) const {
}
void LockAcquiredPayload::decode(__u8 version, bufferlist::iterator &iter) {
}
void LockAcquiredPayload::dump(Formatter *f) const {
}
void LockReleasedPayload::encode(bufferlist &bl) const {
}
void LockReleasedPayload::decode(__u8 version, bufferlist::iterator &iter) {
}
void LockReleasedPayload::dump(Formatter *f) const {
}
void UnknownPayload::encode(bufferlist &bl) const {
assert(false);
}
void UnknownPayload::decode(__u8 version, bufferlist::iterator &iter) {
}
void UnknownPayload::dump(Formatter *f) const {
}
void NotifyMessage::encode(bufferlist& bl) const {
ENCODE_START(1, 1, bl);
boost::apply_visitor(EncodePayloadVisitor(bl), payload);
ENCODE_FINISH(bl);
}
void NotifyMessage::decode(bufferlist::iterator& iter) {
DECODE_START(1, iter);
uint32_t notify_op;
::decode(notify_op, iter);
// select the correct payload variant based upon the encoded op
switch (notify_op) {
case NOTIFY_OP_HEARTBEAT:
payload = HeartbeatPayload();
break;
case NOTIFY_OP_LOCK_ACQUIRED:
payload = LockAcquiredPayload();
break;
case NOTIFY_OP_LOCK_RELEASED:
payload = LockReleasedPayload();
break;
default:
payload = UnknownPayload();
break;
}
apply_visitor(DecodePayloadVisitor(struct_v, iter), payload);
DECODE_FINISH(iter);
}
void NotifyMessage::dump(Formatter *f) const {
apply_visitor(DumpPayloadVisitor(f), payload);
}
void NotifyMessage::generate_test_instances(std::list<NotifyMessage *> &o) {
o.push_back(new NotifyMessage(HeartbeatPayload()));
o.push_back(new NotifyMessage(LockAcquiredPayload()));
o.push_back(new NotifyMessage(LockReleasedPayload()));
}
std::ostream &operator<<(std::ostream &out, const NotifyOp &op) {
switch (op) {
case NOTIFY_OP_HEARTBEAT:
out << "Heartbeat";
break;
case NOTIFY_OP_LOCK_ACQUIRED:
out << "LockAcquired";
break;
case NOTIFY_OP_LOCK_RELEASED:
out << "LockReleased";
break;
default:
out << "Unknown (" << static_cast<uint32_t>(op) << ")";
break;
}
return out;
}
} // namespace leader_watcher
} // namespace mirror
} // namespace librbd

View File

@ -0,0 +1,97 @@
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#ifndef RBD_MIRROR_LEADER_WATCHER_TYPES_H
#define RBD_MIRROR_LEADER_WATCHER_TYPES_H
#include "include/int_types.h"
#include "include/buffer_fwd.h"
#include "include/encoding.h"
#include <boost/variant.hpp>
namespace ceph { class Formatter; }
namespace rbd {
namespace mirror {
namespace leader_watcher {
enum NotifyOp {
NOTIFY_OP_HEARTBEAT = 0,
NOTIFY_OP_LOCK_ACQUIRED = 1,
NOTIFY_OP_LOCK_RELEASED = 2,
};
struct HeartbeatPayload {
static const NotifyOp NOTIFY_OP = NOTIFY_OP_HEARTBEAT;
HeartbeatPayload() {
}
void encode(bufferlist &bl) const;
void decode(__u8 version, bufferlist::iterator &iter);
void dump(Formatter *f) const;
};
struct LockAcquiredPayload {
static const NotifyOp NOTIFY_OP = NOTIFY_OP_LOCK_ACQUIRED;
LockAcquiredPayload() {
}
void encode(bufferlist &bl) const;
void decode(__u8 version, bufferlist::iterator &iter);
void dump(Formatter *f) const;
};
struct LockReleasedPayload {
static const NotifyOp NOTIFY_OP = NOTIFY_OP_LOCK_RELEASED;
LockReleasedPayload() {
}
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<NotifyOp>(-1);
UnknownPayload() {
}
void encode(bufferlist &bl) const;
void decode(__u8 version, bufferlist::iterator &iter);
void dump(Formatter *f) const;
};
typedef boost::variant<HeartbeatPayload,
LockAcquiredPayload,
LockReleasedPayload,
UnknownPayload> Payload;
struct NotifyMessage {
NotifyMessage(const Payload &payload = UnknownPayload()) : payload(payload) {
}
Payload payload;
void encode(bufferlist& bl) const;
void decode(bufferlist::iterator& it);
void dump(Formatter *f) const;
static void generate_test_instances(std::list<NotifyMessage *> &o);
};
WRITE_CLASS_ENCODER(NotifyMessage);
std::ostream &operator<<(std::ostream &out, const NotifyOp &op);
} // namespace leader_watcher
} // namespace mirror
} // namespace librbd
using rbd::mirror::leader_watcher::encode;
using rbd::mirror::leader_watcher::decode;
#endif // RBD_MIRROR_LEADER_WATCHER_TYPES_H