From: Jason Dillaman Date: Sat, 7 Dec 2019 03:38:33 +0000 (-0500) Subject: rbd-mirror: moved event pre-processor to sub-namespace X-Git-Tag: v15.1.0~487^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=975c9047d0bb9cb7866d5dd62f55f6509272fbb6;p=ceph.git rbd-mirror: moved event pre-processor to sub-namespace The current implementation is tied to journal-based replaying so move it down into the journal sub-namespace. Signed-off-by: Jason Dillaman --- diff --git a/src/test/rbd_mirror/CMakeLists.txt b/src/test/rbd_mirror/CMakeLists.txt index 3c40aaa87988b..c769426ba52b2 100644 --- a/src/test/rbd_mirror/CMakeLists.txt +++ b/src/test/rbd_mirror/CMakeLists.txt @@ -35,10 +35,10 @@ add_executable(unittest_rbd_mirror image_deleter/test_mock_TrashWatcher.cc image_replayer/test_mock_BootstrapRequest.cc image_replayer/test_mock_CreateImageRequest.cc - image_replayer/test_mock_EventPreprocessor.cc image_replayer/test_mock_GetMirrorImageIdRequest.cc image_replayer/test_mock_PrepareLocalImageRequest.cc image_replayer/test_mock_PrepareRemoteImageRequest.cc + image_replayer/journal/test_mock_EventPreprocessor.cc image_sync/test_mock_SyncPointCreateRequest.cc image_sync/test_mock_SyncPointPruneRequest.cc pool_watcher/test_mock_RefreshImagesRequest.cc diff --git a/src/test/rbd_mirror/image_replayer/journal/test_mock_EventPreprocessor.cc b/src/test/rbd_mirror/image_replayer/journal/test_mock_EventPreprocessor.cc new file mode 100644 index 0000000000000..ad00552814bfb --- /dev/null +++ b/src/test/rbd_mirror/image_replayer/journal/test_mock_EventPreprocessor.cc @@ -0,0 +1,266 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "test/rbd_mirror/test_mock_fixture.h" +#include "librbd/journal/Types.h" +#include "librbd/journal/TypeTraits.h" +#include "tools/rbd_mirror/Threads.h" +#include "tools/rbd_mirror/image_replayer/journal/EventPreprocessor.h" +#include "test/journal/mock/MockJournaler.h" +#include "test/librbd/mock/MockImageCtx.h" + +namespace librbd { + +namespace { + +struct MockTestImageCtx : public librbd::MockImageCtx { + explicit MockTestImageCtx(librbd::ImageCtx &image_ctx) + : librbd::MockImageCtx(image_ctx) { + } +}; + +} // anonymous namespace + +namespace journal { + +template <> +struct TypeTraits { + typedef ::journal::MockJournaler Journaler; +}; + +} // namespace journal +} // namespace librbd + +// template definitions +#include "tools/rbd_mirror/image_replayer/journal/EventPreprocessor.cc" + +namespace rbd { +namespace mirror { +namespace image_replayer { +namespace journal { + +using testing::_; +using testing::WithArg; + +class TestMockImageReplayerJournalEventPreprocessor : public TestMockFixture { +public: + typedef EventPreprocessor MockEventPreprocessor; + + void SetUp() override { + TestMockFixture::SetUp(); + + librbd::RBD rbd; + ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size)); + ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &m_local_image_ctx)); + } + + void expect_image_refresh(librbd::MockTestImageCtx &mock_remote_image_ctx, int r) { + EXPECT_CALL(*mock_remote_image_ctx.state, refresh(_)) + .WillOnce(CompleteContext(r)); + } + + void expect_update_client(::journal::MockJournaler &mock_journaler, int r) { + EXPECT_CALL(mock_journaler, update_client(_, _)) + .WillOnce(WithArg<1>(CompleteContext(r))); + } + + librbd::ImageCtx *m_local_image_ctx; + librbd::journal::MirrorPeerClientMeta m_client_meta; + +}; + +TEST_F(TestMockImageReplayerJournalEventPreprocessor, IsNotRequired) { + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); + ::journal::MockJournaler mock_remote_journaler; + + MockEventPreprocessor event_preprocessor(mock_local_image_ctx, + mock_remote_journaler, + "local mirror uuid", + &m_client_meta, + m_threads->work_queue); + + librbd::journal::EventEntry event_entry{librbd::journal::RenameEvent{}}; + ASSERT_FALSE(event_preprocessor.is_required(event_entry)); +} + +TEST_F(TestMockImageReplayerJournalEventPreprocessor, IsRequiredSnapMapPrune) { + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); + ::journal::MockJournaler mock_remote_journaler; + + m_client_meta.snap_seqs = {{1, 2}, {3, 4}}; + MockEventPreprocessor event_preprocessor(mock_local_image_ctx, + mock_remote_journaler, + "local mirror uuid", + &m_client_meta, + m_threads->work_queue); + + librbd::journal::EventEntry event_entry{librbd::journal::RenameEvent{}}; + ASSERT_TRUE(event_preprocessor.is_required(event_entry)); +} + +TEST_F(TestMockImageReplayerJournalEventPreprocessor, IsRequiredSnapRename) { + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); + ::journal::MockJournaler mock_remote_journaler; + + MockEventPreprocessor event_preprocessor(mock_local_image_ctx, + mock_remote_journaler, + "local mirror uuid", + &m_client_meta, + m_threads->work_queue); + + librbd::journal::EventEntry event_entry{librbd::journal::SnapRenameEvent{}}; + ASSERT_TRUE(event_preprocessor.is_required(event_entry)); +} + +TEST_F(TestMockImageReplayerJournalEventPreprocessor, PreprocessSnapMapPrune) { + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); + ::journal::MockJournaler mock_remote_journaler; + + expect_image_refresh(mock_local_image_ctx, 0); + expect_update_client(mock_remote_journaler, 0); + + mock_local_image_ctx.snap_info = { + {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}}; + m_client_meta.snap_seqs = {{1, 2}, {3, 4}, {5, 6}}; + MockEventPreprocessor event_preprocessor(mock_local_image_ctx, + mock_remote_journaler, + "local mirror uuid", + &m_client_meta, + m_threads->work_queue); + + librbd::journal::EventEntry event_entry{librbd::journal::RenameEvent{}}; + C_SaferCond ctx; + event_preprocessor.preprocess(&event_entry, &ctx); + ASSERT_EQ(0, ctx.wait()); + + librbd::SnapSeqs expected_snap_seqs = {{5, 6}}; + ASSERT_EQ(expected_snap_seqs, m_client_meta.snap_seqs); +} + +TEST_F(TestMockImageReplayerJournalEventPreprocessor, PreprocessSnapRename) { + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); + ::journal::MockJournaler mock_remote_journaler; + + expect_image_refresh(mock_local_image_ctx, 0); + expect_update_client(mock_remote_journaler, 0); + + mock_local_image_ctx.snap_ids = {{{cls::rbd::UserSnapshotNamespace(), "snap"}, 6}}; + mock_local_image_ctx.snap_info = { + {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}}; + MockEventPreprocessor event_preprocessor(mock_local_image_ctx, + mock_remote_journaler, + "local mirror uuid", + &m_client_meta, + m_threads->work_queue); + + librbd::journal::EventEntry event_entry{ + librbd::journal::SnapRenameEvent{0, 5, "snap", "new_snap"}}; + C_SaferCond ctx; + event_preprocessor.preprocess(&event_entry, &ctx); + ASSERT_EQ(0, ctx.wait()); + + librbd::SnapSeqs expected_snap_seqs = {{5, 6}}; + ASSERT_EQ(expected_snap_seqs, m_client_meta.snap_seqs); + + librbd::journal::SnapRenameEvent *event = + boost::get(&event_entry.event); + ASSERT_EQ(6U, event->snap_id); +} + +TEST_F(TestMockImageReplayerJournalEventPreprocessor, PreprocessSnapRenameMissing) { + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); + ::journal::MockJournaler mock_remote_journaler; + + expect_image_refresh(mock_local_image_ctx, 0); + + MockEventPreprocessor event_preprocessor(mock_local_image_ctx, + mock_remote_journaler, + "local mirror uuid", + &m_client_meta, + m_threads->work_queue); + + librbd::journal::EventEntry event_entry{ + librbd::journal::SnapRenameEvent{0, 5, "snap", "new_snap"}}; + C_SaferCond ctx; + event_preprocessor.preprocess(&event_entry, &ctx); + ASSERT_EQ(-ENOENT, ctx.wait()); + + librbd::journal::SnapRenameEvent *event = + boost::get(&event_entry.event); + ASSERT_EQ(CEPH_NOSNAP, event->snap_id); +} + +TEST_F(TestMockImageReplayerJournalEventPreprocessor, PreprocessSnapRenameKnown) { + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); + ::journal::MockJournaler mock_remote_journaler; + + expect_image_refresh(mock_local_image_ctx, 0); + + mock_local_image_ctx.snap_info = { + {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}}; + m_client_meta.snap_seqs = {{5, 6}}; + MockEventPreprocessor event_preprocessor(mock_local_image_ctx, + mock_remote_journaler, + "local mirror uuid", + &m_client_meta, + m_threads->work_queue); + + librbd::journal::EventEntry event_entry{ + librbd::journal::SnapRenameEvent{0, 5, "snap", "new_snap"}}; + C_SaferCond ctx; + event_preprocessor.preprocess(&event_entry, &ctx); + ASSERT_EQ(0, ctx.wait()); + + librbd::SnapSeqs expected_snap_seqs = {{5, 6}}; + ASSERT_EQ(expected_snap_seqs, m_client_meta.snap_seqs); + + librbd::journal::SnapRenameEvent *event = + boost::get(&event_entry.event); + ASSERT_EQ(6U, event->snap_id); +} + +TEST_F(TestMockImageReplayerJournalEventPreprocessor, PreprocessRefreshError) { + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); + ::journal::MockJournaler mock_remote_journaler; + + expect_image_refresh(mock_local_image_ctx, -EINVAL); + + MockEventPreprocessor event_preprocessor(mock_local_image_ctx, + mock_remote_journaler, + "local mirror uuid", + &m_client_meta, + m_threads->work_queue); + + librbd::journal::EventEntry event_entry{librbd::journal::RenameEvent{}}; + C_SaferCond ctx; + event_preprocessor.preprocess(&event_entry, &ctx); + ASSERT_EQ(-EINVAL, ctx.wait()); +} + +TEST_F(TestMockImageReplayerJournalEventPreprocessor, PreprocessClientUpdateError) { + librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); + ::journal::MockJournaler mock_remote_journaler; + + expect_image_refresh(mock_local_image_ctx, 0); + expect_update_client(mock_remote_journaler, -EINVAL); + + mock_local_image_ctx.snap_ids = {{{cls::rbd::UserSnapshotNamespace(), "snap"}, 6}}; + mock_local_image_ctx.snap_info = { + {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}}; + MockEventPreprocessor event_preprocessor(mock_local_image_ctx, + mock_remote_journaler, + "local mirror uuid", + &m_client_meta, + m_threads->work_queue); + + librbd::journal::EventEntry event_entry{ + librbd::journal::SnapRenameEvent{0, 5, "snap", "new_snap"}}; + C_SaferCond ctx; + event_preprocessor.preprocess(&event_entry, &ctx); + ASSERT_EQ(-EINVAL, ctx.wait()); +} + +} // namespace journal +} // namespace image_replayer +} // namespace mirror +} // namespace rbd diff --git a/src/test/rbd_mirror/image_replayer/test_mock_EventPreprocessor.cc b/src/test/rbd_mirror/image_replayer/test_mock_EventPreprocessor.cc deleted file mode 100644 index 9e02a82f38ddc..0000000000000 --- a/src/test/rbd_mirror/image_replayer/test_mock_EventPreprocessor.cc +++ /dev/null @@ -1,265 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab - -#include "test/rbd_mirror/test_mock_fixture.h" -#include "librbd/journal/Types.h" -#include "librbd/journal/TypeTraits.h" -#include "tools/rbd_mirror/image_replayer/EventPreprocessor.h" -#include "tools/rbd_mirror/Threads.h" -#include "test/journal/mock/MockJournaler.h" -#include "test/librbd/mock/MockImageCtx.h" - -namespace librbd { - -namespace { - -struct MockTestImageCtx : public librbd::MockImageCtx { - explicit MockTestImageCtx(librbd::ImageCtx &image_ctx) - : librbd::MockImageCtx(image_ctx) { - } -}; - -} // anonymous namespace - -namespace journal { - -template <> -struct TypeTraits { - typedef ::journal::MockJournaler Journaler; -}; - -} // namespace journal -} // namespace librbd - -// template definitions -#include "tools/rbd_mirror/image_replayer/EventPreprocessor.cc" -template class rbd::mirror::image_replayer::EventPreprocessor; - -namespace rbd { -namespace mirror { -namespace image_replayer { - -using testing::_; -using testing::WithArg; - -class TestMockImageReplayerEventPreprocessor : public TestMockFixture { -public: - typedef EventPreprocessor MockEventPreprocessor; - - void SetUp() override { - TestMockFixture::SetUp(); - - librbd::RBD rbd; - ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size)); - ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &m_local_image_ctx)); - } - - void expect_image_refresh(librbd::MockTestImageCtx &mock_remote_image_ctx, int r) { - EXPECT_CALL(*mock_remote_image_ctx.state, refresh(_)) - .WillOnce(CompleteContext(r)); - } - - void expect_update_client(journal::MockJournaler &mock_journaler, int r) { - EXPECT_CALL(mock_journaler, update_client(_, _)) - .WillOnce(WithArg<1>(CompleteContext(r))); - } - - librbd::ImageCtx *m_local_image_ctx; - librbd::journal::MirrorPeerClientMeta m_client_meta; - -}; - -TEST_F(TestMockImageReplayerEventPreprocessor, IsNotRequired) { - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - ::journal::MockJournaler mock_remote_journaler; - - MockEventPreprocessor event_preprocessor(mock_local_image_ctx, - mock_remote_journaler, - "local mirror uuid", - &m_client_meta, - m_threads->work_queue); - - librbd::journal::EventEntry event_entry{librbd::journal::RenameEvent{}}; - ASSERT_FALSE(event_preprocessor.is_required(event_entry)); -} - -TEST_F(TestMockImageReplayerEventPreprocessor, IsRequiredSnapMapPrune) { - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - ::journal::MockJournaler mock_remote_journaler; - - m_client_meta.snap_seqs = {{1, 2}, {3, 4}}; - MockEventPreprocessor event_preprocessor(mock_local_image_ctx, - mock_remote_journaler, - "local mirror uuid", - &m_client_meta, - m_threads->work_queue); - - librbd::journal::EventEntry event_entry{librbd::journal::RenameEvent{}}; - ASSERT_TRUE(event_preprocessor.is_required(event_entry)); -} - -TEST_F(TestMockImageReplayerEventPreprocessor, IsRequiredSnapRename) { - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - ::journal::MockJournaler mock_remote_journaler; - - MockEventPreprocessor event_preprocessor(mock_local_image_ctx, - mock_remote_journaler, - "local mirror uuid", - &m_client_meta, - m_threads->work_queue); - - librbd::journal::EventEntry event_entry{librbd::journal::SnapRenameEvent{}}; - ASSERT_TRUE(event_preprocessor.is_required(event_entry)); -} - -TEST_F(TestMockImageReplayerEventPreprocessor, PreprocessSnapMapPrune) { - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - ::journal::MockJournaler mock_remote_journaler; - - expect_image_refresh(mock_local_image_ctx, 0); - expect_update_client(mock_remote_journaler, 0); - - mock_local_image_ctx.snap_info = { - {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}}; - m_client_meta.snap_seqs = {{1, 2}, {3, 4}, {5, 6}}; - MockEventPreprocessor event_preprocessor(mock_local_image_ctx, - mock_remote_journaler, - "local mirror uuid", - &m_client_meta, - m_threads->work_queue); - - librbd::journal::EventEntry event_entry{librbd::journal::RenameEvent{}}; - C_SaferCond ctx; - event_preprocessor.preprocess(&event_entry, &ctx); - ASSERT_EQ(0, ctx.wait()); - - librbd::SnapSeqs expected_snap_seqs = {{5, 6}}; - ASSERT_EQ(expected_snap_seqs, m_client_meta.snap_seqs); -} - -TEST_F(TestMockImageReplayerEventPreprocessor, PreprocessSnapRename) { - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - ::journal::MockJournaler mock_remote_journaler; - - expect_image_refresh(mock_local_image_ctx, 0); - expect_update_client(mock_remote_journaler, 0); - - mock_local_image_ctx.snap_ids = {{{cls::rbd::UserSnapshotNamespace(), "snap"}, 6}}; - mock_local_image_ctx.snap_info = { - {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}}; - MockEventPreprocessor event_preprocessor(mock_local_image_ctx, - mock_remote_journaler, - "local mirror uuid", - &m_client_meta, - m_threads->work_queue); - - librbd::journal::EventEntry event_entry{ - librbd::journal::SnapRenameEvent{0, 5, "snap", "new_snap"}}; - C_SaferCond ctx; - event_preprocessor.preprocess(&event_entry, &ctx); - ASSERT_EQ(0, ctx.wait()); - - librbd::SnapSeqs expected_snap_seqs = {{5, 6}}; - ASSERT_EQ(expected_snap_seqs, m_client_meta.snap_seqs); - - librbd::journal::SnapRenameEvent *event = - boost::get(&event_entry.event); - ASSERT_EQ(6U, event->snap_id); -} - -TEST_F(TestMockImageReplayerEventPreprocessor, PreprocessSnapRenameMissing) { - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - ::journal::MockJournaler mock_remote_journaler; - - expect_image_refresh(mock_local_image_ctx, 0); - - MockEventPreprocessor event_preprocessor(mock_local_image_ctx, - mock_remote_journaler, - "local mirror uuid", - &m_client_meta, - m_threads->work_queue); - - librbd::journal::EventEntry event_entry{ - librbd::journal::SnapRenameEvent{0, 5, "snap", "new_snap"}}; - C_SaferCond ctx; - event_preprocessor.preprocess(&event_entry, &ctx); - ASSERT_EQ(-ENOENT, ctx.wait()); - - librbd::journal::SnapRenameEvent *event = - boost::get(&event_entry.event); - ASSERT_EQ(CEPH_NOSNAP, event->snap_id); -} - -TEST_F(TestMockImageReplayerEventPreprocessor, PreprocessSnapRenameKnown) { - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - ::journal::MockJournaler mock_remote_journaler; - - expect_image_refresh(mock_local_image_ctx, 0); - - mock_local_image_ctx.snap_info = { - {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}}; - m_client_meta.snap_seqs = {{5, 6}}; - MockEventPreprocessor event_preprocessor(mock_local_image_ctx, - mock_remote_journaler, - "local mirror uuid", - &m_client_meta, - m_threads->work_queue); - - librbd::journal::EventEntry event_entry{ - librbd::journal::SnapRenameEvent{0, 5, "snap", "new_snap"}}; - C_SaferCond ctx; - event_preprocessor.preprocess(&event_entry, &ctx); - ASSERT_EQ(0, ctx.wait()); - - librbd::SnapSeqs expected_snap_seqs = {{5, 6}}; - ASSERT_EQ(expected_snap_seqs, m_client_meta.snap_seqs); - - librbd::journal::SnapRenameEvent *event = - boost::get(&event_entry.event); - ASSERT_EQ(6U, event->snap_id); -} - -TEST_F(TestMockImageReplayerEventPreprocessor, PreprocessRefreshError) { - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - ::journal::MockJournaler mock_remote_journaler; - - expect_image_refresh(mock_local_image_ctx, -EINVAL); - - MockEventPreprocessor event_preprocessor(mock_local_image_ctx, - mock_remote_journaler, - "local mirror uuid", - &m_client_meta, - m_threads->work_queue); - - librbd::journal::EventEntry event_entry{librbd::journal::RenameEvent{}}; - C_SaferCond ctx; - event_preprocessor.preprocess(&event_entry, &ctx); - ASSERT_EQ(-EINVAL, ctx.wait()); -} - -TEST_F(TestMockImageReplayerEventPreprocessor, PreprocessClientUpdateError) { - librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - ::journal::MockJournaler mock_remote_journaler; - - expect_image_refresh(mock_local_image_ctx, 0); - expect_update_client(mock_remote_journaler, -EINVAL); - - mock_local_image_ctx.snap_ids = {{{cls::rbd::UserSnapshotNamespace(), "snap"}, 6}}; - mock_local_image_ctx.snap_info = { - {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}}; - MockEventPreprocessor event_preprocessor(mock_local_image_ctx, - mock_remote_journaler, - "local mirror uuid", - &m_client_meta, - m_threads->work_queue); - - librbd::journal::EventEntry event_entry{ - librbd::journal::SnapRenameEvent{0, 5, "snap", "new_snap"}}; - C_SaferCond ctx; - event_preprocessor.preprocess(&event_entry, &ctx); - ASSERT_EQ(-EINVAL, ctx.wait()); -} - -} // namespace image_replayer -} // namespace mirror -} // namespace rbd diff --git a/src/test/rbd_mirror/test_mock_ImageReplayer.cc b/src/test/rbd_mirror/test_mock_ImageReplayer.cc index a47b4456e6f65..3b4d596ed55b0 100644 --- a/src/test/rbd_mirror/test_mock_ImageReplayer.cc +++ b/src/test/rbd_mirror/test_mock_ImageReplayer.cc @@ -11,9 +11,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/EventPreprocessor.h" #include "tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.h" #include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.h" +#include "tools/rbd_mirror/image_replayer/journal/EventPreprocessor.h" #include "tools/rbd_mirror/image_replayer/journal/ReplayStatusFormatter.h" #include "test/rbd_mirror/test_mock_fixture.h" #include "test/journal/mock/MockJournaler.h" @@ -270,6 +270,13 @@ struct CloseImageRequest { MOCK_METHOD0(send, void()); }; +BootstrapRequest* BootstrapRequest::s_instance = nullptr; +CloseImageRequest* CloseImageRequest::s_instance = nullptr; +PrepareLocalImageRequest* PrepareLocalImageRequest::s_instance = nullptr; +PrepareRemoteImageRequest* PrepareRemoteImageRequest::s_instance = nullptr; + +namespace journal { + template<> struct EventPreprocessor { static EventPreprocessor *s_instance; @@ -300,14 +307,6 @@ struct EventPreprocessor { MOCK_METHOD2(preprocess, void(librbd::journal::EventEntry *, Context *)); }; -BootstrapRequest* BootstrapRequest::s_instance = nullptr; -CloseImageRequest* CloseImageRequest::s_instance = nullptr; -EventPreprocessor* EventPreprocessor::s_instance = nullptr; -PrepareLocalImageRequest* PrepareLocalImageRequest::s_instance = nullptr; -PrepareRemoteImageRequest* PrepareRemoteImageRequest::s_instance = nullptr; - -namespace journal { - template<> struct ReplayStatusFormatter { static ReplayStatusFormatter* s_instance; @@ -334,6 +333,7 @@ struct ReplayStatusFormatter { MOCK_METHOD2(get_or_send_update, bool(std::string *description, Context *on_finish)); }; +EventPreprocessor* EventPreprocessor::s_instance = nullptr; ReplayStatusFormatter* ReplayStatusFormatter::s_instance = nullptr; } // namespace journal @@ -365,9 +365,9 @@ public: typedef MirrorStatusUpdater MockMirrorStatusUpdater; typedef image_replayer::BootstrapRequest MockBootstrapRequest; typedef image_replayer::CloseImageRequest MockCloseImageRequest; - typedef image_replayer::EventPreprocessor MockEventPreprocessor; typedef image_replayer::PrepareLocalImageRequest MockPrepareLocalImageRequest; typedef image_replayer::PrepareRemoteImageRequest MockPrepareRemoteImageRequest; + typedef image_replayer::journal::EventPreprocessor MockEventPreprocessor; typedef image_replayer::journal::ReplayStatusFormatter MockReplayStatusFormatter; typedef librbd::journal::Replay MockReplay; typedef ImageReplayer MockImageReplayer; diff --git a/src/tools/rbd_mirror/CMakeLists.txt b/src/tools/rbd_mirror/CMakeLists.txt index 736dbe9246cb1..cdac9c614c42b 100644 --- a/src/tools/rbd_mirror/CMakeLists.txt +++ b/src/tools/rbd_mirror/CMakeLists.txt @@ -35,13 +35,13 @@ set(rbd_mirror_internal image_replayer/BootstrapRequest.cc image_replayer/CloseImageRequest.cc image_replayer/CreateImageRequest.cc - image_replayer/EventPreprocessor.cc image_replayer/GetMirrorImageIdRequest.cc image_replayer/OpenImageRequest.cc image_replayer/OpenLocalImageRequest.cc image_replayer/PrepareLocalImageRequest.cc image_replayer/PrepareRemoteImageRequest.cc image_replayer/Utils.cc + image_replayer/journal/EventPreprocessor.cc image_replayer/journal/ReplayStatusFormatter.cc image_sync/SyncPointCreateRequest.cc image_sync/SyncPointPruneRequest.cc diff --git a/src/tools/rbd_mirror/ImageReplayer.cc b/src/tools/rbd_mirror/ImageReplayer.cc index 9933dd7509b17..42ef95606184d 100644 --- a/src/tools/rbd_mirror/ImageReplayer.cc +++ b/src/tools/rbd_mirror/ImageReplayer.cc @@ -27,9 +27,9 @@ #include "Threads.h" #include "tools/rbd_mirror/image_replayer/BootstrapRequest.h" #include "tools/rbd_mirror/image_replayer/CloseImageRequest.h" -#include "tools/rbd_mirror/image_replayer/EventPreprocessor.h" #include "tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.h" #include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.h" +#include "tools/rbd_mirror/image_replayer/journal/EventPreprocessor.h" #include "tools/rbd_mirror/image_replayer/journal/ReplayStatusFormatter.h" #define dout_context g_ceph_context @@ -633,7 +633,7 @@ void ImageReplayer::handle_start_replay(int r) { std::swap(m_on_start_finish, on_finish); } - m_event_preprocessor = image_replayer::EventPreprocessor::create( + m_event_preprocessor = image_replayer::journal::EventPreprocessor::create( *m_local_image_ctx, *m_remote_journaler, m_local_mirror_uuid, &m_client_meta, m_threads->work_queue); @@ -1543,7 +1543,8 @@ void ImageReplayer::shut_down(int r) { m_local_journal->stop_external_replay(); m_local_replay = nullptr; - image_replayer::EventPreprocessor::destroy(m_event_preprocessor); + image_replayer::journal::EventPreprocessor::destroy( + m_event_preprocessor); m_event_preprocessor = nullptr; ctx->complete(0); }); diff --git a/src/tools/rbd_mirror/ImageReplayer.h b/src/tools/rbd_mirror/ImageReplayer.h index 29613c87cac6d..f121f02e53efc 100644 --- a/src/tools/rbd_mirror/ImageReplayer.h +++ b/src/tools/rbd_mirror/ImageReplayer.h @@ -56,10 +56,13 @@ template struct Threads; namespace image_replayer { template class BootstrapRequest; -template class EventPreprocessor; -namespace journal { template class ReplayStatusFormatter; } +namespace journal { +template class EventPreprocessor; +template class ReplayStatusFormatter; + +} // namespace journal } // namespace image_replayer /** @@ -311,7 +314,8 @@ private: bool m_delete_requested = false; bool m_resync_requested = false; - image_replayer::EventPreprocessor *m_event_preprocessor = nullptr; + image_replayer::journal::EventPreprocessor* + m_event_preprocessor = nullptr; image_replayer::journal::ReplayStatusFormatter* m_replay_status_formatter = nullptr; ImageCtxT *m_local_image_ctx = nullptr; diff --git a/src/tools/rbd_mirror/image_replayer/EventPreprocessor.cc b/src/tools/rbd_mirror/image_replayer/EventPreprocessor.cc deleted file mode 100644 index 9034ca4f64258..0000000000000 --- a/src/tools/rbd_mirror/image_replayer/EventPreprocessor.cc +++ /dev/null @@ -1,204 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab - -#include "EventPreprocessor.h" -#include "common/debug.h" -#include "common/dout.h" -#include "common/errno.h" -#include "common/WorkQueue.h" -#include "journal/Journaler.h" -#include "librbd/ImageCtx.h" -#include "librbd/ImageState.h" -#include "librbd/Utils.h" -#include "librbd/journal/Types.h" -#include - -#define dout_context g_ceph_context -#define dout_subsys ceph_subsys_rbd_mirror - -#undef dout_prefix -#define dout_prefix *_dout << "rbd::mirror::image_replayer::EventPreprocessor: " \ - << this << " " << __func__ - -namespace rbd { -namespace mirror { -namespace image_replayer { - -using librbd::util::create_context_callback; - -template -EventPreprocessor::EventPreprocessor(I &local_image_ctx, - Journaler &remote_journaler, - const std::string &local_mirror_uuid, - MirrorPeerClientMeta *client_meta, - ContextWQ *work_queue) - : m_local_image_ctx(local_image_ctx), m_remote_journaler(remote_journaler), - m_local_mirror_uuid(local_mirror_uuid), m_client_meta(client_meta), - m_work_queue(work_queue) { -} - -template -EventPreprocessor::~EventPreprocessor() { - ceph_assert(!m_in_progress); -} - -template -bool EventPreprocessor::is_required(const EventEntry &event_entry) { - SnapSeqs snap_seqs(m_client_meta->snap_seqs); - return (prune_snap_map(&snap_seqs) || - event_entry.get_event_type() == - librbd::journal::EVENT_TYPE_SNAP_RENAME); -} - -template -void EventPreprocessor::preprocess(EventEntry *event_entry, - Context *on_finish) { - ceph_assert(!m_in_progress); - m_in_progress = true; - m_event_entry = event_entry; - m_on_finish = on_finish; - - refresh_image(); -} - -template -void EventPreprocessor::refresh_image() { - dout(20) << dendl; - - Context *ctx = create_context_callback< - EventPreprocessor, &EventPreprocessor::handle_refresh_image>(this); - m_local_image_ctx.state->refresh(ctx); -} - -template -void EventPreprocessor::handle_refresh_image(int r) { - dout(20) << ": r=" << r << dendl; - - if (r < 0) { - derr << "error encountered during image refresh: " << cpp_strerror(r) - << dendl; - finish(r); - return; - } - - preprocess_event(); -} - -template -void EventPreprocessor::preprocess_event() { - dout(20) << dendl; - - m_snap_seqs = m_client_meta->snap_seqs; - m_snap_seqs_updated = prune_snap_map(&m_snap_seqs); - - int r = boost::apply_visitor(PreprocessEventVisitor(this), - m_event_entry->event); - if (r < 0) { - finish(r); - return; - } - - update_client(); -} - -template -int EventPreprocessor::preprocess_snap_rename( - librbd::journal::SnapRenameEvent &event) { - dout(20) << ": " - << "remote_snap_id=" << event.snap_id << ", " - << "src_snap_name=" << event.src_snap_name << ", " - << "dest_snap_name=" << event.dst_snap_name << dendl; - - auto snap_seq_it = m_snap_seqs.find(event.snap_id); - if (snap_seq_it != m_snap_seqs.end()) { - dout(20) << ": remapping remote snap id " << snap_seq_it->first << " " - << "to local snap id " << snap_seq_it->second << dendl; - event.snap_id = snap_seq_it->second; - return 0; - } - - auto snap_id_it = m_local_image_ctx.snap_ids.find({cls::rbd::UserSnapshotNamespace(), - event.src_snap_name}); - if (snap_id_it == m_local_image_ctx.snap_ids.end()) { - dout(20) << ": cannot map remote snapshot '" << event.src_snap_name << "' " - << "to local snapshot" << dendl; - event.snap_id = CEPH_NOSNAP; - return -ENOENT; - } - - dout(20) << ": mapping remote snap id " << event.snap_id << " " - << "to local snap id " << snap_id_it->second << dendl; - m_snap_seqs_updated = true; - m_snap_seqs[event.snap_id] = snap_id_it->second; - event.snap_id = snap_id_it->second; - return 0; -} - -template -void EventPreprocessor::update_client() { - if (!m_snap_seqs_updated) { - finish(0); - return; - } - - dout(20) << dendl; - librbd::journal::MirrorPeerClientMeta client_meta(*m_client_meta); - client_meta.snap_seqs = m_snap_seqs; - - librbd::journal::ClientData client_data(client_meta); - bufferlist data_bl; - encode(client_data, data_bl); - - Context *ctx = create_context_callback< - EventPreprocessor, &EventPreprocessor::handle_update_client>( - this); - m_remote_journaler.update_client(data_bl, ctx); -} - -template -void EventPreprocessor::handle_update_client(int r) { - dout(20) << ": r=" << r << dendl; - - if (r < 0) { - derr << "failed to update mirror peer journal client: " - << cpp_strerror(r) << dendl; - finish(r); - return; - } - - m_client_meta->snap_seqs = m_snap_seqs; - finish(0); -} - -template -bool EventPreprocessor::prune_snap_map(SnapSeqs *snap_seqs) { - bool pruned = false; - - std::shared_lock image_locker{m_local_image_ctx.image_lock}; - for (auto it = snap_seqs->begin(); it != snap_seqs->end(); ) { - auto current_it(it++); - if (m_local_image_ctx.snap_info.count(current_it->second) == 0) { - snap_seqs->erase(current_it); - pruned = true; - } - } - return pruned; -} - -template -void EventPreprocessor::finish(int r) { - dout(20) << ": r=" << r << dendl; - - Context *on_finish = m_on_finish; - m_on_finish = nullptr; - m_event_entry = nullptr; - m_in_progress = false; - m_snap_seqs_updated = false; - m_work_queue->queue(on_finish, r); -} - -} // namespace image_replayer -} // namespace mirror -} // namespace rbd - -template class rbd::mirror::image_replayer::EventPreprocessor; diff --git a/src/tools/rbd_mirror/image_replayer/EventPreprocessor.h b/src/tools/rbd_mirror/image_replayer/EventPreprocessor.h deleted file mode 100644 index 67aeea0b80752..0000000000000 --- a/src/tools/rbd_mirror/image_replayer/EventPreprocessor.h +++ /dev/null @@ -1,122 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab - -#ifndef RBD_MIRROR_IMAGE_REPLAYER_EVENT_PREPROCESSOR_H -#define RBD_MIRROR_IMAGE_REPLAYER_EVENT_PREPROCESSOR_H - -#include "include/int_types.h" -#include "librbd/journal/Types.h" -#include "librbd/journal/TypeTraits.h" -#include -#include -#include - -struct Context; -struct ContextWQ; -namespace journal { class Journaler; } -namespace librbd { class ImageCtx; } - -namespace rbd { -namespace mirror { -namespace image_replayer { - -template -class EventPreprocessor { -public: - using Journaler = typename librbd::journal::TypeTraits::Journaler; - using EventEntry = librbd::journal::EventEntry; - using MirrorPeerClientMeta = librbd::journal::MirrorPeerClientMeta; - - static EventPreprocessor *create(ImageCtxT &local_image_ctx, - Journaler &remote_journaler, - const std::string &local_mirror_uuid, - MirrorPeerClientMeta *client_meta, - ContextWQ *work_queue) { - return new EventPreprocessor(local_image_ctx, remote_journaler, - local_mirror_uuid, client_meta, work_queue); - } - - static void destroy(EventPreprocessor* processor) { - delete processor; - } - - EventPreprocessor(ImageCtxT &local_image_ctx, Journaler &remote_journaler, - const std::string &local_mirror_uuid, - MirrorPeerClientMeta *client_meta, ContextWQ *work_queue); - ~EventPreprocessor(); - - bool is_required(const EventEntry &event_entry); - void preprocess(EventEntry *event_entry, Context *on_finish); - -private: - /** - * @verbatim - * - * - * | - * v (skip if not required) - * REFRESH_IMAGE - * | - * v (skip if not required) - * PREPROCESS_EVENT - * | - * v (skip if not required) - * UPDATE_CLIENT - * - * @endverbatim - */ - - typedef std::map SnapSeqs; - - class PreprocessEventVisitor : public boost::static_visitor { - public: - EventPreprocessor *event_preprocessor; - - PreprocessEventVisitor(EventPreprocessor *event_preprocessor) - : event_preprocessor(event_preprocessor) { - } - - template - inline int operator()(T&) const { - return 0; - } - inline int operator()(librbd::journal::SnapRenameEvent &event) const { - return event_preprocessor->preprocess_snap_rename(event); - } - }; - - ImageCtxT &m_local_image_ctx; - Journaler &m_remote_journaler; - std::string m_local_mirror_uuid; - MirrorPeerClientMeta *m_client_meta; - ContextWQ *m_work_queue; - - bool m_in_progress = false; - EventEntry *m_event_entry = nullptr; - Context *m_on_finish = nullptr; - - SnapSeqs m_snap_seqs; - bool m_snap_seqs_updated = false; - - bool prune_snap_map(SnapSeqs *snap_seqs); - - void refresh_image(); - void handle_refresh_image(int r); - - void preprocess_event(); - int preprocess_snap_rename(librbd::journal::SnapRenameEvent &event); - - void update_client(); - void handle_update_client(int r); - - void finish(int r); - -}; - -} // namespace image_replayer -} // namespace mirror -} // namespace rbd - -extern template class rbd::mirror::image_replayer::EventPreprocessor; - -#endif // RBD_MIRROR_IMAGE_REPLAYER_EVENT_PREPROCESSOR_H diff --git a/src/tools/rbd_mirror/image_replayer/journal/EventPreprocessor.cc b/src/tools/rbd_mirror/image_replayer/journal/EventPreprocessor.cc new file mode 100644 index 0000000000000..c1568073cf336 --- /dev/null +++ b/src/tools/rbd_mirror/image_replayer/journal/EventPreprocessor.cc @@ -0,0 +1,206 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "EventPreprocessor.h" +#include "common/debug.h" +#include "common/dout.h" +#include "common/errno.h" +#include "common/WorkQueue.h" +#include "journal/Journaler.h" +#include "librbd/ImageCtx.h" +#include "librbd/ImageState.h" +#include "librbd/Utils.h" +#include "librbd/journal/Types.h" +#include + +#define dout_context g_ceph_context +#define dout_subsys ceph_subsys_rbd_mirror + +#undef dout_prefix +#define dout_prefix *_dout << "rbd::mirror::image_replayer::journal::" \ + << "EventPreprocessor: " << this << " " << __func__ \ + << ": " + +namespace rbd { +namespace mirror { +namespace image_replayer { +namespace journal { + +using librbd::util::create_context_callback; + +template +EventPreprocessor::EventPreprocessor(I &local_image_ctx, + Journaler &remote_journaler, + const std::string &local_mirror_uuid, + MirrorPeerClientMeta *client_meta, + ContextWQ *work_queue) + : m_local_image_ctx(local_image_ctx), m_remote_journaler(remote_journaler), + m_local_mirror_uuid(local_mirror_uuid), m_client_meta(client_meta), + m_work_queue(work_queue) { +} + +template +EventPreprocessor::~EventPreprocessor() { + ceph_assert(!m_in_progress); +} + +template +bool EventPreprocessor::is_required(const EventEntry &event_entry) { + SnapSeqs snap_seqs(m_client_meta->snap_seqs); + return (prune_snap_map(&snap_seqs) || + event_entry.get_event_type() == + librbd::journal::EVENT_TYPE_SNAP_RENAME); +} + +template +void EventPreprocessor::preprocess(EventEntry *event_entry, + Context *on_finish) { + ceph_assert(!m_in_progress); + m_in_progress = true; + m_event_entry = event_entry; + m_on_finish = on_finish; + + refresh_image(); +} + +template +void EventPreprocessor::refresh_image() { + dout(20) << dendl; + + Context *ctx = create_context_callback< + EventPreprocessor, &EventPreprocessor::handle_refresh_image>(this); + m_local_image_ctx.state->refresh(ctx); +} + +template +void EventPreprocessor::handle_refresh_image(int r) { + dout(20) << "r=" << r << dendl; + + if (r < 0) { + derr << "error encountered during image refresh: " << cpp_strerror(r) + << dendl; + finish(r); + return; + } + + preprocess_event(); +} + +template +void EventPreprocessor::preprocess_event() { + dout(20) << dendl; + + m_snap_seqs = m_client_meta->snap_seqs; + m_snap_seqs_updated = prune_snap_map(&m_snap_seqs); + + int r = boost::apply_visitor(PreprocessEventVisitor(this), + m_event_entry->event); + if (r < 0) { + finish(r); + return; + } + + update_client(); +} + +template +int EventPreprocessor::preprocess_snap_rename( + librbd::journal::SnapRenameEvent &event) { + dout(20) << "remote_snap_id=" << event.snap_id << ", " + << "src_snap_name=" << event.src_snap_name << ", " + << "dest_snap_name=" << event.dst_snap_name << dendl; + + auto snap_seq_it = m_snap_seqs.find(event.snap_id); + if (snap_seq_it != m_snap_seqs.end()) { + dout(20) << "remapping remote snap id " << snap_seq_it->first << " " + << "to local snap id " << snap_seq_it->second << dendl; + event.snap_id = snap_seq_it->second; + return 0; + } + + auto snap_id_it = m_local_image_ctx.snap_ids.find({cls::rbd::UserSnapshotNamespace(), + event.src_snap_name}); + if (snap_id_it == m_local_image_ctx.snap_ids.end()) { + dout(20) << "cannot map remote snapshot '" << event.src_snap_name << "' " + << "to local snapshot" << dendl; + event.snap_id = CEPH_NOSNAP; + return -ENOENT; + } + + dout(20) << "mapping remote snap id " << event.snap_id << " " + << "to local snap id " << snap_id_it->second << dendl; + m_snap_seqs_updated = true; + m_snap_seqs[event.snap_id] = snap_id_it->second; + event.snap_id = snap_id_it->second; + return 0; +} + +template +void EventPreprocessor::update_client() { + if (!m_snap_seqs_updated) { + finish(0); + return; + } + + dout(20) << dendl; + librbd::journal::MirrorPeerClientMeta client_meta(*m_client_meta); + client_meta.snap_seqs = m_snap_seqs; + + librbd::journal::ClientData client_data(client_meta); + bufferlist data_bl; + encode(client_data, data_bl); + + Context *ctx = create_context_callback< + EventPreprocessor, &EventPreprocessor::handle_update_client>( + this); + m_remote_journaler.update_client(data_bl, ctx); +} + +template +void EventPreprocessor::handle_update_client(int r) { + dout(20) << "r=" << r << dendl; + + if (r < 0) { + derr << "failed to update mirror peer journal client: " + << cpp_strerror(r) << dendl; + finish(r); + return; + } + + m_client_meta->snap_seqs = m_snap_seqs; + finish(0); +} + +template +bool EventPreprocessor::prune_snap_map(SnapSeqs *snap_seqs) { + bool pruned = false; + + std::shared_lock image_locker{m_local_image_ctx.image_lock}; + for (auto it = snap_seqs->begin(); it != snap_seqs->end(); ) { + auto current_it(it++); + if (m_local_image_ctx.snap_info.count(current_it->second) == 0) { + snap_seqs->erase(current_it); + pruned = true; + } + } + return pruned; +} + +template +void EventPreprocessor::finish(int r) { + dout(20) << "r=" << r << dendl; + + Context *on_finish = m_on_finish; + m_on_finish = nullptr; + m_event_entry = nullptr; + m_in_progress = false; + m_snap_seqs_updated = false; + m_work_queue->queue(on_finish, r); +} + +} // namespace journal +} // namespace image_replayer +} // namespace mirror +} // namespace rbd + +template class rbd::mirror::image_replayer::journal::EventPreprocessor; diff --git a/src/tools/rbd_mirror/image_replayer/journal/EventPreprocessor.h b/src/tools/rbd_mirror/image_replayer/journal/EventPreprocessor.h new file mode 100644 index 0000000000000..5844e6f748376 --- /dev/null +++ b/src/tools/rbd_mirror/image_replayer/journal/EventPreprocessor.h @@ -0,0 +1,124 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef RBD_MIRROR_IMAGE_REPLAYER_EVENT_PREPROCESSOR_H +#define RBD_MIRROR_IMAGE_REPLAYER_EVENT_PREPROCESSOR_H + +#include "include/int_types.h" +#include "librbd/journal/Types.h" +#include "librbd/journal/TypeTraits.h" +#include +#include +#include + +struct Context; +struct ContextWQ; +namespace journal { class Journaler; } +namespace librbd { class ImageCtx; } + +namespace rbd { +namespace mirror { +namespace image_replayer { +namespace journal { + +template +class EventPreprocessor { +public: + using Journaler = typename librbd::journal::TypeTraits::Journaler; + using EventEntry = librbd::journal::EventEntry; + using MirrorPeerClientMeta = librbd::journal::MirrorPeerClientMeta; + + static EventPreprocessor *create(ImageCtxT &local_image_ctx, + Journaler &remote_journaler, + const std::string &local_mirror_uuid, + MirrorPeerClientMeta *client_meta, + ContextWQ *work_queue) { + return new EventPreprocessor(local_image_ctx, remote_journaler, + local_mirror_uuid, client_meta, work_queue); + } + + static void destroy(EventPreprocessor* processor) { + delete processor; + } + + EventPreprocessor(ImageCtxT &local_image_ctx, Journaler &remote_journaler, + const std::string &local_mirror_uuid, + MirrorPeerClientMeta *client_meta, ContextWQ *work_queue); + ~EventPreprocessor(); + + bool is_required(const EventEntry &event_entry); + void preprocess(EventEntry *event_entry, Context *on_finish); + +private: + /** + * @verbatim + * + * + * | + * v (skip if not required) + * REFRESH_IMAGE + * | + * v (skip if not required) + * PREPROCESS_EVENT + * | + * v (skip if not required) + * UPDATE_CLIENT + * + * @endverbatim + */ + + typedef std::map SnapSeqs; + + class PreprocessEventVisitor : public boost::static_visitor { + public: + EventPreprocessor *event_preprocessor; + + PreprocessEventVisitor(EventPreprocessor *event_preprocessor) + : event_preprocessor(event_preprocessor) { + } + + template + inline int operator()(T&) const { + return 0; + } + inline int operator()(librbd::journal::SnapRenameEvent &event) const { + return event_preprocessor->preprocess_snap_rename(event); + } + }; + + ImageCtxT &m_local_image_ctx; + Journaler &m_remote_journaler; + std::string m_local_mirror_uuid; + MirrorPeerClientMeta *m_client_meta; + ContextWQ *m_work_queue; + + bool m_in_progress = false; + EventEntry *m_event_entry = nullptr; + Context *m_on_finish = nullptr; + + SnapSeqs m_snap_seqs; + bool m_snap_seqs_updated = false; + + bool prune_snap_map(SnapSeqs *snap_seqs); + + void refresh_image(); + void handle_refresh_image(int r); + + void preprocess_event(); + int preprocess_snap_rename(librbd::journal::SnapRenameEvent &event); + + void update_client(); + void handle_update_client(int r); + + void finish(int r); + +}; + +} // namespace journal +} // namespace image_replayer +} // namespace mirror +} // namespace rbd + +extern template class rbd::mirror::image_replayer::journal::EventPreprocessor; + +#endif // RBD_MIRROR_IMAGE_REPLAYER_EVENT_PREPROCESSOR_H