From f27b586f3a76cee7fe2995279c71061aa3e15130 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Mon, 27 Jan 2020 11:23:43 -0500 Subject: [PATCH] rbd-mirror: stub version of snapshot image replayer state builder This stub class will be expanded as support for snapshot-based mirroring is expanded. Signed-off-by: Jason Dillaman --- .../test_mock_PrepareLocalImageRequest.cc | 76 +++++++++++++- src/tools/rbd_mirror/CMakeLists.txt | 1 + .../PrepareLocalImageRequest.cc | 5 +- .../image_replayer/snapshot/StateBuilder.cc | 99 +++++++++++++++++++ .../image_replayer/snapshot/StateBuilder.h | 71 +++++++++++++ 5 files changed, 247 insertions(+), 5 deletions(-) create mode 100644 src/tools/rbd_mirror/image_replayer/snapshot/StateBuilder.cc create mode 100644 src/tools/rbd_mirror/image_replayer/snapshot/StateBuilder.h diff --git a/src/test/rbd_mirror/image_replayer/test_mock_PrepareLocalImageRequest.cc b/src/test/rbd_mirror/image_replayer/test_mock_PrepareLocalImageRequest.cc index 5d96ad67ce0..a66560d5a30 100644 --- a/src/test/rbd_mirror/image_replayer/test_mock_PrepareLocalImageRequest.cc +++ b/src/test/rbd_mirror/image_replayer/test_mock_PrepareLocalImageRequest.cc @@ -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 : public image_replayer::StateBuilder { 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 StateBuilder* StateBuilder::s_instance = nullptr; } // namespace journal + +namespace snapshot { + +template<> +struct StateBuilder + : public image_replayer::StateBuilder { + 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* StateBuilder::s_instance = nullptr; + +} // namespace snapshot } // namespace image_replayer } // namespace mirror } // namespace rbd @@ -151,6 +179,7 @@ public: typedef GetMirrorImageIdRequest MockGetMirrorImageIdRequest; typedef StateBuilder MockStateBuilder; typedef journal::StateBuilder MockJournalStateBuilder; + typedef snapshot::StateBuilder MockSnapshotStateBuilder; typedef librbd::mirror::GetInfoRequest 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; diff --git a/src/tools/rbd_mirror/CMakeLists.txt b/src/tools/rbd_mirror/CMakeLists.txt index 2412108f5b1..3c35e85a76e 100644 --- a/src/tools/rbd_mirror/CMakeLists.txt +++ b/src/tools/rbd_mirror/CMakeLists.txt @@ -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 diff --git a/src/tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.cc b/src/tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.cc index e7ee2d0c2a9..aa2b30f5934 100644 --- a/src/tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.cc +++ b/src/tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.cc @@ -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 #define dout_context g_ceph_context @@ -130,7 +131,9 @@ void PrepareLocalImageRequest::handle_get_mirror_info(int r) { *m_state_builder = journal::StateBuilder::create(m_global_image_id); break; case cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT: - // TODO + // snapshot-based local image exists + *m_state_builder = snapshot::StateBuilder::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 index 00000000000..82b631a8378 --- /dev/null +++ b/src/tools/rbd_mirror/image_replayer/snapshot/StateBuilder.cc @@ -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 +StateBuilder::StateBuilder(const std::string& global_image_id) + : image_replayer::StateBuilder(global_image_id) { +} + +template +StateBuilder::~StateBuilder() { +} + +template +void StateBuilder::close(Context* on_finish) { + dout(10) << dendl; + + this->close_local_image(on_finish); +} + +template +bool StateBuilder::is_disconnected() const { + return false; +} + +template +cls::rbd::MirrorImageMode StateBuilder::get_mirror_image_mode() const { + return cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT; +} + +template +image_sync::SyncPointHandler* StateBuilder::create_sync_point_handler() { + dout(10) << dendl; + + // TODO + ceph_assert(false); + return nullptr; +} + +template +BaseRequest* StateBuilder::create_local_image_request( + Threads* 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 +BaseRequest* StateBuilder::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 +image_replayer::Replayer* StateBuilder::create_replayer( + Threads* 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; 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 index 00000000000..ff4b1209676 --- /dev/null +++ b/src/tools/rbd_mirror/image_replayer/snapshot/StateBuilder.h @@ -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 + +struct Context; + +namespace librbd { struct ImageCtx; } + +namespace rbd { +namespace mirror { +namespace image_replayer { +namespace snapshot { + +template class SyncPointHandler; + +template +class StateBuilder : public image_replayer::StateBuilder { +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* 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* threads, + const std::string& local_mirror_uuid, + ReplayerListener* replayer_listener) override; + + SyncPointHandler* sync_point_handler = nullptr; + +}; + +} // namespace snapshot +} // namespace image_replayer +} // namespace mirror +} // namespace rbd + +extern template class rbd::mirror::image_replayer::snapshot::StateBuilder; + +#endif // CEPH_RBD_MIRROR_IMAGE_REPLAYER_SNAPSHOT_STATE_BUILDER_H -- 2.39.5