]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-mirror: bootstrap now uses the create local image state machine
authorJason Dillaman <dillaman@redhat.com>
Fri, 20 Dec 2019 16:28:07 +0000 (11:28 -0500)
committerJason Dillaman <dillaman@redhat.com>
Sat, 21 Dec 2019 16:29:18 +0000 (11:29 -0500)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc
src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc
src/tools/rbd_mirror/image_replayer/BootstrapRequest.h

index 45610f125b0b9b02a24029822251a401053d7286..6e5242450946719f18a504bb431e834224855814 100644 (file)
@@ -8,9 +8,9 @@
 #include "tools/rbd_mirror/Threads.h"
 #include "tools/rbd_mirror/image_replayer/BootstrapRequest.h"
 #include "tools/rbd_mirror/image_replayer/CloseImageRequest.h"
-#include "tools/rbd_mirror/image_replayer/CreateImageRequest.h"
 #include "tools/rbd_mirror/image_replayer/OpenImageRequest.h"
 #include "tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h"
+#include "tools/rbd_mirror/image_replayer/journal/CreateLocalImageRequest.h"
 #include "test/journal/mock/MockJournaler.h"
 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
 #include "test/librbd/mock/MockImageCtx.h"
@@ -71,18 +71,6 @@ struct GetInfoRequest<librbd::MockTestImageCtx> {
 GetInfoRequest<librbd::MockTestImageCtx>* GetInfoRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
 
 } // namespace mirror
-
-namespace util {
-
-static std::string s_image_id;
-
-template <>
-std::string generate_image_id<MockTestImageCtx>(librados::IoCtx&) {
-  ceph_assert(!s_image_id.empty());
-  return s_image_id;
-}
-
-} // namespace util
 } // namespace librbd
 
 namespace rbd {
@@ -170,37 +158,6 @@ struct CloseImageRequest<librbd::MockTestImageCtx> {
   MOCK_METHOD0(send, void());
 };
 
-template<>
-struct CreateImageRequest<librbd::MockTestImageCtx> {
-  static CreateImageRequest* s_instance;
-  Context *on_finish = nullptr;
-
-  static CreateImageRequest* create(Threads<librbd::MockTestImageCtx>* threads,
-                                    librados::IoCtx &local_io_ctx,
-                                    const std::string &global_image_id,
-                                    const std::string &remote_mirror_uuid,
-                                    const std::string &local_image_name,
-                                   const std::string &local_image_id,
-                                    librbd::MockTestImageCtx *remote_image_ctx,
-                                    Context *on_finish) {
-    ceph_assert(s_instance != nullptr);
-    s_instance->on_finish = on_finish;
-    s_instance->construct(local_image_id);
-    return s_instance;
-  }
-
-  CreateImageRequest() {
-    ceph_assert(s_instance == nullptr);
-    s_instance = this;
-  }
-  ~CreateImageRequest() {
-    s_instance = nullptr;
-  }
-
-  MOCK_METHOD1(construct, void(const std::string&));
-  MOCK_METHOD0(send, void());
-};
-
 template<>
 struct OpenImageRequest<librbd::MockTestImageCtx> {
   static OpenImageRequest* s_instance;
@@ -264,13 +221,53 @@ struct OpenLocalImageRequest<librbd::MockTestImageCtx> {
 
 CloseImageRequest<librbd::MockTestImageCtx>*
   CloseImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
-CreateImageRequest<librbd::MockTestImageCtx>*
-  CreateImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
 OpenImageRequest<librbd::MockTestImageCtx>*
   OpenImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
 OpenLocalImageRequest<librbd::MockTestImageCtx>*
   OpenLocalImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
 
+namespace journal {
+
+template<>
+struct CreateLocalImageRequest<librbd::MockTestImageCtx> {
+  static CreateLocalImageRequest* s_instance;
+
+  librbd::journal::MirrorPeerClientMeta* client_meta = nullptr;
+  std::string* local_image_id;
+  Context *on_finish = nullptr;
+
+  static CreateLocalImageRequest* create(
+      Threads<librbd::MockTestImageCtx>* mock_threads,
+      librados::IoCtx &local_io_ctx,
+      librbd::MockTestImageCtx* mock_remote_image_ctx,
+      ::journal::MockJournaler *mock_remote_journaler,
+      const std::string &global_image_id,
+      const std::string &remote_mirror_uuid,
+      librbd::journal::MirrorPeerClientMeta* client_meta,
+      ProgressContext* progress_ctx,
+      std::string* local_image_id, Context *on_finish) {
+    ceph_assert(s_instance != nullptr);
+    s_instance->client_meta = client_meta;
+    s_instance->local_image_id = local_image_id;
+    s_instance->on_finish = on_finish;
+    return s_instance;
+  }
+
+  CreateLocalImageRequest() {
+    ceph_assert(s_instance == nullptr);
+    s_instance = this;
+  }
+  ~CreateLocalImageRequest() {
+    s_instance = nullptr;
+  }
+
+  MOCK_METHOD0(send, void());
+};
+
+CreateLocalImageRequest<librbd::MockTestImageCtx>*
+  CreateLocalImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
+
+} // namespace journal
 } // namespace image_replayer
 } // namespace mirror
 } // namespace rbd
