From: Jason Dillaman Date: Fri, 31 Jan 2020 02:21:30 +0000 (-0500) Subject: librbd: optionally ignore missing peers when creating promoted mirror snapshot X-Git-Tag: v15.1.1~472^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=33b15088c88ecbcacb9308425c5a09515e2f7b4c;p=ceph.git librbd: optionally ignore missing peers when creating promoted mirror snapshot The initial enable steps as well as demote/promote should ignore the lack of peers. Otherwise, you would never be able to enable snapshot mirroring without first creating TX peers. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/api/Mirror.cc b/src/librbd/api/Mirror.cc index ae4874cc45a0..81694d843473 100644 --- a/src/librbd/api/Mirror.cc +++ b/src/librbd/api/Mirror.cc @@ -1818,7 +1818,7 @@ int Mirror::image_snapshot_create(I *ictx, uint64_t *snap_id) { C_SaferCond on_finish; auto req = mirror::snapshot::CreatePrimaryRequest::create( - ictx, false, false, snap_id, &on_finish); + ictx, 0U, snap_id, &on_finish); req->send(); return on_finish.wait(); } diff --git a/src/librbd/mirror/snapshot/CreatePrimaryRequest.cc b/src/librbd/mirror/snapshot/CreatePrimaryRequest.cc index d11df27bc7c9..4ec7967f98b3 100644 --- a/src/librbd/mirror/snapshot/CreatePrimaryRequest.cc +++ b/src/librbd/mirror/snapshot/CreatePrimaryRequest.cc @@ -26,10 +26,10 @@ using librbd::util::create_context_callback; using librbd::util::create_rados_callback; template -CreatePrimaryRequest::CreatePrimaryRequest(I *image_ctx, bool demoted, - bool force, uint64_t *snap_id, +CreatePrimaryRequest::CreatePrimaryRequest(I *image_ctx, uint32_t flags, + uint64_t *snap_id, Context *on_finish) - : m_image_ctx(image_ctx), m_demoted(demoted), m_force(force), + : m_image_ctx(image_ctx), m_flags(flags), m_snap_id(snap_id), m_on_finish(on_finish) { m_default_ns_ctx.dup(m_image_ctx->md_ctx); m_default_ns_ctx.set_namespace(""); @@ -111,8 +111,10 @@ void CreatePrimaryRequest::handle_get_mirror_image(int r) { return; } - if (!util::can_create_primary_snapshot(m_image_ctx, m_demoted, m_force, - nullptr)) { + if (!util::can_create_primary_snapshot( + m_image_ctx, + ((m_flags & CREATE_PRIMARY_FLAG_DEMOTED) != 0), + ((m_flags & CREATE_PRIMARY_FLAG_FORCE) != 0), nullptr)) { finish(-EINVAL); return; } @@ -166,7 +168,8 @@ void CreatePrimaryRequest::handle_get_mirror_peers(int r) { m_mirror_peer_uuids.insert(peer.uuid); } - if (m_mirror_peer_uuids.empty()) { + if (m_mirror_peer_uuids.empty() && + ((m_flags & CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS) == 0)) { lderr(cct) << "no mirror tx peers configured for the pool" << dendl; finish(-EINVAL); return; @@ -180,7 +183,8 @@ void CreatePrimaryRequest::create_snapshot() { CephContext *cct = m_image_ctx->cct; ldout(cct, 20) << dendl; - cls::rbd::MirrorPrimarySnapshotNamespace ns{m_demoted, m_mirror_peer_uuids}; + cls::rbd::MirrorPrimarySnapshotNamespace ns{ + ((m_flags & CREATE_PRIMARY_FLAG_DEMOTED) != 0), m_mirror_peer_uuids}; auto ctx = create_context_callback< CreatePrimaryRequest, &CreatePrimaryRequest::handle_create_snapshot>(this); @@ -201,7 +205,8 @@ void CreatePrimaryRequest::handle_create_snapshot(int r) { if (m_snap_id != nullptr) { std::shared_lock image_locker{m_image_ctx->image_lock}; - cls::rbd::MirrorPrimarySnapshotNamespace ns{m_demoted, m_mirror_peer_uuids}; + cls::rbd::MirrorPrimarySnapshotNamespace ns{ + ((m_flags & CREATE_PRIMARY_FLAG_DEMOTED) != 0), m_mirror_peer_uuids}; *m_snap_id = m_image_ctx->get_snap_id(ns, m_snap_name); } diff --git a/src/librbd/mirror/snapshot/CreatePrimaryRequest.h b/src/librbd/mirror/snapshot/CreatePrimaryRequest.h index fe7d5f90b26d..022cc95efc3f 100644 --- a/src/librbd/mirror/snapshot/CreatePrimaryRequest.h +++ b/src/librbd/mirror/snapshot/CreatePrimaryRequest.h @@ -7,6 +7,7 @@ #include "include/buffer.h" #include "include/rados/librados.hpp" #include "cls/rbd/cls_rbd_types.h" +#include "librbd/mirror/snapshot/Types.h" #include #include @@ -23,15 +24,14 @@ namespace snapshot { template class CreatePrimaryRequest { public: - static CreatePrimaryRequest *create(ImageCtxT *image_ctx, bool demoted, - bool force, uint64_t *snap_id, + static CreatePrimaryRequest *create(ImageCtxT *image_ctx, uint32_t flags, + uint64_t *snap_id, Context *on_finish) { - return new CreatePrimaryRequest(image_ctx, demoted, force, snap_id, - on_finish); + return new CreatePrimaryRequest(image_ctx, flags, snap_id, on_finish); } - CreatePrimaryRequest(ImageCtxT *image_ctx, bool demoted, bool force, - uint64_t *snap_id, Context *on_finish); + CreatePrimaryRequest(ImageCtxT *image_ctx, uint32_t flags, uint64_t *snap_id, + Context *on_finish); void send(); @@ -63,8 +63,7 @@ private: */ ImageCtxT *m_image_ctx; - const bool m_demoted; - const bool m_force; + const uint32_t m_flags; uint64_t *m_snap_id; Context *m_on_finish; diff --git a/src/librbd/mirror/snapshot/DemoteRequest.cc b/src/librbd/mirror/snapshot/DemoteRequest.cc index 18481b20a49b..62fd7f45d747 100644 --- a/src/librbd/mirror/snapshot/DemoteRequest.cc +++ b/src/librbd/mirror/snapshot/DemoteRequest.cc @@ -64,8 +64,10 @@ void DemoteRequest::create_snapshot() { auto ctx = create_context_callback< DemoteRequest, &DemoteRequest::handle_create_snapshot>(this); - auto req = CreatePrimaryRequest::create(m_image_ctx, true, false, nullptr, - ctx); + auto req = CreatePrimaryRequest::create( + m_image_ctx, + (snapshot::CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS | + snapshot::CREATE_PRIMARY_FLAG_DEMOTED), nullptr, ctx); req->send(); } diff --git a/src/librbd/mirror/snapshot/PromoteRequest.cc b/src/librbd/mirror/snapshot/PromoteRequest.cc index 683b5f4e50e0..3fb28cf16ea9 100644 --- a/src/librbd/mirror/snapshot/PromoteRequest.cc +++ b/src/librbd/mirror/snapshot/PromoteRequest.cc @@ -322,8 +322,10 @@ void PromoteRequest::create_promote_snapshot() { PromoteRequest, &PromoteRequest::handle_create_promote_snapshot>(this); - auto req = CreatePrimaryRequest::create(m_image_ctx, false, true, nullptr, - ctx); + auto req = CreatePrimaryRequest::create( + m_image_ctx, + (snapshot::CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS | + snapshot::CREATE_PRIMARY_FLAG_FORCE), nullptr, ctx); req->send(); } diff --git a/src/librbd/mirror/snapshot/Types.h b/src/librbd/mirror/snapshot/Types.h index 42f4aeae0ccb..1c35aea3307a 100644 --- a/src/librbd/mirror/snapshot/Types.h +++ b/src/librbd/mirror/snapshot/Types.h @@ -15,6 +15,12 @@ namespace librbd { namespace mirror { namespace snapshot { +enum CreatePrimaryFlags { + CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS = (1 << 0), + CREATE_PRIMARY_FLAG_DEMOTED = (1 << 1), + CREATE_PRIMARY_FLAG_FORCE = (1 << 2) +}; + struct ImageStateHeader { uint32_t object_count = 0; diff --git a/src/test/librbd/mirror/snapshot/test_mock_CreatePrimaryRequest.cc b/src/test/librbd/mirror/snapshot/test_mock_CreatePrimaryRequest.cc index 9d88a97a7561..6fda820caebd 100644 --- a/src/test/librbd/mirror/snapshot/test_mock_CreatePrimaryRequest.cc +++ b/src/test/librbd/mirror/snapshot/test_mock_CreatePrimaryRequest.cc @@ -237,8 +237,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, Success) { expect_create_snapshot(mock_image_ctx, 0); C_SaferCond ctx; - auto req = new MockCreatePrimaryRequest(&mock_image_ctx, false, false, - nullptr, &ctx); + auto req = new MockCreatePrimaryRequest(&mock_image_ctx, 0U, nullptr, &ctx); req->send(); ASSERT_EQ(0, ctx.wait()); } @@ -257,8 +256,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, RefreshError) { expect_refresh_image(mock_image_ctx, true, -EINVAL); C_SaferCond ctx; - auto req = new MockCreatePrimaryRequest(&mock_image_ctx, false, false, - nullptr, &ctx); + auto req = new MockCreatePrimaryRequest(&mock_image_ctx, 0U, nullptr, &ctx); req->send(); ASSERT_EQ(-EINVAL, ctx.wait()); } @@ -280,8 +278,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, GetMirrorImageError) { cls::rbd::MIRROR_IMAGE_STATE_ENABLED}, -EINVAL); C_SaferCond ctx; - auto req = new MockCreatePrimaryRequest(&mock_image_ctx, false, false, - nullptr, &ctx); + auto req = new MockCreatePrimaryRequest(&mock_image_ctx, 0U, nullptr, &ctx); req->send(); ASSERT_EQ(-EINVAL, ctx.wait()); } @@ -305,8 +302,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, CanNotError) { expect_can_create_primary_snapshot(mock_utils, false, false, false); C_SaferCond ctx; - auto req = new MockCreatePrimaryRequest(&mock_image_ctx, false, false, - nullptr, &ctx); + auto req = new MockCreatePrimaryRequest(&mock_image_ctx, 0U, nullptr, &ctx); req->send(); ASSERT_EQ(-EINVAL, ctx.wait()); } @@ -333,8 +329,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, GetMirrorPeersError) { "mirror", "fsid"}}, -EINVAL); C_SaferCond ctx; - auto req = new MockCreatePrimaryRequest(&mock_image_ctx, false, false, - nullptr, &ctx); + auto req = new MockCreatePrimaryRequest(&mock_image_ctx, 0U, nullptr, &ctx); req->send(); ASSERT_EQ(-EINVAL, ctx.wait()); } @@ -362,8 +357,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, CreateSnapshotError) { expect_create_snapshot(mock_image_ctx, -EINVAL); C_SaferCond ctx; - auto req = new MockCreatePrimaryRequest(&mock_image_ctx, false, false, - nullptr, &ctx); + auto req = new MockCreatePrimaryRequest(&mock_image_ctx, 0U, nullptr, &ctx); req->send(); ASSERT_EQ(-EINVAL, ctx.wait()); } @@ -400,8 +394,7 @@ TEST_F(TestMockMirrorSnapshotCreatePrimaryRequest, SuccessUnlinkPeer) { expect_unlink_peer(mock_image_ctx, mock_unlink_peer_request, snap_id, "uuid", 0); C_SaferCond ctx; - auto req = new MockCreatePrimaryRequest(&mock_image_ctx, false, false, - nullptr, &ctx); + auto req = new MockCreatePrimaryRequest(&mock_image_ctx, 0U, nullptr, &ctx); req->send(); ASSERT_EQ(0, ctx.wait()); } diff --git a/src/test/librbd/mirror/snapshot/test_mock_PromoteRequest.cc b/src/test/librbd/mirror/snapshot/test_mock_PromoteRequest.cc index 4948652d1cdb..f0a49971317c 100644 --- a/src/test/librbd/mirror/snapshot/test_mock_PromoteRequest.cc +++ b/src/test/librbd/mirror/snapshot/test_mock_PromoteRequest.cc @@ -116,12 +116,12 @@ struct CreatePrimaryRequest { bool force = false; Context* on_finish = nullptr; static CreatePrimaryRequest* s_instance; - static CreatePrimaryRequest *create(MockTestImageCtx *image_ctx, bool demoted, - bool force, uint64_t *snap_id, + static CreatePrimaryRequest *create(MockTestImageCtx *image_ctx, + uint32_t flags, uint64_t *snap_id, Context *on_finish) { ceph_assert(s_instance != nullptr); - s_instance->demoted = demoted; - s_instance->force = force; + s_instance->demoted = ((flags & CREATE_PRIMARY_FLAG_DEMOTED) != 0); + s_instance->force = ((flags & CREATE_PRIMARY_FLAG_FORCE) != 0); s_instance->on_finish = on_finish; return s_instance; }