]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rbd-mirror: prepare remote image now handles the snapshot mode
authorJason Dillaman <dillaman@redhat.com>
Mon, 27 Jan 2020 19:47:30 +0000 (14:47 -0500)
committerJason Dillaman <dillaman@redhat.com>
Thu, 30 Jan 2020 15:26:36 +0000 (10:26 -0500)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/test/rbd_mirror/image_replayer/test_mock_PrepareRemoteImageRequest.cc
src/tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.cc
src/tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.h
src/tools/rbd_mirror/image_replayer/snapshot/StateBuilder.cc
src/tools/rbd_mirror/image_replayer/snapshot/StateBuilder.h

index 180a6f823c7c93615f7423503e1b89422b8debf7..04ee88205db6dc682e8cefba3e5ba8c01b4d5a16 100644 (file)
@@ -10,6 +10,7 @@
 #include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.h"
 #include "tools/rbd_mirror/image_replayer/StateBuilder.h"
 #include "tools/rbd_mirror/image_replayer/journal/StateBuilder.h"
+#include "tools/rbd_mirror/image_replayer/snapshot/StateBuilder.h"
 #include "test/journal/mock/MockJournaler.h"
 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
 #include "test/librbd/mock/MockImageCtx.h"
@@ -137,6 +138,9 @@ struct StateBuilder<librbd::MockTestImageCtx>
   : public image_replayer::StateBuilder<librbd::MockTestImageCtx> {
   static StateBuilder* s_instance;
 
+  cls::rbd::MirrorImageMode mirror_image_mode =
+    cls::rbd::MIRROR_IMAGE_MODE_JOURNAL;
+
   ::journal::MockJournalerProxy* remote_journaler = nullptr;
   cls::journal::ClientState remote_client_state;
   librbd::journal::MirrorPeerClientMeta remote_client_meta;
@@ -154,6 +158,32 @@ struct StateBuilder<librbd::MockTestImageCtx>
 StateBuilder<librbd::MockTestImageCtx>* StateBuilder<librbd::MockTestImageCtx>::s_instance = nullptr;
 
 } // namespace journal
+
+namespace snapshot {
+
+template<>
+struct StateBuilder<librbd::MockTestImageCtx>
+  : public image_replayer::StateBuilder<librbd::MockTestImageCtx> {
+  static StateBuilder* s_instance;
+
+  cls::rbd::MirrorImageMode mirror_image_mode =
+    cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT;
+
+  std::string remote_mirror_peer_uuid;
+
+  static StateBuilder* create(const std::string&) {
+    ceph_assert(s_instance != nullptr);
+    return s_instance;
+  }
+
+  StateBuilder() {
+    s_instance = this;
+  }
+};
+
+StateBuilder<librbd::MockTestImageCtx>* StateBuilder<librbd::MockTestImageCtx>::s_instance = nullptr;
+
+} // namespace snapshot
 } // namespace image_replayer
 } // namespace mirror
 } // namespace rbd
@@ -180,6 +210,7 @@ public:
   typedef GetMirrorImageIdRequest<librbd::MockTestImageCtx> MockGetMirrorImageIdRequest;
   typedef StateBuilder<librbd::MockTestImageCtx> MockStateBuilder;
   typedef journal::StateBuilder<librbd::MockTestImageCtx> MockJournalStateBuilder;
+  typedef snapshot::StateBuilder<librbd::MockTestImageCtx> MockSnapshotStateBuilder;
   typedef librbd::mirror::GetInfoRequest<librbd::MockTestImageCtx> MockGetMirrorInfoRequest;
 
   void expect_get_mirror_image_mode(MockStateBuilder& mock_state_builder,
@@ -239,7 +270,7 @@ public:
   }
 };
 
-TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, Success) {
+TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessJournal) {
   ::journal::MockJournaler mock_remote_journaler;
   MockThreads mock_threads(m_threads);
 
@@ -284,6 +315,10 @@ TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, Success) {
 
   ASSERT_EQ(0, ctx.wait());
   ASSERT_TRUE(mock_state_builder != nullptr);
+  ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
+           mock_journal_state_builder.mirror_image_mode);
+  ASSERT_EQ(std::string("remote mirror uuid"),
+            mock_journal_state_builder.remote_mirror_uuid);
   ASSERT_EQ(std::string("remote image id"),
             mock_journal_state_builder.remote_image_id);
   ASSERT_EQ(librbd::mirror::PROMOTION_STATE_PRIMARY,
@@ -293,6 +328,52 @@ TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, Success) {
             mock_journal_state_builder.remote_client_state);
 }
 
+TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessSnapshot) {
+  ::journal::MockJournaler mock_remote_journaler;
+  MockThreads mock_threads(m_threads);
+
+  InSequence seq;
+  MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
+  expect_get_mirror_image_id(mock_get_mirror_image_id_request,
+                             "remote image id", 0);
+
+  MockGetMirrorInfoRequest mock_get_mirror_info_request;
+  expect_get_mirror_info(mock_get_mirror_info_request,
+                         {cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT,
+                          "global image id",
+                          cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
+                         librbd::mirror::PROMOTION_STATE_PRIMARY,
+                         "remote mirror uuid", 0);
+
+  MockSnapshotStateBuilder mock_snapshot_state_builder;
+  MockStateBuilder* mock_state_builder = nullptr;
+  C_SaferCond ctx;
+  auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
+                                                   m_local_io_ctx,
+                                                   m_remote_io_ctx,
+                                                   "global image id",
+                                                   "local mirror uuid",
+                                                   {"remote mirror uuid",
+                                                    "remote mirror peer uuid"},
+                                                   nullptr,
+                                                   &mock_state_builder,
+                                                   &ctx);
+  req->send();
+
+  ASSERT_EQ(0, ctx.wait());
+  ASSERT_TRUE(mock_state_builder != nullptr);
+  ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT,
+           mock_snapshot_state_builder.mirror_image_mode);
+  ASSERT_EQ(std::string("remote mirror uuid"),
+            mock_snapshot_state_builder.remote_mirror_uuid);
+  ASSERT_EQ(std::string("remote mirror peer uuid"),
+            mock_snapshot_state_builder.remote_mirror_peer_uuid);
+  ASSERT_EQ(std::string("remote image id"),
+            mock_snapshot_state_builder.remote_image_id);
+  ASSERT_EQ(librbd::mirror::PROMOTION_STATE_PRIMARY,
+            mock_snapshot_state_builder.remote_promotion_state);
+}
+
 TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessNotRegistered) {
   ::journal::MockJournaler mock_remote_journaler;
   MockThreads mock_threads(m_threads);
index 652c22d7122cf00ef2bb44bc444e4928665eff8d..b3d4ec4e18aed7312e82c73d9b2ea7d5fa232c6c 100644 (file)
@@ -16,6 +16,7 @@
 #include "tools/rbd_mirror/image_replayer/GetMirrorImageIdRequest.h"
 #include "tools/rbd_mirror/image_replayer/Utils.h"
 #include "tools/rbd_mirror/image_replayer/journal/StateBuilder.h"
+#include "tools/rbd_mirror/image_replayer/snapshot/StateBuilder.h"
 
 #define dout_context g_ceph_context
 #define dout_subsys ceph_subsys_rbd_mirror
@@ -121,7 +122,9 @@ void PrepareRemoteImageRequest<I>::handle_get_mirror_info(int r) {
     get_client();
     break;
   case cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT:
-    // TODO
+    finalize_snapshot_state_builder();
+    finish(0);
+    break;
   default:
     derr << "unsupported mirror image mode " << m_mirror_image.mode << " "
          << "for image " << m_global_image_id << dendl;
@@ -236,6 +239,25 @@ void PrepareRemoteImageRequest<I>::finalize_journal_state_builder(
   state_builder->remote_client_meta = client_meta;
 }
 
+template <typename I>
+void PrepareRemoteImageRequest<I>::finalize_snapshot_state_builder() {
+  snapshot::StateBuilder<I>* state_builder = nullptr;
+  if (*m_state_builder != nullptr) {
+    // already verified that it's a matching builder in
+    // 'handle_get_mirror_info'
+    state_builder = dynamic_cast<snapshot::StateBuilder<I>*>(*m_state_builder);
+    ceph_assert(state_builder != nullptr);
+  } else {
+    state_builder = snapshot::StateBuilder<I>::create(m_global_image_id);
+    *m_state_builder = state_builder;
+  }
+
+  state_builder->remote_mirror_uuid = m_remote_pool_meta.mirror_uuid;
+  state_builder->remote_mirror_peer_uuid = m_remote_pool_meta.mirror_peer_uuid;
+  state_builder->remote_image_id = m_remote_image_id;
+  state_builder->remote_promotion_state = m_promotion_state;
+}
+
 template <typename I>
 void PrepareRemoteImageRequest<I>::finish(int r) {
   dout(10) << "r=" << r << dendl;
index 397436bc747e7ec2839af38f8c7647034a0d8dd8..b546cdc80ffc7f52f9b6ce97934abcd5afe869ee 100644 (file)
@@ -92,13 +92,16 @@ private:
    *    |
    *    | (journal)
    *    \-----------> GET_CLIENT
-   *                      |
-   *                      v (skip if not needed)
-   *                  REGISTER_CLIENT
-   *                      |
-   *                      v
-   *                  <finish>
-
+   *    |                 |
+   *    |                 v (skip if not needed)
+   *    |             REGISTER_CLIENT
+   *    |                 |
+   *    |                 |
+   *    |/----------------/
+   *    |
+   *    v
+   * <finish>
+   *
    * @endverbatim
    */
 
@@ -136,6 +139,8 @@ private:
 
   void finalize_journal_state_builder(cls::journal::ClientState client_state,
                                       const MirrorPeerClientMeta& client_meta);
+  void finalize_snapshot_state_builder();
+
   void finish(int r);
 };
 
index 471a8a7a638c09c1f8ab1588a6567802bfe3e76d..604b62f9c74d9e9d23ee0c14574398627b47e604 100644 (file)
@@ -41,6 +41,13 @@ bool StateBuilder<I>::is_disconnected() const {
   return false;
 }
 
+template <typename I>
+bool StateBuilder<I>::is_linked() const {
+  // the remote has to have us registered as a peer
+  return (image_replayer::StateBuilder<I>::is_linked() &&
+          !remote_mirror_peer_uuid.empty());
+}
+
 template <typename I>
 cls::rbd::MirrorImageMode StateBuilder<I>::get_mirror_image_mode() const {
   return cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT;
index 49e2f66d853462d0c86b0a5c0c133af19d3c8d32..7444ceb344d7beaf24dd34810824b47ed0db077a 100644 (file)
@@ -31,6 +31,7 @@ public:
   void close(Context* on_finish) override;
 
   bool is_disconnected() const override;
+  bool is_linked() const override;
 
   cls::rbd::MirrorImageMode get_mirror_image_mode() const override;
 
@@ -57,6 +58,8 @@ public:
 
   SyncPointHandler<ImageCtxT>* sync_point_handler = nullptr;
 
+  std::string remote_mirror_peer_uuid;
+
 };
 
 } // namespace snapshot