]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rbd-mirror: stub version of snapshot image replayer state builder
authorJason Dillaman <dillaman@redhat.com>
Mon, 27 Jan 2020 16:23:43 +0000 (11:23 -0500)
committerJason Dillaman <dillaman@redhat.com>
Thu, 30 Jan 2020 15:26:36 +0000 (10:26 -0500)
This stub class will be expanded as support for snapshot-based
mirroring is expanded.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/test/rbd_mirror/image_replayer/test_mock_PrepareLocalImageRequest.cc
src/tools/rbd_mirror/CMakeLists.txt
src/tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.cc
src/tools/rbd_mirror/image_replayer/snapshot/StateBuilder.cc [new file with mode: 0644]
src/tools/rbd_mirror/image_replayer/snapshot/StateBuilder.h [new file with mode: 0644]

index 5d96ad67ce00ae62f8cd8ae9a2f9c563ff5a9dca..a66560d5a30aab08b2e5ef7157f6b2dcfe9cb5cc 100644 (file)
@@ -9,6 +9,7 @@
 #include "tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.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"
@@ -112,6 +113,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;
+
   static StateBuilder* create(const std::string&) {
     ceph_assert(s_instance != nullptr);
     return s_instance;
@@ -125,6 +129,30 @@ 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;
+
+  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
@@ -151,6 +179,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_id(MockGetMirrorImageIdRequest& mock_get_mirror_image_id_request,
@@ -193,7 +222,7 @@ public:
   }
 };
 
