m_global_image_id, m_threads.get(),
m_instance_watcher, m_local_status_updater,
nullptr);
- m_replayer->add_peer("peer uuid", m_remote_ioctx);
+ m_replayer->add_peer("peer uuid", m_remote_ioctx, nullptr);
}
void start()
void expect_set_mirror_image_status_repeatedly() {
EXPECT_CALL(m_local_status_updater, set_mirror_image_status(_, _, _))
.WillRepeatedly(Invoke([](auto, auto, auto){}));
+ EXPECT_CALL(m_remote_status_updater, set_mirror_image_status(_, _, _))
+ .WillRepeatedly(Invoke([](auto, auto, auto){}));
}
void expect_mirror_image_status_exists(bool exists) {
EXPECT_CALL(m_local_status_updater, exists(_))
.WillOnce(Return(exists));
+ EXPECT_CALL(m_remote_status_updater, exists(_))
+ .WillOnce(Return(exists));
}
void create_image_replayer(MockThreads &mock_threads) {
m_image_replayer = new MockImageReplayer(
m_local_io_ctx, "local_mirror_uuid", "global image id",
&mock_threads, &m_instance_watcher, &m_local_status_updater, nullptr);
- m_image_replayer->add_peer("peer_uuid", m_remote_io_ctx);
+ m_image_replayer->add_peer("peer_uuid", m_remote_io_ctx,
+ &m_remote_status_updater);
}
librbd::ImageCtx *m_remote_image_ctx;
librbd::ImageCtx *m_local_image_ctx = nullptr;
MockInstanceWatcher m_instance_watcher;
MockMirrorStatusUpdater m_local_status_updater;
+ MockMirrorStatusUpdater m_remote_status_updater;
MockImageReplayer *m_image_replayer = nullptr;
};
MockPrepareLocalImageRequest mock_prepare_local_image_request;
MockReplayStatusFormatter mock_replay_status_formatter;
- expect_set_mirror_image_status_repeatedly();
+ EXPECT_CALL(m_local_status_updater, set_mirror_image_status(_, _, _))
+ .WillRepeatedly(Invoke([](auto, auto, auto){}));
expect_get_or_send_update(mock_replay_status_formatter);
InSequence seq;
expect_send(mock_prepare_local_image_request, mock_local_image_ctx.id,
mock_local_image_ctx.name, "remote mirror uuid", -EINVAL);
- expect_mirror_image_status_exists(false);
+ EXPECT_CALL(m_local_status_updater, exists(_))
+ .WillOnce(Return(false));
create_image_replayer(mock_threads);
MOCK_METHOD0(restart, void());
MOCK_METHOD0(flush, void());
MOCK_METHOD1(print_status, void(Formatter *));
- MOCK_METHOD2(add_peer, void(const std::string &, librados::IoCtx &));
+ MOCK_METHOD3(add_peer, void(const std::string &, librados::IoCtx &,
+ MirrorStatusUpdater<librbd::MockTestImageCtx>*));
MOCK_METHOD0(get_global_image_id, const std::string &());
MOCK_METHOD0(get_local_image_id, const std::string &());
MOCK_METHOD0(is_running, bool());
Context *timer_ctx = nullptr;
expect_add_event_after(mock_threads, &timer_ctx);
instance_replayer.init();
- instance_replayer.add_peer("peer_uuid", m_remote_io_ctx);
+ instance_replayer.add_peer("peer_uuid", m_remote_io_ctx, nullptr);
// Acquire
C_SaferCond on_acquire;
- EXPECT_CALL(mock_image_replayer, add_peer("peer_uuid", _));
+ EXPECT_CALL(mock_image_replayer, add_peer("peer_uuid", _, _));
EXPECT_CALL(mock_image_replayer, is_stopped()).WillOnce(Return(true));
EXPECT_CALL(mock_image_replayer, is_blacklisted()).WillOnce(Return(false));
EXPECT_CALL(mock_image_replayer, is_finished()).WillOnce(Return(false));
Context *timer_ctx1 = nullptr;
expect_add_event_after(mock_threads, &timer_ctx1);
instance_replayer.init();
- instance_replayer.add_peer("peer_uuid", m_remote_io_ctx);
+ instance_replayer.add_peer("peer_uuid", m_remote_io_ctx, nullptr);
// Acquire
C_SaferCond on_acquire;
- EXPECT_CALL(mock_image_replayer, add_peer("peer_uuid", _));
+ EXPECT_CALL(mock_image_replayer, add_peer("peer_uuid", _, _));
EXPECT_CALL(mock_image_replayer, is_stopped()).WillOnce(Return(true));
EXPECT_CALL(mock_image_replayer, is_blacklisted()).WillOnce(Return(false));
EXPECT_CALL(mock_image_replayer, is_finished()).WillOnce(Return(false));
Context *timer_ctx = nullptr;
expect_add_event_after(mock_threads, &timer_ctx);
instance_replayer.init();
- instance_replayer.add_peer("peer_uuid", m_remote_io_ctx);
+ instance_replayer.add_peer("peer_uuid", m_remote_io_ctx, nullptr);
// Acquire
- EXPECT_CALL(mock_image_replayer, add_peer("peer_uuid", _));
+ EXPECT_CALL(mock_image_replayer, add_peer("peer_uuid", _, _));
EXPECT_CALL(mock_image_replayer, is_stopped()).WillOnce(Return(true));
EXPECT_CALL(mock_image_replayer, is_blacklisted()).WillOnce(Return(false));
EXPECT_CALL(mock_image_replayer, is_finished()).WillOnce(Return(false));
MOCK_METHOD2(print_status, void(Formatter*, std::stringstream*));
- MOCK_METHOD2(add_peer, void(const std::string&, librados::IoCtx&));
+ MOCK_METHOD3(add_peer, void(const std::string&, librados::IoCtx&,
+ MirrorStatusUpdater<librbd::MockTestImageCtx>*));
MOCK_METHOD1(init, void(Context*));
MOCK_METHOD1(shut_down, void(Context*));
void expect_instance_replayer_add_peer(
MockInstanceReplayer& mock_instance_replayer, const std::string& uuid) {
- EXPECT_CALL(mock_instance_replayer, add_peer(uuid, _));
+ EXPECT_CALL(mock_instance_replayer, add_peer(uuid, _, _));
}
void expect_instance_replayer_release_all(
}
template <typename I>
-void ImageReplayer<I>::add_peer(const std::string &peer_uuid,
- librados::IoCtx &io_ctx) {
+void ImageReplayer<I>::add_peer(
+ const std::string &peer_uuid, librados::IoCtx &io_ctx,
+ MirrorStatusUpdater<I>* remote_status_updater) {
+ dout(10) << "peer_uuid=" << &peer_uuid << ", "
+ << "remote_status_updater=" << remote_status_updater << dendl;
+
std::lock_guard locker{m_lock};
auto it = m_peers.find({peer_uuid});
if (it == m_peers.end()) {
- m_peers.insert({peer_uuid, io_ctx});
+ m_peers.insert({peer_uuid, io_ctx, remote_status_updater});
}
}
dout(15) << "status=" << status << dendl;
m_local_status_updater->set_mirror_image_status(m_global_image_id, status,
force);
+ if (m_remote_image.mirror_status_updater != nullptr) {
+ m_remote_image.mirror_status_updater->set_mirror_image_status(
+ m_global_image_id, status, force);
+ }
m_in_flight_op_tracker.finish_op();
}
return;
}
+ if (m_remote_image.mirror_status_updater != nullptr &&
+ m_remote_image.mirror_status_updater->exists(m_global_image_id)) {
+ dout(15) << "removing remote mirror image status" << dendl;
+ auto ctx = new LambdaContext([this, r](int) {
+ handle_shut_down(r);
+ });
+ m_remote_image.mirror_status_updater->remove_mirror_image_status(
+ m_global_image_id, ctx);
+ return;
+ }
+
dout(10) << "stop complete" << dendl;
ReplayStatusFormatter<I>::destroy(m_replay_status_formatter);
m_replay_status_formatter = nullptr;
image_replayer::HealthState get_health_state() const;
- void add_peer(const std::string &peer_uuid, librados::IoCtx &remote_io_ctx);
+ void add_peer(const std::string &peer_uuid, librados::IoCtx &remote_io_ctx,
+ MirrorStatusUpdater<ImageCtxT>* remote_status_updater);
inline int64_t get_local_pool_id() const {
return m_local_io_ctx.get_id();
bool on_replay_interrupted();
private:
+ typedef std::set<Peer<ImageCtxT>> Peers;
typedef typename librbd::journal::TypeTraits<ImageCtxT>::ReplayEntry ReplayEntry;
enum State {
std::string mirror_uuid;
std::string image_id;
librados::IoCtx io_ctx;
+ MirrorStatusUpdater<ImageCtxT>* mirror_status_updater = nullptr;
RemoteImage() {
}
- RemoteImage(const Peer& peer) : io_ctx(peer.io_ctx) {
+ RemoteImage(const Peer<ImageCtxT>& peer)
+ : io_ctx(peer.io_ctx), mirror_status_updater(peer.mirror_status_updater) {
}
};
}
template <typename I>
-void InstanceReplayer<I>::add_peer(std::string peer_uuid,
- librados::IoCtx io_ctx) {
+void InstanceReplayer<I>::add_peer(
+ std::string peer_uuid, librados::IoCtx io_ctx,
+ MirrorStatusUpdater<I>* remote_status_updater) {
dout(10) << peer_uuid << dendl;
std::lock_guard locker{m_lock};
- auto result = m_peers.insert(Peer(peer_uuid, io_ctx)).second;
+ auto result = m_peers.insert(
+ Peer(peer_uuid, io_ctx, remote_status_updater)).second;
ceph_assert(result);
}
// TODO only a single peer is currently supported
ceph_assert(m_peers.size() == 1);
auto peer = *m_peers.begin();
- image_replayer->add_peer(peer.peer_uuid, peer.io_ctx);
+ image_replayer->add_peer(peer.peer_uuid, peer.io_ctx,
+ peer.mirror_status_updater);
start_image_replayer(image_replayer);
} else {
// A duplicate acquire notification implies (1) connection hiccup or
void init(Context *on_finish);
void shut_down(Context *on_finish);
- void add_peer(std::string peer_uuid, librados::IoCtx io_ctx);
+ void add_peer(std::string peer_uuid, librados::IoCtx io_ctx,
+ MirrorStatusUpdater<ImageCtxT>* remote_status_updater);
void acquire_image(InstanceWatcher<ImageCtxT> *instance_watcher,
const std::string &global_image_id, Context *on_finish);
* @endverbatim
*/
+ typedef std::set<Peer<ImageCtxT>> Peers;
+
librados::IoCtx &m_local_io_ctx;
std::string m_local_mirror_uuid;
Threads<ImageCtxT> *m_threads;
return;
}
- m_instance_replayer->add_peer(m_remote_mirror_uuid, m_remote_io_ctx);
+ m_instance_replayer->add_peer(m_remote_mirror_uuid, m_remote_io_ctx,
+ m_remote_status_updater.get());
init_instance_watcher();
}
namespace rbd {
namespace mirror {
+template <typename> struct MirrorStatusUpdater;
+
// Performance counters
enum {
l_rbd_mirror_first = 27000,
typedef std::set<ImageId> ImageIds;
+template <typename I>
struct Peer {
std::string peer_uuid;
librados::IoCtx io_ctx;
+ MirrorStatusUpdater<I>* mirror_status_updater = nullptr;
Peer() {
}
Peer(const std::string &peer_uuid) : peer_uuid(peer_uuid) {
}
- Peer(const std::string &peer_uuid, librados::IoCtx& io_ctx)
- : peer_uuid(peer_uuid), io_ctx(io_ctx) {
+ Peer(const std::string &peer_uuid, librados::IoCtx& io_ctx,
+ MirrorStatusUpdater<I>* mirror_status_updater)
+ : peer_uuid(peer_uuid), io_ctx(io_ctx),
+ mirror_status_updater(mirror_status_updater) {
}
inline bool operator<(const Peer &rhs) const {
}
};
-typedef std::set<Peer> Peers;
-
struct PeerSpec {
PeerSpec() = default;
PeerSpec(const std::string &uuid, const std::string &cluster_name,