From 5cf28db7d86a15af833d478f3d9f7782f5503fa6 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 11 Apr 2019 17:01:22 -0400 Subject: [PATCH] rbd-mirror: periodically flush prior to updating status This ensure the most up-to-date commit position is included in the status report. Fixes: http://tracker.ceph.com/issues/39257 Signed-off-by: Jason Dillaman (cherry picked from commit af22cd213c90c6a5a6ae9d7bcc44457ef5b01649) --- src/test/rbd_mirror/test_mock_ImageReplayer.cc | 17 +++++++++++++++++ src/tools/rbd_mirror/ImageReplayer.cc | 10 +++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/test/rbd_mirror/test_mock_ImageReplayer.cc b/src/test/rbd_mirror/test_mock_ImageReplayer.cc index 4683b0d8fdb14..1bd330fd8a452 100644 --- a/src/test/rbd_mirror/test_mock_ImageReplayer.cc +++ b/src/test/rbd_mirror/test_mock_ImageReplayer.cc @@ -396,6 +396,18 @@ public: })); } + void expect_flush_repeatedly(MockReplay& mock_replay, + journal::MockJournaler& mock_journal) { + EXPECT_CALL(mock_replay, flush(_)) + .WillRepeatedly(Invoke([this](Context* ctx) { + m_threads->work_queue->queue(ctx, 0); + })); + EXPECT_CALL(mock_journal, flush_commit_position(_)) + .WillRepeatedly(Invoke([this](Context* ctx) { + m_threads->work_queue->queue(ctx, 0); + })); + } + void expect_trash_move(MockImageDeleter& mock_image_deleter, const std::string& global_image_id, bool ignore_orphan, int r) { @@ -624,6 +636,7 @@ TEST_F(TestMockImageReplayer, StartStop) { MockEventPreprocessor mock_event_preprocessor; MockReplayStatusFormatter mock_replay_status_formatter; + expect_flush_repeatedly(mock_local_replay, mock_remote_journaler); expect_get_or_send_update(mock_replay_status_formatter); InSequence seq; @@ -999,6 +1012,7 @@ TEST_F(TestMockImageReplayer, StopError) { MockEventPreprocessor mock_event_preprocessor; MockReplayStatusFormatter mock_replay_status_formatter; + expect_flush_repeatedly(mock_local_replay, mock_remote_journaler); expect_get_or_send_update(mock_replay_status_formatter); InSequence seq; @@ -1067,6 +1081,7 @@ TEST_F(TestMockImageReplayer, Replay) { MockReplayStatusFormatter mock_replay_status_formatter; ::journal::MockReplayEntry mock_replay_entry; + expect_flush_repeatedly(mock_local_replay, mock_remote_journaler); expect_get_or_send_update(mock_replay_status_formatter); expect_get_commit_tid_in_debug(mock_replay_entry); expect_get_tag_tid_in_debug(mock_local_journal); @@ -1176,6 +1191,7 @@ TEST_F(TestMockImageReplayer, DecodeError) { MockReplayStatusFormatter mock_replay_status_formatter; ::journal::MockReplayEntry mock_replay_entry; + expect_flush_repeatedly(mock_local_replay, mock_remote_journaler); expect_get_or_send_update(mock_replay_status_formatter); expect_get_commit_tid_in_debug(mock_replay_entry); expect_get_tag_tid_in_debug(mock_local_journal); @@ -1277,6 +1293,7 @@ TEST_F(TestMockImageReplayer, DelayedReplay) { MockReplayStatusFormatter mock_replay_status_formatter; ::journal::MockReplayEntry mock_replay_entry; + expect_flush_repeatedly(mock_local_replay, mock_remote_journaler); expect_get_or_send_update(mock_replay_status_formatter); expect_get_commit_tid_in_debug(mock_replay_entry); expect_get_tag_tid_in_debug(mock_local_journal); diff --git a/src/tools/rbd_mirror/ImageReplayer.cc b/src/tools/rbd_mirror/ImageReplayer.cc index 48b78be01aa66..14d66df135ff3 100644 --- a/src/tools/rbd_mirror/ImageReplayer.cc +++ b/src/tools/rbd_mirror/ImageReplayer.cc @@ -1343,10 +1343,18 @@ void ImageReplayer::finish_mirror_image_status_update() { template void ImageReplayer::queue_mirror_image_status_update(const OptionalState &state) { dout(15) << dendl; - FunctionContext *ctx = new FunctionContext( + + auto ctx = new FunctionContext( [this, state](int r) { send_mirror_status_update(state); }); + + // ensure pending IO is flushed and the commit position is updated + // prior to updating the mirror status + ctx = new FunctionContext( + [this, ctx](int r) { + flush_local_replay(ctx); + }); m_threads->work_queue->queue(ctx, 0); } -- 2.39.5