From: Mykola Golub Date: Thu, 9 Jan 2020 09:55:58 +0000 (+0000) Subject: librbd: fix some edge cases for snapshot mirror mode promote X-Git-Tag: v15.1.0~215^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0b63fac09993bdb62ebb7fc114063af5ca05e803;p=ceph.git librbd: fix some edge cases for snapshot mirror mode promote - don't skip `can_create_primary_snapshot` check when refresh is not required; - always call `can_create_primary_snapshot` with force in order not to fail whith "trying to create primary snapshot without force when previous primary snapshot is demoted". Signed-off-by: Mykola Golub --- diff --git a/src/librbd/mirror/snapshot/PromoteRequest.cc b/src/librbd/mirror/snapshot/PromoteRequest.cc index 9fe4bfe2060f..683b5f4e50e0 100644 --- a/src/librbd/mirror/snapshot/PromoteRequest.cc +++ b/src/librbd/mirror/snapshot/PromoteRequest.cc @@ -36,7 +36,7 @@ void PromoteRequest::send() { template void PromoteRequest::refresh_image() { if (!m_image_ctx->state->is_refresh_required()) { - create_promote_snapshot(); + handle_refresh_image(0); return; } @@ -59,7 +59,7 @@ void PromoteRequest::handle_refresh_image(int r) { return; } - if (!util::can_create_primary_snapshot(m_image_ctx, false, m_force, + if (!util::can_create_primary_snapshot(m_image_ctx, false, true, &m_rollback_snap_id)) { lderr(cct) << "cannot promote" << dendl; finish(-EINVAL); @@ -69,6 +69,12 @@ void PromoteRequest::handle_refresh_image(int r) { return; } + if (!m_force) { + lderr(cct) << "cannot promote: needs rollback and force not set" << dendl; + finish(-EINVAL); + return; + } + create_orphan_snapshot(); } @@ -157,7 +163,7 @@ void PromoteRequest::wait_update_notify() { finish(r); return; } - + scheduler_unregister_update_watcher(); } diff --git a/src/test/librbd/mirror/snapshot/test_mock_PromoteRequest.cc b/src/test/librbd/mirror/snapshot/test_mock_PromoteRequest.cc index 304ad6295312..4948652d1cdb 100644 --- a/src/test/librbd/mirror/snapshot/test_mock_PromoteRequest.cc +++ b/src/test/librbd/mirror/snapshot/test_mock_PromoteRequest.cc @@ -275,12 +275,12 @@ TEST_F(TestMockMirrorSnapshotPromoteRequest, Success) { expect_refresh_image(mock_image_ctx, true, 0); MockUtils mock_utils; - expect_can_create_primary_snapshot(mock_utils, force, CEPH_NOSNAP, true); + expect_can_create_primary_snapshot(mock_utils, true, CEPH_NOSNAP, true); MockCreatePrimaryRequest mock_create_primary_request; expect_create_promote_snapshot(mock_image_ctx, mock_create_primary_request, 0); C_SaferCond ctx; - auto req = new MockPromoteRequest(&mock_image_ctx, false, &ctx); + auto req = new MockPromoteRequest(&mock_image_ctx, force, &ctx); req->send(); ASSERT_EQ(0, ctx.wait()); } @@ -305,14 +305,14 @@ TEST_F(TestMockMirrorSnapshotPromoteRequest, SuccessRollback) { expect_refresh_image(mock_image_ctx, true, 0); MockUtils mock_utils; - expect_can_create_primary_snapshot(mock_utils, force, 123, true); + expect_can_create_primary_snapshot(mock_utils, true, 123, true); MockCreateNonPrimaryRequest mock_create_non_primary_request; expect_create_orphan_snapshot(mock_image_ctx, mock_create_non_primary_request, 0); MockListWatchersRequest mock_list_watchers_request; expect_list_watchers(mock_image_ctx, mock_list_watchers_request, {}, 0); expect_acquire_lock(mock_image_ctx, 0); - + SnapInfo snap_info = {"snap", cls::rbd::MirrorPrimarySnapshotNamespace{}, 0, {}, 0, 0, {}}; expect_rollback(mock_image_ctx, 123, &snap_info, 0); @@ -360,7 +360,7 @@ TEST_F(TestMockMirrorSnapshotPromoteRequest, ErrorCannotRollback) { expect_refresh_image(mock_image_ctx, true, 0); MockUtils mock_utils; - expect_can_create_primary_snapshot(mock_utils, force, CEPH_NOSNAP, false); + expect_can_create_primary_snapshot(mock_utils, true, CEPH_NOSNAP, false); C_SaferCond ctx; auto req = new MockPromoteRequest(&mock_image_ctx, force, &ctx);