#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"
: 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;
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
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,
}
};
-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",
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"),
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;
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;
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;
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
#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
*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;
--- /dev/null
+// -*- 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>;
--- /dev/null
+// -*- 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