]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-mirror: removed duplicate client registration logic 18136/head
authorJason Dillaman <dillaman@redhat.com>
Thu, 5 Oct 2017 20:38:32 +0000 (16:38 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 10 Oct 2017 00:53:51 +0000 (20:53 -0400)
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 <dillaman@redhat.com>
src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc
src/test/rbd_mirror/test_mock_ImageReplayer.cc
src/tools/rbd_mirror/ImageReplayer.cc
src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc
src/tools/rbd_mirror/image_replayer/BootstrapRequest.h

index 4dff2f0a2c6c2ba051ce5c1632e45a17b01686b7..3d4c16a820d55e43d74d3952032976a87a394b4a 100644 (file)
@@ -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());
 }
index f79dcef00fa432d6414e9ff36f10f94ee1f626dd..e63c7338a39df6526597b9d486e0c70da050d382 100644 (file)
@@ -191,6 +191,7 @@ struct BootstrapRequest<librbd::MockTestImageCtx> {
       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) {
index 8b4c6c91c04b3f3f646eb974e6e2e0ca5819df03..ddf3b5a3cea71fb4377225a475ee37968041f45e 100644 (file)
@@ -522,8 +522,8 @@ void ImageReplayer<I>::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);
index 1c521b274ac813c3021231a50c2e2cc82ab0d463..2c24ef1f7d5e07e27831088f44dc3147de1a7940 100644 (file)
@@ -51,6 +51,7 @@ BootstrapRequest<I>::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<I>::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<I>::handle_open_remote_image(int r) {
     return;
   }
 
-  get_client();
-}
-
-template <typename I>
-void BootstrapRequest<I>::get_client() {
-  dout(20) << dendl;
-
-  update_progress("GET_CLIENT");
-
-  Context *ctx = create_context_callback<
-    BootstrapRequest<I>, &BootstrapRequest<I>::handle_get_client>(
-      this);
-  m_journaler->get_client(m_local_mirror_uuid, &m_client, ctx);
-}
-
-template <typename I>
-void BootstrapRequest<I>::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 <typename I>
-void BootstrapRequest<I>::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<I>, &BootstrapRequest<I>::handle_register_client>(
-      this);
-  m_journaler->register_client(client_data_bl, ctx);
-}
-
-template <typename I>
-void BootstrapRequest<I>::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<I>::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<I>::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<I>::handle_unregister_client(int r) {
   register_client();
 }
 
+template <typename I>
+void BootstrapRequest<I>::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<I>, &BootstrapRequest<I>::handle_register_client>(
+      this);
+  m_journaler->register_client(client_data_bl, ctx);
+}
+
+template <typename I>
+void BootstrapRequest<I>::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 <typename I>
 void BootstrapRequest<I>::update_client_image() {
   dout(20) << dendl;
@@ -769,36 +744,6 @@ void BootstrapRequest<I>::handle_close_remote_image(int r) {
   finish(m_ret_val);
 }
 
-template <typename I>
-bool BootstrapRequest<I>::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<librbd::journal::MirrorPeerClientMeta>(&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 <typename I>
 void BootstrapRequest<I>::update_progress(const std::string &description) {
   dout(20) << ": " << description << dendl;
index 6c67222d4abd24cf3ecb16f3a9213bccda825088..8a46e7038d6d043b53146ccd3dcfd73f36a524c1 100644 (file)
@@ -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);
 };