From: Jason Dillaman Date: Thu, 5 Oct 2017 20:38:32 +0000 (-0400) Subject: rbd-mirror: removed duplicate client registration logic X-Git-Tag: v13.0.1~620^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d774d4702fbb9ff0b88797392b6673964d6b8c7c;p=ceph.git rbd-mirror: removed duplicate client registration logic The client will now be registered before the bootstrap state machine is invoked. Fixes: http://tracker.ceph.com/issues/21561 Signed-off-by: Jason Dillaman --- 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 4dff2f0a2c6c..3d4c16a820d5 100644 --- a/src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc +++ b/src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc @@ -448,6 +448,8 @@ public: const std::string &global_image_id, const std::string &local_mirror_uuid, const std::string &remote_mirror_uuid, + cls::journal::ClientState *client_state, + librbd::journal::MirrorPeerClientMeta *mirror_peer_client_meta, Context *on_finish) { return new MockBootstrapRequest(m_local_io_ctx, m_remote_io_ctx, @@ -462,14 +464,13 @@ public: local_mirror_uuid, remote_mirror_uuid, &mock_journaler, - &m_mirror_peer_client_meta, + client_state, mirror_peer_client_meta, on_finish, &m_do_resync); } librbd::ImageCtx *m_remote_image_ctx; librbd::ImageCtx *m_local_image_ctx = nullptr; librbd::MockTestImageCtx *m_local_test_image_ctx = nullptr; - librbd::journal::MirrorPeerClientMeta m_mirror_peer_client_meta; bool m_do_resync; }; @@ -495,22 +496,14 @@ TEST_F(TestMockImageReplayerBootstrapRequest, NonPrimaryRemoteSyncingState) { expect_open_image(mock_open_image_request, m_remote_io_ctx, mock_remote_image_ctx.id, mock_remote_image_ctx, 0); - // lookup local peer in remote journal - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{ - mock_local_image_ctx.id}; - mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_SYNCING; - client_data.client_meta = mirror_peer_client_meta; - client.data.clear(); - ::encode(client_data, client.data); - expect_journaler_get_client(mock_journaler, "local mirror uuid", - client, 0); - // test if remote image is primary MockIsPrimaryRequest mock_is_primary_request; expect_is_primary(mock_is_primary_request, false, 0); // switch the state to replaying + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); + librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{ + mock_local_image_ctx.id}; mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; client_data.client_meta = mirror_peer_client_meta; expect_journaler_update_client(mock_journaler, client_data, 0); @@ -520,10 +513,12 @@ TEST_F(TestMockImageReplayerBootstrapRequest, NonPrimaryRemoteSyncingState) { C_SaferCond ctx; MockInstanceWatcher mock_instance_watcher; + cls::journal::ClientState client_state = cls::journal::CLIENT_STATE_CONNECTED; + mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_SYNCING; MockBootstrapRequest *request = create_request( &mock_instance_watcher, mock_journaler, mock_local_image_ctx.id, mock_remote_image_ctx.id, "global image id", "local mirror uuid", - "remote mirror uuid", &ctx); + "remote mirror uuid", &client_state, &mirror_peer_client_meta, &ctx); request->send(); ASSERT_EQ(-EREMOTEIO, ctx.wait()); } @@ -550,22 +545,12 @@ TEST_F(TestMockImageReplayerBootstrapRequest, RemoteDemotePromote) { expect_open_image(mock_open_image_request, m_remote_io_ctx, mock_remote_image_ctx.id, mock_remote_image_ctx, 0); - // lookup local peer in remote journal - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{ - mock_local_image_ctx.id}; - mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; - client_data.client_meta = mirror_peer_client_meta; - client.data.clear(); - ::encode(client_data, client.data); - expect_journaler_get_client(mock_journaler, "local mirror uuid", - client, 0); - // test if remote image is primary MockIsPrimaryRequest mock_is_primary_request; expect_is_primary(mock_is_primary_request, true, 0); // open the local image + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); mock_local_image_ctx.journal = &mock_journal; MockOpenLocalImageRequest mock_open_local_image_request; expect_open_local_image(mock_open_local_image_request, m_local_io_ctx, @@ -596,10 +581,14 @@ TEST_F(TestMockImageReplayerBootstrapRequest, RemoteDemotePromote) { C_SaferCond ctx; MockInstanceWatcher mock_instance_watcher; + cls::journal::ClientState client_state = cls::journal::CLIENT_STATE_CONNECTED; + librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{ + mock_local_image_ctx.id}; + mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; MockBootstrapRequest *request = create_request( &mock_instance_watcher, mock_journaler, mock_local_image_ctx.id, mock_remote_image_ctx.id, "global image id", "local mirror uuid", - "remote mirror uuid", &ctx); + "remote mirror uuid", &client_state, &mirror_peer_client_meta, &ctx); request->send(); ASSERT_EQ(0, ctx.wait()); } @@ -626,22 +615,12 @@ TEST_F(TestMockImageReplayerBootstrapRequest, MultipleRemoteDemotePromotes) { expect_open_image(mock_open_image_request, m_remote_io_ctx, mock_remote_image_ctx.id, mock_remote_image_ctx, 0); - // lookup local peer in remote journal - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{ - mock_local_image_ctx.id}; - mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; - client_data.client_meta = mirror_peer_client_meta; - client.data.clear(); - ::encode(client_data, client.data); - expect_journaler_get_client(mock_journaler, "local mirror uuid", - client, 0); - // test if remote image is primary MockIsPrimaryRequest mock_is_primary_request; expect_is_primary(mock_is_primary_request, true, 0); // open the local image + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); mock_local_image_ctx.journal = &mock_journal; MockOpenLocalImageRequest mock_open_local_image_request; expect_open_local_image(mock_open_local_image_request, m_local_io_ctx, @@ -682,10 +661,14 @@ TEST_F(TestMockImageReplayerBootstrapRequest, MultipleRemoteDemotePromotes) { C_SaferCond ctx; MockInstanceWatcher mock_instance_watcher; + cls::journal::ClientState client_state = cls::journal::CLIENT_STATE_CONNECTED; + librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{ + mock_local_image_ctx.id}; + mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; MockBootstrapRequest *request = create_request( &mock_instance_watcher, mock_journaler, mock_local_image_ctx.id, mock_remote_image_ctx.id, "global image id", "local mirror uuid", - "remote mirror uuid", &ctx); + "remote mirror uuid", &client_state, &mirror_peer_client_meta, &ctx); request->send(); ASSERT_EQ(0, ctx.wait()); } @@ -712,22 +695,12 @@ TEST_F(TestMockImageReplayerBootstrapRequest, LocalDemoteRemotePromote) { expect_open_image(mock_open_image_request, m_remote_io_ctx, mock_remote_image_ctx.id, mock_remote_image_ctx, 0); - // lookup local peer in remote journal - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{ - mock_local_image_ctx.id}; - mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; - client_data.client_meta = mirror_peer_client_meta; - client.data.clear(); - ::encode(client_data, client.data); - expect_journaler_get_client(mock_journaler, "local mirror uuid", - client, 0); - // test if remote image is primary MockIsPrimaryRequest mock_is_primary_request; expect_is_primary(mock_is_primary_request, true, 0); // open the local image + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); mock_local_image_ctx.journal = &mock_journal; MockOpenLocalImageRequest mock_open_local_image_request; expect_open_local_image(mock_open_local_image_request, m_local_io_ctx, @@ -756,10 +729,14 @@ TEST_F(TestMockImageReplayerBootstrapRequest, LocalDemoteRemotePromote) { C_SaferCond ctx; MockInstanceWatcher mock_instance_watcher; + cls::journal::ClientState client_state = cls::journal::CLIENT_STATE_CONNECTED; + librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{ + mock_local_image_ctx.id}; + mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; MockBootstrapRequest *request = create_request( &mock_instance_watcher, mock_journaler, mock_local_image_ctx.id, mock_remote_image_ctx.id, "global image id", "local mirror uuid", - "remote mirror uuid", &ctx); + "remote mirror uuid", &client_state, &mirror_peer_client_meta, &ctx); request->send(); ASSERT_EQ(0, ctx.wait()); } @@ -786,22 +763,12 @@ TEST_F(TestMockImageReplayerBootstrapRequest, SplitBrainForcePromote) { expect_open_image(mock_open_image_request, m_remote_io_ctx, mock_remote_image_ctx.id, mock_remote_image_ctx, 0); - // lookup local peer in remote journal - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{ - mock_local_image_ctx.id}; - mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; - client_data.client_meta = mirror_peer_client_meta; - client.data.clear(); - ::encode(client_data, client.data); - expect_journaler_get_client(mock_journaler, "local mirror uuid", - client, 0); - // test if remote image is primary MockIsPrimaryRequest mock_is_primary_request; expect_is_primary(mock_is_primary_request, true, 0); // open the local image + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); mock_local_image_ctx.journal = &mock_journal; MockOpenLocalImageRequest mock_open_local_image_request; expect_open_local_image(mock_open_local_image_request, m_local_io_ctx, @@ -829,10 +796,14 @@ TEST_F(TestMockImageReplayerBootstrapRequest, SplitBrainForcePromote) { C_SaferCond ctx; MockInstanceWatcher mock_instance_watcher; + cls::journal::ClientState client_state = cls::journal::CLIENT_STATE_CONNECTED; + librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{ + mock_local_image_ctx.id}; + mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; MockBootstrapRequest *request = create_request( &mock_instance_watcher, mock_journaler, mock_local_image_ctx.id, mock_remote_image_ctx.id, "global image id", "local mirror uuid", - "remote mirror uuid", &ctx); + "remote mirror uuid", &client_state, &mirror_peer_client_meta, &ctx); request->send(); ASSERT_EQ(-EEXIST, ctx.wait()); ASSERT_EQ(NULL, m_local_test_image_ctx); @@ -860,22 +831,12 @@ TEST_F(TestMockImageReplayerBootstrapRequest, ResyncRequested) { expect_open_image(mock_open_image_request, m_remote_io_ctx, mock_remote_image_ctx.id, mock_remote_image_ctx, 0); - // lookup local peer in remote journal - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{ - mock_local_image_ctx.id}; - mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; - client_data.client_meta = mirror_peer_client_meta; - client.data.clear(); - ::encode(client_data, client.data); - expect_journaler_get_client(mock_journaler, "local mirror uuid", - client, 0); - // test if remote image is primary MockIsPrimaryRequest mock_is_primary_request; expect_is_primary(mock_is_primary_request, true, 0); // open the local image + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); mock_local_image_ctx.journal = &mock_journal; MockOpenLocalImageRequest mock_open_local_image_request; expect_open_local_image(mock_open_local_image_request, m_local_io_ctx, @@ -890,10 +851,14 @@ TEST_F(TestMockImageReplayerBootstrapRequest, ResyncRequested) { C_SaferCond ctx; MockInstanceWatcher mock_instance_watcher; + cls::journal::ClientState client_state = cls::journal::CLIENT_STATE_CONNECTED; + librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{ + mock_local_image_ctx.id}; + mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; MockBootstrapRequest *request = create_request( &mock_instance_watcher, mock_journaler, mock_local_image_ctx.id, mock_remote_image_ctx.id, "global image id", "local mirror uuid", - "remote mirror uuid", &ctx); + "remote mirror uuid", &client_state, &mirror_peer_client_meta, &ctx); m_do_resync = false; request->send(); ASSERT_EQ(0, ctx.wait()); @@ -922,17 +887,6 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemote) { expect_open_image(mock_open_image_request, m_remote_io_ctx, mock_remote_image_ctx.id, mock_remote_image_ctx, 0); - // lookup local peer in remote journal - client = {}; - expect_journaler_get_client(mock_journaler, "local mirror uuid", - client, -ENOENT); - - // 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); - // test if remote image is primary MockIsPrimaryRequest mock_is_primary_request; expect_is_primary(mock_is_primary_request, true, 0); @@ -942,7 +896,8 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemote) { mock_local_image_ctx.journal = &mock_journal; librbd::util::s_image_id = mock_local_image_ctx.id; - mirror_peer_client_meta = {mock_local_image_ctx.id}; + librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta; + mirror_peer_client_meta.image_id = mock_local_image_ctx.id; mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_SYNCING; client_data.client_meta = mirror_peer_client_meta; client.data.clear(); @@ -968,10 +923,13 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemote) { C_SaferCond ctx; MockInstanceWatcher mock_instance_watcher; + cls::journal::ClientState client_state = cls::journal::CLIENT_STATE_CONNECTED; + mirror_peer_client_meta.image_id = ""; + mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; MockBootstrapRequest *request = create_request( &mock_instance_watcher, mock_journaler, "", mock_remote_image_ctx.id, "global image id", "local mirror uuid", - "remote mirror uuid", &ctx); + "remote mirror uuid", &client_state, &mirror_peer_client_meta, &ctx); request->send(); ASSERT_EQ(0, ctx.wait()); } @@ -998,16 +956,6 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemoteLocalDeleted) { expect_open_image(mock_open_image_request, m_remote_io_ctx, mock_remote_image_ctx.id, mock_remote_image_ctx, 0); - // lookup local peer in remote journal - librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{ - "missing image id"}; - mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; - client_data.client_meta = mirror_peer_client_meta; - client.data.clear(); - ::encode(client_data, client.data); - expect_journaler_get_client(mock_journaler, "local mirror uuid", - client, 0); - // test if remote image is primary MockIsPrimaryRequest mock_is_primary_request; expect_is_primary(mock_is_primary_request, true, 0); @@ -1019,7 +967,8 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemoteLocalDeleted) { // re-register the client expect_journaler_unregister_client(mock_journaler, 0); - mirror_peer_client_meta = {}; + librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta; + mirror_peer_client_meta.image_id = ""; 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); @@ -1032,7 +981,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemoteLocalDeleted) { mock_local_image_ctx.journal = &mock_journal; librbd::util::s_image_id = mock_local_image_ctx.id; - mirror_peer_client_meta = {mock_local_image_ctx.id}; + mirror_peer_client_meta.image_id = mock_local_image_ctx.id; mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_SYNCING; client_data.client_meta = mirror_peer_client_meta; client.data.clear(); @@ -1057,10 +1006,13 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemoteLocalDeleted) { C_SaferCond ctx; MockInstanceWatcher mock_instance_watcher; + cls::journal::ClientState client_state = cls::journal::CLIENT_STATE_CONNECTED; + mirror_peer_client_meta.image_id = "missing image id"; + mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; MockBootstrapRequest *request = create_request( - &mock_instance_watcher, mock_journaler, "", + &mock_instance_watcher, mock_journaler, "missing image id", mock_remote_image_ctx.id, "global image id", "local mirror uuid", - "remote mirror uuid", &ctx); + "remote mirror uuid", &client_state, &mirror_peer_client_meta, &ctx); request->send(); ASSERT_EQ(0, ctx.wait()); } diff --git a/src/test/rbd_mirror/test_mock_ImageReplayer.cc b/src/test/rbd_mirror/test_mock_ImageReplayer.cc index f79dcef00fa4..e63c7338a39d 100644 --- a/src/test/rbd_mirror/test_mock_ImageReplayer.cc +++ b/src/test/rbd_mirror/test_mock_ImageReplayer.cc @@ -191,6 +191,7 @@ struct BootstrapRequest { const std::string &local_mirror_uuid, const std::string &remote_mirror_uuid, ::journal::MockJournalerProxy *journaler, + cls::journal::ClientState *client_state, librbd::journal::MirrorPeerClientMeta *client_meta, Context *on_finish, bool *do_resync, rbd::mirror::ProgressContext *progress_ctx = nullptr) { diff --git a/src/tools/rbd_mirror/ImageReplayer.cc b/src/tools/rbd_mirror/ImageReplayer.cc index 8b4c6c91c04b..ddf3b5a3cea7 100644 --- a/src/tools/rbd_mirror/ImageReplayer.cc +++ b/src/tools/rbd_mirror/ImageReplayer.cc @@ -522,8 +522,8 @@ void ImageReplayer::bootstrap() { &m_local_image_ctx, m_local_image_id, m_remote_image.image_id, m_global_image_id, m_threads->work_queue, m_threads->timer, &m_threads->timer_lock, m_local_mirror_uuid, m_remote_image.mirror_uuid, - m_remote_journaler, &m_client_meta, ctx, &m_resync_requested, - &m_progress_cxt); + m_remote_journaler, &m_client_state, &m_client_meta, ctx, + &m_resync_requested, &m_progress_cxt); { Mutex::Locker locker(m_lock); diff --git a/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc b/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc index 1c521b274ac8..2c24ef1f7d5e 100644 --- a/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc +++ b/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc @@ -51,6 +51,7 @@ BootstrapRequest::BootstrapRequest( const std::string &local_mirror_uuid, const std::string &remote_mirror_uuid, Journaler *journaler, + cls::journal::ClientState *client_state, MirrorPeerClientMeta *client_meta, Context *on_finish, bool *do_resync, @@ -64,8 +65,8 @@ BootstrapRequest::BootstrapRequest( m_timer(timer), m_timer_lock(timer_lock), m_local_mirror_uuid(local_mirror_uuid), m_remote_mirror_uuid(remote_mirror_uuid), m_journaler(journaler), - m_client_meta(client_meta), m_progress_ctx(progress_ctx), - m_do_resync(do_resync), + m_client_state(client_state), m_client_meta(client_meta), + m_progress_ctx(progress_ctx), m_do_resync(do_resync), m_lock(unique_lock_name("BootstrapRequest::m_lock", this)) { } @@ -172,77 +173,6 @@ void BootstrapRequest::handle_open_remote_image(int r) { return; } - get_client(); -} - -template -void BootstrapRequest::get_client() { - dout(20) << dendl; - - update_progress("GET_CLIENT"); - - Context *ctx = create_context_callback< - BootstrapRequest, &BootstrapRequest::handle_get_client>( - this); - m_journaler->get_client(m_local_mirror_uuid, &m_client, ctx); -} - -template -void BootstrapRequest::handle_get_client(int r) { - dout(20) << ": r=" << r << dendl; - - if (r == -ENOENT) { - dout(10) << ": client not registered" << dendl; - } else if (r < 0) { - derr << ": failed to retrieve client: " << cpp_strerror(r) << dendl; - m_ret_val = r; - close_remote_image(); - return; - } else if (decode_client_meta()) { - // skip registration if it already exists - is_primary(); - return; - } - - register_client(); -} - -template -void BootstrapRequest::register_client() { - dout(20) << dendl; - - update_progress("REGISTER_CLIENT"); - - 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); - - Context *ctx = create_context_callback< - BootstrapRequest, &BootstrapRequest::handle_register_client>( - this); - m_journaler->register_client(client_data_bl, ctx); -} - -template -void BootstrapRequest::handle_register_client(int r) { - dout(20) << ": r=" << r << dendl; - - if (r < 0) { - derr << ": failed to register with remote journal: " << cpp_strerror(r) - << dendl; - m_ret_val = r; - close_remote_image(); - return; - } - - m_client = {}; - *m_client_meta = librbd::journal::MirrorPeerClientMeta(m_local_image_id); - m_client_meta->state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; - is_primary(); } @@ -280,6 +210,12 @@ void BootstrapRequest::handle_is_primary(int r) { return; } + if (!m_client_meta->image_id.empty()) { + // have an image id -- use that to open the image since a deletion (resync) + // will leave the old image id registered in the peer + m_local_image_id = m_client_meta->image_id; + } + if (m_local_image_id.empty()) { update_client_image(); return; @@ -386,7 +322,7 @@ void BootstrapRequest::handle_open_local_image(int r) { return; } - if (m_client.state == cls::journal::CLIENT_STATE_DISCONNECTED) { + if (*m_client_state == cls::journal::CLIENT_STATE_DISCONNECTED) { dout(10) << ": client flagged disconnected -- skipping bootstrap" << dendl; // The caller is expected to detect disconnect initializing remote journal. m_ret_val = 0; @@ -424,6 +360,45 @@ void BootstrapRequest::handle_unregister_client(int r) { register_client(); } +template +void BootstrapRequest::register_client() { + dout(20) << dendl; + + update_progress("REGISTER_CLIENT"); + + 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); + + Context *ctx = create_context_callback< + BootstrapRequest, &BootstrapRequest::handle_register_client>( + this); + m_journaler->register_client(client_data_bl, ctx); +} + +template +void BootstrapRequest::handle_register_client(int r) { + dout(20) << ": r=" << r << dendl; + + if (r < 0) { + derr << ": failed to register with remote journal: " << cpp_strerror(r) + << dendl; + m_ret_val = r; + close_remote_image(); + return; + } + + *m_client_state = cls::journal::CLIENT_STATE_CONNECTED; + *m_client_meta = librbd::journal::MirrorPeerClientMeta(m_local_image_id); + m_client_meta->state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; + + is_primary(); +} + template void BootstrapRequest::update_client_image() { dout(20) << dendl; @@ -769,36 +744,6 @@ void BootstrapRequest::handle_close_remote_image(int r) { finish(m_ret_val); } -template -bool BootstrapRequest::decode_client_meta() { - dout(20) << dendl; - - librbd::journal::ClientData client_data; - bufferlist::iterator it = m_client.data.begin(); - try { - ::decode(client_data, it); - } catch (const buffer::error &err) { - derr << ": failed to decode client meta data: " << err.what() << dendl; - return false; - } - - librbd::journal::MirrorPeerClientMeta *client_meta = - boost::get(&client_data.client_meta); - if (client_meta == nullptr) { - derr << ": unknown peer registration" << dendl; - return false; - } else if (!client_meta->image_id.empty()) { - // have an image id -- use that to open the image - m_local_image_id = client_meta->image_id; - } - - *m_client_meta = *client_meta; - - dout(20) << ": client found: image_id=" << m_local_image_id - << ", client_meta=" << *m_client_meta << dendl; - return true; -} - template void BootstrapRequest::update_progress(const std::string &description) { dout(20) << ": " << description << dendl; diff --git a/src/tools/rbd_mirror/image_replayer/BootstrapRequest.h b/src/tools/rbd_mirror/image_replayer/BootstrapRequest.h index 6c67222d4abd..8a46e7038d6d 100644 --- a/src/tools/rbd_mirror/image_replayer/BootstrapRequest.h +++ b/src/tools/rbd_mirror/image_replayer/BootstrapRequest.h @@ -53,6 +53,7 @@ public: const std::string &local_mirror_uuid, const std::string &remote_mirror_uuid, Journaler *journaler, + cls::journal::ClientState *client_state, MirrorPeerClientMeta *client_meta, Context *on_finish, bool *do_resync, @@ -62,8 +63,8 @@ public: local_image_id, remote_image_id, global_image_id, work_queue, timer, timer_lock, local_mirror_uuid, remote_mirror_uuid, - journaler, client_meta, on_finish, do_resync, - progress_ctx); + journaler, client_state, client_meta, on_finish, + do_resync, progress_ctx); } BootstrapRequest(librados::IoCtx &local_io_ctx, @@ -76,6 +77,7 @@ public: SafeTimer *timer, Mutex *timer_lock, const std::string &local_mirror_uuid, const std::string &remote_mirror_uuid, Journaler *journaler, + cls::journal::ClientState *client_state, MirrorPeerClientMeta *client_meta, Context *on_finish, bool *do_resync, ProgressContext *progress_ctx = nullptr); ~BootstrapRequest() override; @@ -97,14 +99,8 @@ private: * v * * OPEN_REMOTE_IMAGE * * * * * * * * * * * * * * * * * * * * | * - * v * - * GET_CLIENT * * * * * * * * * * * * * * * * * * * * * * - * | * * - * |/----------------------------------------------*---*---\ - * v (skip if not needed) * * | - * REGISTER_CLIENT * * * * * * * * * * * * * * * * * * * | - * | * * | - * v * * | + * |/--------------------------------------------------*---\ + * v * | * IS_PRIMARY * * * * * * * * * * * * * * * * * * * * * * | * | * * | * | (remote image primary, no local image id) * * | @@ -120,6 +116,9 @@ private: * | | . (image doesn't exist) * * | * | | . . > UNREGISTER_CLIENT * * * * * * * | * | | | * * | + * | | v * * | + * | | REGISTER_CLIENT * * * * * * * * | + * | | | * * | * | | \-----------------------*---*---/ * | | * * * | v (skip if not needed) * * @@ -159,6 +158,7 @@ private: std::string m_local_mirror_uuid; std::string m_remote_mirror_uuid; Journaler *m_journaler; + cls::journal::ClientState *m_client_state; MirrorPeerClientMeta *m_client_meta; ProgressContext *m_progress_ctx; bool *m_do_resync; @@ -179,12 +179,6 @@ private: void get_remote_tag_class(); void handle_get_remote_tag_class(int r); - void get_client(); - void handle_get_client(int r); - - void register_client(); - void handle_register_client(int r); - void open_remote_image(); void handle_open_remote_image(int r); @@ -200,6 +194,9 @@ private: void unregister_client(); void handle_unregister_client(int r); + void register_client(); + void handle_register_client(int r); + void create_local_image(); void handle_create_local_image(int r); @@ -218,8 +215,6 @@ private: void close_remote_image(); void handle_close_remote_image(int r); - bool decode_client_meta(); - void update_progress(const std::string &description); };