From bc96c53d947625d12f7b30a45da68a96c09faf70 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Tue, 26 Sep 2017 15:46:28 -0400 Subject: [PATCH] rbd-mirror: ensure forced-failover cannot result in sync state If the local image already exists and the local image isn't registered in the remote journal, it should be assumed that it's already in the replaying state so it can verify the ancestry to detect split-brains. Fixes: http://tracker.ceph.com/issues/21559 Signed-off-by: Jason Dillaman --- .../image_replayer/test_mock_BootstrapRequest.cc | 2 ++ .../rbd_mirror/image_replayer/BootstrapRequest.cc | 15 ++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc b/src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc index c372a4b9fc397..4dff2f0a2c6c2 100644 --- a/src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc +++ b/src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc @@ -929,6 +929,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemote) { // register missing client in remote journal librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta; + mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; client_data.client_meta = mirror_peer_client_meta; expect_journaler_register_client(mock_journaler, client_data, 0); @@ -1019,6 +1020,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemoteLocalDeleted) { // re-register the client expect_journaler_unregister_client(mock_journaler, 0); mirror_peer_client_meta = {}; + mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; client_data.client_meta = mirror_peer_client_meta; expect_journaler_register_client(mock_journaler, client_data, 0); diff --git a/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc b/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc index 1b2359a7df031..1c521b274ac81 100644 --- a/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc +++ b/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc @@ -213,9 +213,11 @@ void BootstrapRequest::register_client() { update_progress("REGISTER_CLIENT"); - // record an place-holder record - librbd::journal::ClientData client_data{ - librbd::journal::MirrorPeerClientMeta{m_local_image_id}}; + librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{ + m_local_image_id}; + mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; + + librbd::journal::ClientData client_data{mirror_peer_client_meta}; bufferlist client_data_bl; ::encode(client_data, client_data_bl); @@ -239,6 +241,8 @@ void BootstrapRequest::handle_register_client(int r) { m_client = {}; *m_client_meta = librbd::journal::MirrorPeerClientMeta(m_local_image_id); + m_client_meta->state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; + is_primary(); } @@ -498,10 +502,6 @@ void BootstrapRequest::handle_create_local_image(int r) { template void BootstrapRequest::get_remote_tags() { - dout(20) << dendl; - - update_progress("GET_REMOTE_TAGS"); - if (m_client_meta->state == librbd::journal::MIRROR_PEER_STATE_SYNCING) { // optimization -- no need to compare remote tags if we just created // the image locally or sync was interrupted @@ -510,6 +510,7 @@ void BootstrapRequest::get_remote_tags() { } dout(20) << dendl; + update_progress("GET_REMOTE_TAGS"); Context *ctx = create_context_callback< BootstrapRequest, &BootstrapRequest::handle_get_remote_tags>(this); -- 2.39.5