diff --git a/src/test/rbd_mirror/test_mock_ImageReplayer.cc b/src/test/rbd_mirror/test_mock_ImageReplayer.cc index 61dce0e2b29..430edaa16d3 100644 --- a/src/test/rbd_mirror/test_mock_ImageReplayer.cc +++ b/src/test/rbd_mirror/test_mock_ImageReplayer.cc @@ -490,9 +490,9 @@ TEST_F(TestMockImageReplayer, StartStop) { expect_get_or_send_update(mock_replay_status_formatter); InSequence seq; - EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_prepare_local_image_request, mock_local_image_ctx.id, "remote mirror uuid", 0); + EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_bootstrap_request, mock_local_image_ctx, false, 0); EXPECT_CALL(mock_local_journal, add_listener(_)); @@ -534,20 +534,15 @@ TEST_F(TestMockImageReplayer, LocalImagePrimary) { create_local_image(); librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - journal::MockJournaler mock_remote_journaler; MockPrepareLocalImageRequest mock_prepare_local_image_request; MockReplayStatusFormatter mock_replay_status_formatter; expect_get_or_send_update(mock_replay_status_formatter); InSequence seq; - EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_prepare_local_image_request, mock_local_image_ctx.id, "", 0); - EXPECT_CALL(mock_remote_journaler, remove_listener(_)); - expect_shut_down(mock_remote_journaler, 0); - C_SaferCond start_ctx; m_image_replayer->start(&start_ctx); ASSERT_EQ(0, start_ctx.wait()); @@ -565,8 +560,8 @@ TEST_F(TestMockImageReplayer, LocalImageDNE) { expect_get_or_send_update(mock_replay_status_formatter); InSequence seq; - EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_prepare_local_image_request, "", "", -ENOENT); + EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_bootstrap_request, mock_local_image_ctx, false, -EREMOTEIO); EXPECT_CALL(mock_remote_journaler, remove_listener(_)); @@ -581,20 +576,15 @@ TEST_F(TestMockImageReplayer, PrepareLocalImageError) { create_local_image(); librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); - journal::MockJournaler mock_remote_journaler; MockPrepareLocalImageRequest mock_prepare_local_image_request; MockReplayStatusFormatter mock_replay_status_formatter; expect_get_or_send_update(mock_replay_status_formatter); InSequence seq; - EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_prepare_local_image_request, mock_local_image_ctx.id, "remote mirror uuid", -EINVAL); - EXPECT_CALL(mock_remote_journaler, remove_listener(_)); - expect_shut_down(mock_remote_journaler, 0); - C_SaferCond start_ctx; m_image_replayer->start(&start_ctx); ASSERT_EQ(-EINVAL, start_ctx.wait()); @@ -613,9 +603,9 @@ TEST_F(TestMockImageReplayer, BootstrapError) { expect_get_or_send_update(mock_replay_status_formatter); InSequence seq; - EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_prepare_local_image_request, mock_local_image_ctx.id, "remote mirror uuid", 0); + EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_bootstrap_request, mock_local_image_ctx, false, -EINVAL); EXPECT_CALL(mock_remote_journaler, remove_listener(_)); @@ -645,9 +635,9 @@ TEST_F(TestMockImageReplayer, StartExternalReplayError) { expect_get_or_send_update(mock_replay_status_formatter); InSequence seq; - EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_prepare_local_image_request, mock_local_image_ctx.id, "remote mirror uuid", 0); + EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_bootstrap_request, mock_local_image_ctx, false, 0); EXPECT_CALL(mock_local_journal, add_listener(_)); @@ -692,9 +682,9 @@ TEST_F(TestMockImageReplayer, StopError) { expect_get_or_send_update(mock_replay_status_formatter); InSequence seq; - EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_prepare_local_image_request, mock_local_image_ctx.id, "remote mirror uuid", 0); + EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_bootstrap_request, mock_local_image_ctx, false, 0); EXPECT_CALL(mock_local_journal, add_listener(_)); @@ -754,9 +744,9 @@ TEST_F(TestMockImageReplayer, Replay) { expect_committed(mock_remote_journaler, 2); InSequence seq; - EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_prepare_local_image_request, mock_local_image_ctx.id, "remote mirror uuid", 0); + EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_bootstrap_request, mock_local_image_ctx, false, 0); EXPECT_CALL(mock_local_journal, add_listener(_)); @@ -854,9 +844,9 @@ TEST_F(TestMockImageReplayer, DecodeError) { expect_get_commit_tid_in_debug(mock_replay_entry); InSequence seq; - EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_prepare_local_image_request, mock_local_image_ctx.id, "remote mirror uuid", 0); + EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_bootstrap_request, mock_local_image_ctx, false, 0); EXPECT_CALL(mock_local_journal, add_listener(_)); @@ -946,9 +936,9 @@ TEST_F(TestMockImageReplayer, DelayedReplay) { expect_committed(mock_remote_journaler, 1); InSequence seq; - EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_prepare_local_image_request, mock_local_image_ctx.id, "remote mirror uuid", 0); + EXPECT_CALL(mock_remote_journaler, construct()); expect_send(mock_bootstrap_request, mock_local_image_ctx, false, 0); EXPECT_CALL(mock_local_journal, add_listener(_)); diff --git a/src/tools/rbd_mirror/ImageReplayer.cc b/src/tools/rbd_mirror/ImageReplayer.cc index bb56c6e95a5..3276dba3b8f 100644 --- a/src/tools/rbd_mirror/ImageReplayer.cc +++ b/src/tools/rbd_mirror/ImageReplayer.cc @@ -372,18 +372,12 @@ void ImageReplayer::start(Context *on_finish, bool manual) dout(5) << "stopped manually, ignoring start without manual flag" << dendl; r = -EPERM; - } else if (m_remote_images.empty()) { - derr << "no remote images associated with replayer" << dendl; - r = -EINVAL; } else { m_state = STATE_STARTING; m_last_r = 0; m_state_desc.clear(); m_manual_stop = false; - // TODO bootstrap will need to support multiple remote images - m_remote_image = *m_remote_images.begin(); - if (on_finish != nullptr) { assert(m_on_start_finish == nullptr); m_on_start_finish = on_finish; @@ -407,17 +401,6 @@ void ImageReplayer::start(Context *on_finish, bool manual) return; } - CephContext *cct = static_cast(m_local->cct()); - journal::Settings settings; - settings.commit_interval = cct->_conf->rbd_mirror_journal_commit_age; - settings.max_fetch_bytes = cct->_conf->rbd_mirror_journal_max_fetch_bytes; - - m_remote_journaler = new Journaler(m_threads->work_queue, - m_threads->timer, - &m_threads->timer_lock, - m_remote_image.io_ctx, - m_remote_image.image_id, - m_local_mirror_uuid, settings); prepare_local_image(); } @@ -456,6 +439,26 @@ template void ImageReplayer::bootstrap() { dout(20) << dendl; + if (m_remote_images.empty()) { + on_start_fail(0, "waiting for primary remote image"); + return; + } + + // TODO bootstrap will need to support multiple remote images + m_remote_image = *m_remote_images.begin(); + + CephContext *cct = static_cast(m_local->cct()); + journal::Settings settings; + settings.commit_interval = cct->_conf->rbd_mirror_journal_commit_age; + settings.max_fetch_bytes = cct->_conf->rbd_mirror_journal_max_fetch_bytes; + + m_remote_journaler = new Journaler(m_threads->work_queue, + m_threads->timer, + &m_threads->timer_lock, + m_remote_image.io_ctx, + m_remote_image.image_id, + m_local_mirror_uuid, settings); + Context *ctx = create_context_callback< ImageReplayer, &ImageReplayer::handle_bootstrap>(this);