From: Jason Dillaman Date: Thu, 11 Apr 2019 21:01:22 +0000 (-0400) Subject: rbd-mirror: periodically flush prior to updating status X-Git-Tag: v15.1.0~2944^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=af22cd213c90c6a5a6ae9d7bcc44457ef5b01649;p=ceph.git 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 --- diff --git a/src/test/rbd_mirror/test_mock_ImageReplayer.cc b/src/test/rbd_mirror/test_mock_ImageReplayer.cc index 4683b0d8fdb1..1bd330fd8a45 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 48b78be01aa6..14d66df135ff 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); }