@@ -300,11 +297,11 @@ public:
   typedef Threads<librbd::MockTestImageCtx> MockThreads;
   typedef BootstrapRequest<librbd::MockTestImageCtx> MockBootstrapRequest;
   typedef CloseImageRequest<librbd::MockTestImageCtx> MockCloseImageRequest;
-  typedef CreateImageRequest<librbd::MockTestImageCtx> MockCreateImageRequest;
   typedef ImageSync<librbd::MockTestImageCtx> MockImageSync;
   typedef InstanceWatcher<librbd::MockTestImageCtx> MockInstanceWatcher;
   typedef OpenImageRequest<librbd::MockTestImageCtx> MockOpenImageRequest;
   typedef OpenLocalImageRequest<librbd::MockTestImageCtx> MockOpenLocalImageRequest;
+  typedef journal::CreateLocalImageRequest<librbd::MockTestImageCtx> MockCreateLocalImageRequest;
   typedef librbd::mirror::GetInfoRequest<librbd::MockTestImageCtx> MockGetMirrorInfoRequest;
   typedef std::list<cls::journal::Tag> Tags;
 
@@ -346,26 +343,6 @@ public:
                                         }))));
   }
 
-  void expect_journaler_register_client(::journal::MockJournaler &mock_journaler,
-                                        const librbd::journal::ClientData &client_data,
-                                        int r) {
-    bufferlist bl;
-    encode(client_data, bl);
-
-    EXPECT_CALL(mock_journaler, register_client(ContentsEqual(bl), _))
-      .WillOnce(WithArg<1>(Invoke([this, r](Context *on_finish) {
-                                    m_threads->work_queue->queue(on_finish, r);
-                                  })));
-  }
-
-  void expect_journaler_unregister_client(::journal::MockJournaler &mock_journaler,
-                                          int r) {
-    EXPECT_CALL(mock_journaler, unregister_client(_))
-      .WillOnce(Invoke([this, r](Context *on_finish) {
-                  m_threads->work_queue->queue(on_finish, r);
-                }));
-  }
-
   void expect_journaler_update_client(::journal::MockJournaler &mock_journaler,
                                       const librbd::journal::ClientData &client_data,
                                       int r) {
@@ -443,12 +420,21 @@ public:
                       Return(r)));
   }
 