-TEST_F(TestMockImageReplayerPrepareLocalImageRequest, Success) {
+TEST_F(TestMockImageReplayerPrepareLocalImageRequest, SuccessJournal) {
   InSequence seq;
   MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
   expect_get_mirror_image_id(mock_get_mirror_image_id_request, "local image id",
@@ -225,6 +254,48 @@ TEST_F(TestMockImageReplayerPrepareLocalImageRequest, Success) {
   ASSERT_EQ(std::string("local image name"), local_image_name);
   ASSERT_EQ(std::string("local image id"),
             mock_journal_state_builder.local_image_id);
+  ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
+            mock_journal_state_builder.mirror_image_mode);
+  ASSERT_EQ(librbd::mirror::PROMOTION_STATE_NON_PRIMARY,
+            mock_journal_state_builder.local_promotion_state);
+  ASSERT_EQ(std::string("remote mirror uuid"),
+            mock_journal_state_builder.local_primary_mirror_uuid);
+}
+
+TEST_F(TestMockImageReplayerPrepareLocalImageRequest, SuccessSnapshot) {
+  InSequence seq;
+  MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
+  expect_get_mirror_image_id(mock_get_mirror_image_id_request, "local image id",
+                             0);
+  expect_dir_get_name(m_local_io_ctx, "local image name", 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_NON_PRIMARY,
+                         "remote mirror uuid", 0);
+
+  MockSnapshotStateBuilder mock_journal_state_builder;
+  MockStateBuilder* mock_state_builder = nullptr;
+  std::string local_image_name;
+  C_SaferCond ctx;
+  auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx,
+                                                  "global image id",
+                                                  &local_image_name,
+                                                  &mock_state_builder,
+                                                  m_threads->work_queue,
+                                                  &ctx);
+  req->send();
+
+  ASSERT_EQ(0, ctx.wait());
+  ASSERT_TRUE(mock_state_builder != nullptr);
+  ASSERT_EQ(std::string("local image name"), local_image_name);
+  ASSERT_EQ(std::string("local image id"),
+            mock_journal_state_builder.local_image_id);
+  ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT,
+            mock_journal_state_builder.mirror_image_mode);
   ASSERT_EQ(librbd::mirror::PROMOTION_STATE_NON_PRIMARY,
             mock_journal_state_builder.local_promotion_state);
   ASSERT_EQ(std::string("remote mirror uuid"),
@@ -236,7 +307,6 @@ TEST_F(TestMockImageReplayerPrepareLocalImageRequest, MirrorImageIdError) {
   MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
   expect_get_mirror_image_id(mock_get_mirror_image_id_request, "", -EINVAL);
 
-  MockJournalStateBuilder mock_journal_state_builder;
   MockStateBuilder* mock_state_builder = nullptr;
   std::string local_image_name;
   C_SaferCond ctx;
@@ -258,7 +328,6 @@ TEST_F(TestMockImageReplayerPrepareLocalImageRequest, DirGetNameError) {
                              0);
   expect_dir_get_name(m_local_io_ctx, "", -ENOENT);
 
-  MockJournalStateBuilder mock_journal_state_builder;
   MockStateBuilder* mock_state_builder = nullptr;
   std::string local_image_name;
   C_SaferCond ctx;
@@ -288,7 +357,6 @@ TEST_F(TestMockImageReplayerPrepareLocalImageRequest, MirrorImageInfoError) {
                          librbd::mirror::PROMOTION_STATE_NON_PRIMARY,
                          "remote mirror uuid", -EINVAL);
 
-  MockJournalStateBuilder mock_journal_state_builder;
   MockStateBuilder* mock_state_builder = nullptr;
   std::string local_image_name;
   C_SaferCond ctx;
index 2412108f5b1b1b11a5d8c4f8f498d2fce682bdf4..3c35e85a76e71bd4c1618ef9d97ffbfb0f5f74b1 100644 (file)
@@ -50,6 +50,7 @@ set(rbd_mirror_internal
   image_replayer/journal/ReplayStatusFormatter.cc
   image_replayer/journal/StateBuilder.cc
   image_replayer/journal/SyncPointHandler.cc
+  image_replayer/snapshot/StateBuilder.cc
   image_sync/SyncPointCreateRequest.cc
   image_sync/SyncPointPruneRequest.cc
   pool_watcher/RefreshImagesRequest.cc
index e7ee2d0c2a9000d7a00d8e4b597a6cebea6f158e..aa2b30f59344cc25760eb75c5df6859b58cda067 100644 (file)
@@ -13,6 +13,7 @@
 #include "tools/rbd_mirror/Threads.h"
 #include "tools/rbd_mirror/image_replayer/GetMirrorImageIdRequest.h"
 #include "tools/rbd_mirror/image_replayer/journal/StateBuilder.h"
+#include "tools/rbd_mirror/image_replayer/snapshot/StateBuilder.h"
 #include <type_traits>
 
 #define dout_context g_ceph_context
@@ -130,7 +131,9 @@ void PrepareLocalImageRequest<I>::handle_get_mirror_info(int r) {
     *m_state_builder = journal::StateBuilder<I>::create(m_global_image_id);
     break;
   case cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT:
-    // TODO
+    // snapshot-based local image exists
+    *m_state_builder = snapshot::StateBuilder<I>::create(m_global_image_id);
+    break;
   default:
     derr << "unsupported mirror image mode " << m_mirror_image.mode << " "
          << "for image " << m_global_image_id << dendl;
diff --git a/src/tools/rbd_mirror/image_replayer/snapshot/StateBuilder.cc b/src/tools/rbd_mirror/image_replayer/snapshot/StateBuilder.cc
new file mode 100644 (file)
index 0000000..82b631a
--- /dev/null
@@ -0,0 +1,99 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "StateBuilder.h"
+#include "include/ceph_assert.h"
+#include "include/Context.h"
+#include "common/debug.h"
+#include "common/errno.h"
+#include "librbd/ImageCtx.h"
+
+#define dout_context g_ceph_context
+#define dout_subsys ceph_subsys_rbd_mirror
+#undef dout_prefix
+#define dout_prefix *_dout << "rbd::mirror::image_replayer::snapshot::" \
+                           << "StateBuilder: " << this << " " \
+                           << __func__ << ": "
+
+namespace rbd {
+namespace mirror {
+namespace image_replayer {
+namespace snapshot {
+
+template <typename I>
+StateBuilder<I>::StateBuilder(const std::string& global_image_id)
+  : image_replayer::StateBuilder<I>(global_image_id) {
+}
+
+template <typename I>
+StateBuilder<I>::~StateBuilder() {
+}
+
+template <typename I>
+void StateBuilder<I>::close(Context* on_finish) {
+  dout(10) << dendl;
+
+  this->close_local_image(on_finish);
+}
+
+template <typename I>
+bool StateBuilder<I>::is_disconnected() const {
+  return false;
+}
+
+template <typename I>
+cls::rbd::MirrorImageMode StateBuilder<I>::get_mirror_image_mode() const {
+  return cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT;
+}
+
+template <typename I>
+image_sync::SyncPointHandler* StateBuilder<I>::create_sync_point_handler() {
+  dout(10) << dendl;
+
+  // TODO
+  ceph_assert(false);
+  return nullptr;
+}
+
+template <typename I>
+BaseRequest* StateBuilder<I>::create_local_image_request(
+    Threads<I>* threads,
+    librados::IoCtx& local_io_ctx,
+    I* remote_image_ctx,
+    const std::string& global_image_id,
+    ProgressContext* progress_ctx,
+    Context* on_finish) {
+  // TODO
+  ceph_assert(false);
+  return nullptr;
+}
+
+template <typename I>
+BaseRequest* StateBuilder<I>::create_prepare_replay_request(
+    const std::string& local_mirror_uuid,
+    librbd::mirror::PromotionState remote_promotion_state,
+    ProgressContext* progress_ctx,
+    bool* resync_requested,
+    bool* syncing,
+    Context* on_finish) {
+  // TODO
+  ceph_assert(false);
+  return nullptr;
+}
+
+template <typename I>
+image_replayer::Replayer* StateBuilder<I>::create_replayer(
+   Threads<I>* threads,
+    const std::string& local_mirror_uuid,
+    ReplayerListener* replayer_listener) {
+  // TODO
+  ceph_assert(false);
+  return nullptr;
+}
+
+} // namespace snapshot
+} // namespace image_replayer
+} // namespace mirror
+} // namespace rbd
+
+template class rbd::mirror::image_replayer::snapshot::StateBuilder<librbd::ImageCtx>;
diff --git a/src/tools/rbd_mirror/image_replayer/snapshot/StateBuilder.h b/src/tools/rbd_mirror/image_replayer/snapshot/StateBuilder.h
new file mode 100644 (file)
index 0000000..ff4b120
--- /dev/null
@@ -0,0 +1,71 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_RBD_MIRROR_IMAGE_REPLAYER_SNAPSHOT_STATE_BUILDER_H
+#define CEPH_RBD_MIRROR_IMAGE_REPLAYER_SNAPSHOT_STATE_BUILDER_H
+
+#include "tools/rbd_mirror/image_replayer/StateBuilder.h"
+#include <string>
+
+struct Context;
+
+namespace librbd { struct ImageCtx; }
+
+namespace rbd {
+namespace mirror {
+namespace image_replayer {
+namespace snapshot {
+
+template <typename> class SyncPointHandler;
+
+template <typename ImageCtxT>
+class StateBuilder : public image_replayer::StateBuilder<ImageCtxT> {
+public:
+  static StateBuilder* create(const std::string& global_image_id) {
+    return new StateBuilder(global_image_id);
+  }
+
+  StateBuilder(const std::string& global_image_id);
+  ~StateBuilder() override;
+
+  void close(Context* on_finish) override;
+
+  bool is_disconnected() const override;
+
+  cls::rbd::MirrorImageMode get_mirror_image_mode() const override;
+
+  image_sync::SyncPointHandler* create_sync_point_handler() override;
+
+  BaseRequest* create_local_image_request(
+      Threads<ImageCtxT>* threads,
+      librados::IoCtx& local_io_ctx,
+      ImageCtxT* remote_image_ctx,
+      const std::string& global_image_id,
+      ProgressContext* progress_ctx,
+      Context* on_finish) override;
+
+  BaseRequest* create_prepare_replay_request(
+      const std::string& local_mirror_uuid,
+      librbd::mirror::PromotionState remote_promotion_state,
+      ProgressContext* progress_ctx,
+      bool* resync_requested,
+      bool* syncing,
+      Context* on_finish) override;
+
+  image_replayer::Replayer* create_replayer(
+      Threads<ImageCtxT>* threads,
+      const std::string& local_mirror_uuid,
+      ReplayerListener* replayer_listener) override;
+
+  SyncPointHandler<ImageCtxT>* sync_point_handler = nullptr;
+
+};
+
+} // namespace snapshot
+} // namespace image_replayer
+} // namespace mirror
+} // namespace rbd
+
+extern template class rbd::mirror::image_replayer::snapshot::StateBuilder<librbd::ImageCtx>;
+
+#endif // CEPH_RBD_MIRROR_IMAGE_REPLAYER_SNAPSHOT_STATE_BUILDER_H