From a895eb4b0f8d9a89987337e937620349d1ba01af Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Wed, 26 Feb 2020 20:18:57 -0500 Subject: [PATCH] rbd-mirror: prepare local image shouldn't abort if image does not exist If we already have a mirror image record, we should still bootstrap up using the data we know like the old image id so that we can properly clean up later. Signed-off-by: Jason Dillaman --- .../test_mock_PrepareLocalImageRequest.cc | 34 +++++++++++++++++-- .../PrepareLocalImageRequest.cc | 11 +++--- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/test/rbd_mirror/image_replayer/test_mock_PrepareLocalImageRequest.cc b/src/test/rbd_mirror/image_replayer/test_mock_PrepareLocalImageRequest.cc index a66560d5a30aa..1888607a62241 100644 --- a/src/test/rbd_mirror/image_replayer/test_mock_PrepareLocalImageRequest.cc +++ b/src/test/rbd_mirror/image_replayer/test_mock_PrepareLocalImageRequest.cc @@ -321,13 +321,43 @@ TEST_F(TestMockImageReplayerPrepareLocalImageRequest, MirrorImageIdError) { ASSERT_EQ(-EINVAL, ctx.wait()); } -TEST_F(TestMockImageReplayerPrepareLocalImageRequest, DirGetNameError) { +TEST_F(TestMockImageReplayerPrepareLocalImageRequest, DirGetNameDNE) { 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, "", -ENOENT); + MockGetMirrorInfoRequest mock_get_mirror_info_request; + expect_get_mirror_info(mock_get_mirror_info_request, + {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL, + "global image id", + cls::rbd::MIRROR_IMAGE_STATE_ENABLED}, + librbd::mirror::PROMOTION_STATE_NON_PRIMARY, + "remote mirror uuid", 0); + + MockJournalStateBuilder 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()); +} + +TEST_F(TestMockImageReplayerPrepareLocalImageRequest, DirGetNameError) { + 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, "", -EPERM); + MockStateBuilder* mock_state_builder = nullptr; std::string local_image_name; C_SaferCond ctx; @@ -339,7 +369,7 @@ TEST_F(TestMockImageReplayerPrepareLocalImageRequest, DirGetNameError) { &ctx); req->send(); - ASSERT_EQ(-ENOENT, ctx.wait()); + ASSERT_EQ(-EPERM, ctx.wait()); } TEST_F(TestMockImageReplayerPrepareLocalImageRequest, MirrorImageInfoError) { diff --git a/src/tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.cc b/src/tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.cc index aa2b30f59344c..4cbf2bd923b3b 100644 --- a/src/tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.cc +++ b/src/tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.cc @@ -86,10 +86,13 @@ void PrepareLocalImageRequest::handle_get_local_image_name(int r) { r = librbd::cls_client::dir_get_name_finish(&it, m_local_image_name); } - if (r < 0) { - if (r != -ENOENT) { - derr << "failed to retrieve image name: " << cpp_strerror(r) << dendl; - } + if (r == -ENOENT) { + // proceed we should have a mirror image record if we got this far + dout(10) << "image does not exist for local image id " << m_local_image_id + << dendl; + *m_local_image_name = ""; + } else if (r < 0) { + derr << "failed to retrieve image name: " << cpp_strerror(r) << dendl; finish(r); return; } -- 2.39.5