-  void expect_create_image(MockCreateImageRequest &mock_create_image_request,
-                           const std::string &image_id, int r) {
-    EXPECT_CALL(mock_create_image_request, construct(image_id));
-    EXPECT_CALL(mock_create_image_request, send())
-      .WillOnce(Invoke([this, &mock_create_image_request, r]() {
-          m_threads->work_queue->queue(mock_create_image_request.on_finish, r);
+  void expect_create_local_image(
+      MockCreateLocalImageRequest &mock_create_local_image_request,
+      const std::string& local_image_id, int r) {
+    EXPECT_CALL(mock_create_local_image_request, send())
+      .WillOnce(Invoke([this, &mock_create_local_image_request, local_image_id,
+                        r]() {
+          if (r >= 0) {
+            mock_create_local_image_request.client_meta->state =
+              librbd::journal::MIRROR_PEER_STATE_SYNCING;
+            mock_create_local_image_request.client_meta->image_id =
+              local_image_id;
+            *mock_create_local_image_request.local_image_id = local_image_id;
+          }
+          m_threads->work_queue->queue(
+            mock_create_local_image_request.on_finish, r);
         }));
   }
 
@@ -1025,29 +1011,17 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemote) {
                                  cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
                                 librbd::mirror::PROMOTION_STATE_PRIMARY, 0);
 
-  // update client state back to syncing
-  librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
-  mock_local_image_ctx.journal = &mock_journal;
-
-  librbd::util::s_image_id = 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;
-  librbd::journal::ClientData client_data;
-  client_data.client_meta = mirror_peer_client_meta;
-  cls::journal::Client client;
-  encode(client_data, client.data);
-  ::journal::MockJournaler mock_journaler;
-  expect_journaler_update_client(mock_journaler, client_data, 0);
-
   // create the local image
-  MockCreateImageRequest mock_create_image_request;
-  expect_create_image(mock_create_image_request, mock_local_image_ctx.id, 0);
+  MockCreateLocalImageRequest mock_create_local_image_request;
+  expect_create_local_image(mock_create_local_image_request, "local image id",
+                            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,
-                          mock_local_image_ctx.id, &mock_local_image_ctx, 0);
+                          "local image id", &mock_local_image_ctx, 0);
   expect_is_resync_requested(mock_journal, false, 0);
 
   expect_journal_get_tag_tid(mock_journal, 345);
@@ -1063,7 +1037,9 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemote) {
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
   MockInstanceWatcher mock_instance_watcher;
+  ::journal::MockJournaler mock_journaler;
   cls::journal::ClientState client_state = cls::journal::CLIENT_STATE_CONNECTED;
+  librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta;
   mirror_peer_client_meta.image_id = "";
   mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
   MockBootstrapRequest *request = create_request(
@@ -1098,41 +1074,16 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemoteLocalDeleted) {
   expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
                           "missing image id", nullptr, -ENOENT);
 
-  // re-register the client
-  ::journal::MockJournaler mock_journaler;
-  expect_journaler_unregister_client(mock_journaler, 0);
-  librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta;
-  mirror_peer_client_meta.image_id = "";
-  mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
-  librbd::journal::ClientData client_data;
-  client_data.client_meta = mirror_peer_client_meta;
-  expect_journaler_register_client(mock_journaler, client_data, 0);
-
-  // test if remote image is primary
-  expect_get_remote_mirror_info(mock_get_mirror_info_request,
-                                {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL, "uuid",
-                                 cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
-                                librbd::mirror::PROMOTION_STATE_PRIMARY, 0);
-
-  // update client state back to syncing
-  librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
-  mock_local_image_ctx.journal = &mock_journal;
-
-  librbd::util::s_image_id = 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;
-  cls::journal::Client client;
-  encode(client_data, client.data);
-  expect_journaler_update_client(mock_journaler, client_data, 0);
-
   // create the missing local image
-  MockCreateImageRequest mock_create_image_request;
-  expect_create_image(mock_create_image_request, mock_local_image_ctx.id, 0);
+  MockCreateLocalImageRequest mock_create_local_image_request;
+  expect_create_local_image(mock_create_local_image_request, "local image id",
+                            0);
 
   // open the local image
+  librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  mock_local_image_ctx.journal = &mock_journal;
   expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
-                          mock_local_image_ctx.id, &mock_local_image_ctx, 0);
+                          "local image id", &mock_local_image_ctx, 0);
   expect_is_resync_requested(mock_journal, false, 0);
 
   expect_journal_get_tag_tid(mock_journal, 345);
@@ -1148,7 +1099,9 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemoteLocalDeleted) {
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
   MockInstanceWatcher mock_instance_watcher;
+  ::journal::MockJournaler mock_journaler;
   cls::journal::ClientState client_state = cls::journal::CLIENT_STATE_CONNECTED;
+  librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta;
   mirror_peer_client_meta.image_id = "missing image id";
   mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
   MockBootstrapRequest *request = create_request(
@@ -1159,7 +1112,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, PrimaryRemoteLocalDeleted) {
   ASSERT_EQ(0, ctx.wait());
 }
 
-TEST_F(TestMockImageReplayerBootstrapRequest, LocalImageIdCollision) {
+TEST_F(TestMockImageReplayerBootstrapRequest, CreateLocalImageError) {
   create_local_image();
 
   InSequence seq;
@@ -1178,41 +1131,9 @@ TEST_F(TestMockImageReplayerBootstrapRequest, LocalImageIdCollision) {
                                  cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
                                 librbd::mirror::PROMOTION_STATE_PRIMARY, 0);
 
-  // update client state back to syncing
-  librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
-  mock_local_image_ctx.journal = &mock_journal;
-
-  librbd::util::s_image_id = 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;
-  librbd::journal::ClientData client_data;
-  client_data.client_meta = mirror_peer_client_meta;
-  cls::journal::Client client;
-  encode(client_data, client.data);
-  ::journal::MockJournaler mock_journaler;
-  expect_journaler_update_client(mock_journaler, client_data, 0);
-
   // create the local image
-  MockCreateImageRequest mock_create_image_request;
-  expect_create_image(mock_create_image_request, mock_local_image_ctx.id,
-                      -EBADF);
-
-  expect_journaler_update_client(mock_journaler, client_data, 0);
-  expect_create_image(mock_create_image_request, mock_local_image_ctx.id, 0);
-
-  // open the local image
-  MockOpenLocalImageRequest mock_open_local_image_request;
-  expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
-                          mock_local_image_ctx.id, &mock_local_image_ctx, 0);
-  expect_is_resync_requested(mock_journal, false, 0);
-
-  expect_journal_get_tag_tid(mock_journal, 345);
-  expect_journal_get_tag_data(mock_journal, {"remote mirror uuid"});
-
-  // sync the remote image to the local image
-  MockImageSync mock_image_sync;
-  expect_image_sync(mock_image_sync, 0);
+  MockCreateLocalImageRequest mock_create_local_image_request;
+  expect_create_local_image(mock_create_local_image_request, "", -EINVAL);
 
   MockCloseImageRequest mock_close_image_request;
   expect_close_image(mock_close_image_request, mock_remote_image_ctx, 0);
@@ -1220,7 +1141,9 @@ TEST_F(TestMockImageReplayerBootstrapRequest, LocalImageIdCollision) {
   C_SaferCond ctx;
   MockThreads mock_threads(m_threads);
   MockInstanceWatcher mock_instance_watcher;
+  ::journal::MockJournaler mock_journaler;
   cls::journal::ClientState client_state = cls::journal::CLIENT_STATE_CONNECTED;
+  librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta;
   mirror_peer_client_meta.image_id = "";
   mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
   MockBootstrapRequest *request = create_request(
@@ -1228,7 +1151,7 @@ TEST_F(TestMockImageReplayerBootstrapRequest, LocalImageIdCollision) {
     mock_remote_image_ctx.id, "global image id", "local mirror uuid",
     "remote mirror uuid", &client_state, &mirror_peer_client_meta, &ctx);
   request->send();
-  ASSERT_EQ(0, ctx.wait());
+  ASSERT_EQ(-EINVAL, ctx.wait());
 }
 
 } // namespace image_replayer
index 2542356eae651cf48986defd439846e132c8580c..b08a9207ca015d00e7dd41e02fb364a81d32a5b9 100644 (file)
@@ -23,6 +23,7 @@
 #include "tools/rbd_mirror/ProgressContext.h"
 #include "tools/rbd_mirror/ImageSync.h"
 #include "tools/rbd_mirror/Threads.h"
+#include "tools/rbd_mirror/image_replayer/journal/CreateLocalImageRequest.h"
 
 #define dout_context g_ceph_context
 #define dout_subsys ceph_subsys_rbd_mirror
@@ -35,7 +36,6 @@ namespace mirror {
 namespace image_replayer {
 
 using librbd::util::create_context_callback;
-using librbd::util::create_rados_callback;
 using librbd::util::unique_lock_name;
 
 template <typename I>
@@ -50,7 +50,7 @@ BootstrapRequest<I>::BootstrapRequest(
         const std::string &global_image_id,
         const std::string &local_mirror_uuid,
         const std::string &remote_mirror_uuid,
-        Journaler *journaler,
+        Journaler *remote_journaler,
         cls::journal::ClientState *client_state,
         MirrorPeerClientMeta *client_meta,
         Context *on_finish,
@@ -63,10 +63,12 @@ BootstrapRequest<I>::BootstrapRequest(
     m_local_image_ctx(local_image_ctx), m_local_image_id(local_image_id),
     m_remote_image_id(remote_image_id), m_global_image_id(global_image_id),
     m_local_mirror_uuid(local_mirror_uuid),
-    m_remote_mirror_uuid(remote_mirror_uuid), m_journaler(journaler),
+    m_remote_mirror_uuid(remote_mirror_uuid),
+    m_remote_journaler(remote_journaler),
     m_client_state(client_state), m_client_meta(client_meta),
     m_progress_ctx(progress_ctx), m_do_resync(do_resync),
-    m_lock(ceph::make_mutex(unique_lock_name("BootstrapRequest::m_lock", this))) {
+    m_lock(ceph::make_mutex(unique_lock_name("BootstrapRequest::m_lock",
+                                             this))) {
   dout(10) << dendl;
 }
 
@@ -192,8 +194,7 @@ void BootstrapRequest<I>::handle_get_remote_mirror_info(int r) {
   }
 
   if (m_local_image_id.empty()) {
-    // prepare to create local image
-    update_client_image();
+    create_local_image();
     return;
   }
 
@@ -222,7 +223,7 @@ void BootstrapRequest<I>::handle_open_local_image(int r) {
   if (r == -ENOENT) {
     ceph_assert(*m_local_image_ctx == nullptr);
     dout(10) << "local image missing" << dendl;
-    unregister_client();
+    create_local_image();
     return;
   } else if (r == -EREMOTEIO) {
     ceph_assert(*m_local_image_ctx == nullptr);
@@ -319,7 +320,7 @@ void BootstrapRequest<I>::update_client_state() {
   Context *ctx = create_context_callback<
     BootstrapRequest<I>, &BootstrapRequest<I>::handle_update_client_state>(
       this);
-  m_journaler->update_client(data_bl, ctx);
+  m_remote_journaler->update_client(data_bl, ctx);
 }
 
 template <typename I>
@@ -336,132 +337,18 @@ void BootstrapRequest<I>::handle_update_client_state(int r) {
   get_remote_tag_class();
 }
 
-template <typename I>
-void BootstrapRequest<I>::unregister_client() {
-  dout(15) << dendl;
-  update_progress("UNREGISTER_CLIENT");
-
-  m_local_image_id = "";
-  Context *ctx = create_context_callback<
-    BootstrapRequest<I>, &BootstrapRequest<I>::handle_unregister_client>(
-      this);
-  m_journaler->unregister_client(ctx);
-}
-
-template <typename I>
-void BootstrapRequest<I>::handle_unregister_client(int r) {
-  dout(15) << "r=" << r << dendl;
-  if (r < 0) {
-    derr << "failed to unregister with remote journal: " << cpp_strerror(r)
-         << dendl;
-    m_ret_val = r;
-    close_remote_image();
-    return;
-  }
-
-  *m_client_meta = librbd::journal::MirrorPeerClientMeta("");
-  register_client();
-}
-
-template <typename I>
-void BootstrapRequest<I>::register_client() {
-  dout(15) << dendl;
-
-  update_progress("REGISTER_CLIENT");
-
-  ceph_assert(m_local_image_id.empty());
-  librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta;
-  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(15) << "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_client_meta->state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
-
-  get_remote_mirror_info();
-}
-
-template <typename I>
-void BootstrapRequest<I>::update_client_image() {
-  ceph_assert(m_local_image_id.empty());
-  assert(m_local_image_id.empty());
-  m_local_image_id = librbd::util::generate_image_id<I>(m_local_io_ctx);
-
-  dout(15) << "local_image_id=" << m_local_image_id << dendl;
-  update_progress("UPDATE_CLIENT_IMAGE");
-
-  librbd::journal::MirrorPeerClientMeta client_meta{m_local_image_id};
-  client_meta.state = librbd::journal::MIRROR_PEER_STATE_SYNCING;
-
-  librbd::journal::ClientData client_data(client_meta);
-  bufferlist data_bl;
-  encode(client_data, data_bl);
-
-  Context *ctx = create_context_callback<
-    BootstrapRequest<I>, &BootstrapRequest<I>::handle_update_client_image>(
-      this);
-  m_journaler->update_client(data_bl, ctx);
-}
-
-template <typename I>
-void BootstrapRequest<I>::handle_update_client_image(int r) {
-  dout(15) << "r=" << r << dendl;
-
-  if (r < 0) {
-    derr << "failed to update client: " << cpp_strerror(r) << dendl;
-    m_ret_val = r;
-    close_remote_image();
-    return;
-  }
-
-  if (m_canceled) {
-    dout(10) << "request canceled" << dendl;
-    m_ret_val = -ECANCELED;
-    close_remote_image();
-    return;
-  }
-
-  *m_client_meta = {m_local_image_id};
-  m_client_meta->state = librbd::journal::MIRROR_PEER_STATE_SYNCING;
-  create_local_image();
-}
-
 template <typename I>
 void BootstrapRequest<I>::create_local_image() {
-  dout(15) << "local_image_id=" << m_local_image_id << dendl;
   update_progress("CREATE_LOCAL_IMAGE");
 
-  m_remote_image_ctx->image_lock.lock_shared();
-  std::string image_name = m_remote_image_ctx->name;
-  m_remote_image_ctx->image_lock.unlock_shared();
-
-  Context *ctx = create_context_callback<
-    BootstrapRequest<I>, &BootstrapRequest<I>::handle_create_local_image>(
-      this);
-  CreateImageRequest<I> *request = CreateImageRequest<I>::create(
-    m_threads, m_local_io_ctx, m_global_image_id, m_remote_mirror_uuid,
-    image_name, m_local_image_id, m_remote_image_ctx, ctx);
+  // TODO support snapshot-based mirroring
+  auto ctx = create_context_callback<
+    BootstrapRequest<I>,
+    &BootstrapRequest<I>::handle_create_local_image>(this);
+  auto request = journal::CreateLocalImageRequest<I>::create(
+    m_threads, m_local_io_ctx, m_remote_image_ctx, m_remote_journaler,
+    m_global_image_id, m_remote_mirror_uuid, m_client_meta, m_progress_ctx,
+    &m_local_image_id, ctx);
   request->send();
 }
 
@@ -469,12 +356,7 @@ template <typename I>
 void BootstrapRequest<I>::handle_create_local_image(int r) {
   dout(15) << "r=" << r << dendl;
 
-  if (r == -EBADF) {
-    dout(5) << "image id " << m_local_image_id << " already in-use" << dendl;
-    m_local_image_id = "";
-    update_client_image();
-    return;
-  } else if (r < 0) {
+  if (r < 0) {
     if (r == -ENOENT) {
       dout(10) << "parent image does not exist" << dendl;
     } else {
@@ -485,6 +367,8 @@ void BootstrapRequest<I>::handle_create_local_image(int r) {
     return;
   }
 
+  *m_client_state = cls::journal::CLIENT_STATE_CONNECTED;
+
   open_local_image();
 }
 
@@ -504,7 +388,7 @@ void BootstrapRequest<I>::get_remote_tag_class() {
   Context *ctx = create_context_callback<
     BootstrapRequest<I>, &BootstrapRequest<I>::handle_get_remote_tag_class>(
       this);
-  m_journaler->get_client(librbd::Journal<>::IMAGE_CLIENT_ID, &m_client, ctx);
+  m_remote_journaler->get_client(librbd::Journal<>::IMAGE_CLIENT_ID, &m_client, ctx);
 }
 
 template <typename I>
@@ -552,7 +436,7 @@ void BootstrapRequest<I>::get_remote_tags() {
 
   Context *ctx = create_context_callback<
     BootstrapRequest<I>, &BootstrapRequest<I>::handle_get_remote_tags>(this);
-  m_journaler->get_tags(m_remote_tag_class, &m_remote_tags, ctx);
+  m_remote_journaler->get_tags(m_remote_tag_class, &m_remote_tags, ctx);
 }
 
 template <typename I>
@@ -696,7 +580,7 @@ void BootstrapRequest<I>::image_sync() {
         BootstrapRequest<I>, &BootstrapRequest<I>::handle_image_sync>(this);
       m_image_sync = ImageSync<I>::create(
           *m_local_image_ctx, m_remote_image_ctx, m_threads->timer,
-          &m_threads->timer_lock, m_local_mirror_uuid, m_journaler,
+          &m_threads->timer_lock, m_local_mirror_uuid, m_remote_journaler,
           m_client_meta, m_threads->work_queue, m_instance_watcher, ctx,
           m_progress_ctx);
 
index c2608caa4702b339c38bde38946cf257d98469d9..693867701c0aa56d7c68a0884ca9c4b48723fa2d 100644 (file)
@@ -54,7 +54,7 @@ public:
         const std::string &global_image_id,
         const std::string &local_mirror_uuid,
         const std::string &remote_mirror_uuid,
-        Journaler *journaler,
+        Journaler *remote_journaler,
         cls::journal::ClientState *client_state,
         MirrorPeerClientMeta *client_meta,
         Context *on_finish,
@@ -64,9 +64,9 @@ public:
                                 instance_watcher, local_image_ctx,
                                 local_image_id, remote_image_id,
                                 global_image_id, local_mirror_uuid,
-                                remote_mirror_uuid, journaler, client_state,
-                                client_meta, on_finish, do_resync,
-                                progress_ctx);
+                                remote_mirror_uuid, remote_journaler,
+                                client_state, client_meta, on_finish,
+                                do_resync, progress_ctx);
   }
 
   BootstrapRequest(Threads<ImageCtxT>* threads,
@@ -78,7 +78,8 @@ public:
                    const std::string &remote_image_id,
                    const std::string &global_image_id,
                    const std::string &local_mirror_uuid,
-                   const std::string &remote_mirror_uuid, Journaler *journaler,
+                   const std::string &remote_mirror_uuid,
+                   Journaler *remote_journaler,
                    cls::journal::ClientState *client_state,
                    MirrorPeerClientMeta *client_meta, Context *on_finish,
                    bool *do_resync, ProgressContext *progress_ctx = nullptr);
@@ -98,28 +99,14 @@ private:
    *    v
    * OPEN_REMOTE_IMAGE  * * * * * * * * * * * * * * * * * * * (error)
    *    |                                                   *
-   *    |/--------------------------------------------------*---\
-   *    v                                                   *   |
-   * GET_REMOTE_MIRROR_INFO * * * * * * * * * * * * * * *   *   |
-   *    |                                               *   *   |
-   *    | (remote image primary, no local image id)     *   *   |
-   *    \----> UPDATE_CLIENT_IMAGE  * * * * * * * * * * *   *   |
-   *    |         |   ^                                 *   *   |
-   *    |         |   * (duplicate image id)            *   *   |
-   *    |         v   *                                 *   *   |
-   *    \----> CREATE_LOCAL_IMAGE * * * * * * * * * * * *   *   |
-   *    |         |                                     *   *   |
-   *    |         v                                     *   *   |
-   *    | (remote image primary)                        *   *   |
-   *    \----> OPEN_LOCAL_IMAGE * * * * * * * * * * * * *   *   |
-   *              |   .                                 *   *   |
-   *              |   . (image doesn't exist)           *   *   |
-   *              |   . . > UNREGISTER_CLIENT * * * * * *   *   |
-   *              |             |                       *   *   |
-   *              |             v                       *   *   |
-   *              |         REGISTER_CLIENT * * * * * * *   *   |
-   *              |             |                       *   *   |
-   *              |             \-----------------------*---*---/
+   *    v                                                   *
+   * GET_REMOTE_MIRROR_INFO * * * * * * * * * * * * * * *   *
+   *    |                                               *   *
+   *    |                                               *   *
+   *    \----> CREATE_LOCAL_IMAGE * * * * * * * * * * * *   *
+   *    |         |       ^                             *   *
+   *    |         v       . (image DNE)                 *   *
+   *    \----> OPEN_LOCAL_IMAGE * * * * * * * * * * * * *   *
    *              |                                     *   *
    *              v (skip if not needed)                *   *
    *           UPDATE_CLIENT_STATE                      *   *
@@ -158,7 +145,7 @@ private:
   std::string m_global_image_id;
   std::string m_local_mirror_uuid;
   std::string m_remote_mirror_uuid;
-  Journaler *m_journaler;
+  Journaler *m_remote_journaler;
   cls::journal::ClientState *m_client_state;
   MirrorPeerClientMeta *m_client_meta;
   ProgressContext *m_progress_ctx;
@@ -191,18 +178,9 @@ private:
   void open_local_image();
   void handle_open_local_image(int r);
 
-  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);
 
-  void update_client_image();
-  void handle_update_client_image(int r);
-
   void update_client_state();
   void handle_update_client_state(int r);