From 1d58b16c99cf10c641b368e2e2f39adedbcb00cd Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 30 Jan 2020 15:35:48 -0500 Subject: [PATCH] librbd: create primary mirror snapshot when enabling mirroring This will create an initial primary mirror snapshot when enabling snapshot-based mirroring on an image. Signed-off-by: Jason Dillaman --- src/librbd/api/Migration.cc | 3 +- src/librbd/mirror/EnableRequest.cc | 106 ++++++++++++------ src/librbd/mirror/EnableRequest.h | 39 ++++--- .../mirror/snapshot/CreatePrimaryRequest.cc | 3 - src/test/librbd/test_mirroring.cc | 8 +- 5 files changed, 101 insertions(+), 58 deletions(-) diff --git a/src/librbd/api/Migration.cc b/src/librbd/api/Migration.cc index 73294503217..a2fb4fb08b2 100644 --- a/src/librbd/api/Migration.cc +++ b/src/librbd/api/Migration.cc @@ -1495,8 +1495,7 @@ int Migration::enable_mirroring( C_SaferCond ctx; auto req = mirror::EnableRequest::create( - image_ctx->md_ctx, image_ctx->id, mirror_image_mode, "", - image_ctx->op_work_queue, &ctx); + image_ctx, mirror_image_mode, &ctx); req->send(); r = ctx.wait(); if (r < 0) { diff --git a/src/librbd/mirror/EnableRequest.cc b/src/librbd/mirror/EnableRequest.cc index 767ec2590dd..50f2afb7a48 100644 --- a/src/librbd/mirror/EnableRequest.cc +++ b/src/librbd/mirror/EnableRequest.cc @@ -9,6 +9,7 @@ #include "librbd/Journal.h" #include "librbd/Utils.h" #include "librbd/mirror/ImageStateUpdateRequest.h" +#include "librbd/mirror/snapshot/CreatePrimaryRequest.h" #define dout_subsys ceph_subsys_rbd #undef dout_prefix @@ -24,10 +25,11 @@ using util::create_rados_callback; template EnableRequest::EnableRequest(librados::IoCtx &io_ctx, const std::string &image_id, + I* image_ctx, cls::rbd::MirrorImageMode mode, const std::string &non_primary_global_image_id, ContextWQ *op_work_queue, Context *on_finish) - : m_io_ctx(io_ctx), m_image_id(image_id), + : m_io_ctx(io_ctx), m_image_id(image_id), m_image_ctx(image_ctx), m_mode(mode), m_non_primary_global_image_id(non_primary_global_image_id), m_op_work_queue(op_work_queue), m_on_finish(on_finish), m_cct(reinterpret_cast(io_ctx.cct())) { @@ -35,11 +37,11 @@ EnableRequest::EnableRequest(librados::IoCtx &io_ctx, template void EnableRequest::send() { - send_get_mirror_image(); + get_mirror_image(); } template -void EnableRequest::send_get_mirror_image() { +void EnableRequest::get_mirror_image() { ldout(m_cct, 10) << dendl; librados::ObjectReadOperation op; @@ -55,34 +57,36 @@ void EnableRequest::send_get_mirror_image() { } template -Context *EnableRequest::handle_get_mirror_image(int *result) { - ldout(m_cct, 10) << "r=" << *result << dendl; +void EnableRequest::handle_get_mirror_image(int r) { + ldout(m_cct, 10) << "r=" << r << dendl; - if (*result == 0) { + if (r == 0) { auto iter = m_out_bl.cbegin(); - *result = cls_client::mirror_image_get_finish(&iter, &m_mirror_image); + r = cls_client::mirror_image_get_finish(&iter, &m_mirror_image); } - if (*result == 0) { + if (r == 0) { if (m_mirror_image.mode != m_mode) { lderr(m_cct) << "invalid current image mirror mode" << dendl; - *result = -EINVAL; + r = -EINVAL; } else if (m_mirror_image.state == cls::rbd::MIRROR_IMAGE_STATE_ENABLED) { ldout(m_cct, 10) << "mirroring is already enabled" << dendl; } else { lderr(m_cct) << "currently disabling" << dendl; - *result = -EINVAL; + r = -EINVAL; } - return m_on_finish; + finish(r); + return; } - if (*result != -ENOENT) { - lderr(m_cct) << "failed to retrieve mirror image: " << cpp_strerror(*result) + if (r != -ENOENT) { + lderr(m_cct) << "failed to retrieve mirror image: " << cpp_strerror(r) << dendl; - return m_on_finish; + finish(r); + return; } - *result = 0; + r = 0; m_mirror_image.mode = m_mode; if (m_non_primary_global_image_id.empty()) { uuid_d uuid_gen; @@ -92,17 +96,17 @@ Context *EnableRequest::handle_get_mirror_image(int *result) { m_mirror_image.global_image_id = m_non_primary_global_image_id; } - send_get_tag_owner(); - return nullptr; + get_tag_owner(); } template -void EnableRequest::send_get_tag_owner() { +void EnableRequest::get_tag_owner() { if (m_mirror_image.mode == cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT || !m_non_primary_global_image_id.empty()) { - send_image_state_update(); + create_primary_snapshot(); return; } + ldout(m_cct, 10) << dendl; using klass = EnableRequest; @@ -113,27 +117,53 @@ void EnableRequest::send_get_tag_owner() { } template -Context *EnableRequest::handle_get_tag_owner(int *result) { - ldout(m_cct, 10) << "r=" << *result << dendl; +void EnableRequest::handle_get_tag_owner(int r) { + ldout(m_cct, 10) << "r=" << r << dendl; - if (*result < 0) { - lderr(m_cct) << "failed to check tag ownership: " << cpp_strerror(*result) + if (r < 0) { + lderr(m_cct) << "failed to check tag ownership: " << cpp_strerror(r) << dendl; - return m_on_finish; + finish(r); + return; } if (!m_is_primary) { lderr(m_cct) << "last journal tag not owned by local cluster" << dendl; - *result = -EINVAL; - return m_on_finish; + finish(-EINVAL); + return; } - send_image_state_update(); - return nullptr; + image_state_update(); } template -void EnableRequest::send_image_state_update() { +void EnableRequest::create_primary_snapshot() { + if (!m_non_primary_global_image_id.empty()) { + image_state_update(); + return; + } + + ldout(m_cct, 10) << dendl; + + ceph_assert(m_image_ctx != nullptr); + auto ctx = create_context_callback< + EnableRequest, + &EnableRequest::handle_create_primary_snapshot>(this); + auto req = snapshot::CreatePrimaryRequest::create( + m_image_ctx, m_mirror_image.global_image_id, + snapshot::CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS, &m_snap_id, ctx); + req->send(); +} + +template +void EnableRequest::handle_create_primary_snapshot(int r) { + ldout(m_cct, 10) << "r=" << r << dendl; + + image_state_update(); +} + +template +void EnableRequest::image_state_update() { ldout(m_cct, 10) << dendl; auto ctx = create_context_callback< @@ -145,15 +175,23 @@ void EnableRequest::send_image_state_update() { } template -Context *EnableRequest::handle_image_state_update(int *result) { - ldout(m_cct, 10) << "r=" << *result << dendl; +void EnableRequest::handle_image_state_update(int r) { + ldout(m_cct, 10) << "r=" << r << dendl; - if (*result < 0) { - lderr(m_cct) << "failed to enable mirroring: " << cpp_strerror(*result) + if (r < 0) { + lderr(m_cct) << "failed to enable mirroring: " << cpp_strerror(r) << dendl; } - return m_on_finish; + finish(r); +} + +template +void EnableRequest::finish(int r) { + ldout(m_cct, 10) << "r=" << r << dendl; + + m_on_finish->complete(r); + delete this; } } // namespace mirror diff --git a/src/librbd/mirror/EnableRequest.h b/src/librbd/mirror/EnableRequest.h index 374f038c86d..853e96a7efc 100644 --- a/src/librbd/mirror/EnableRequest.h +++ b/src/librbd/mirror/EnableRequest.h @@ -9,6 +9,7 @@ #include "include/rbd/librbd.hpp" #include "cls/rbd/cls_rbd_types.h" #include "librbd/ImageCtx.h" +#include "librbd/mirror/Types.h" #include #include @@ -24,15 +25,15 @@ public: static EnableRequest *create(ImageCtxT *image_ctx, cls::rbd::MirrorImageMode mode, Context *on_finish) { - return create(image_ctx->md_ctx, image_ctx->id, mode, "", - image_ctx->op_work_queue, on_finish); + return new EnableRequest(image_ctx->md_ctx, image_ctx->id, image_ctx, mode, + "", image_ctx->op_work_queue, on_finish); } static EnableRequest *create(librados::IoCtx &io_ctx, const std::string &image_id, cls::rbd::MirrorImageMode mode, const std::string &non_primary_global_image_id, ContextWQ *op_work_queue, Context *on_finish) { - return new EnableRequest(io_ctx, image_id, mode, + return new EnableRequest(io_ctx, image_id, nullptr, mode, non_primary_global_image_id, op_work_queue, on_finish); } @@ -48,9 +49,12 @@ private: * v * GET_MIRROR_IMAGE * * * * * * * * | * (on error) - * v * + * v (skip if not needed) * * GET_TAG_OWNER * * * * * * * * - * | (skip if not needed) * + * | * + * v (skip if not needed) * + * CREATE_PRIMARY_SNAPSHOT * * * + * | * * v * * IMAGE_STATE_UPDATE * * * * * * * | * @@ -61,33 +65,38 @@ private: */ EnableRequest(librados::IoCtx &io_ctx, const std::string &image_id, - cls::rbd::MirrorImageMode mode, + ImageCtxT* image_ctx, cls::rbd::MirrorImageMode mode, const std::string &non_primary_global_image_id, ContextWQ *op_work_queue, Context *on_finish); librados::IoCtx &m_io_ctx; std::string m_image_id; + ImageCtxT* m_image_ctx; cls::rbd::MirrorImageMode m_mode; std::string m_non_primary_global_image_id; ContextWQ *m_op_work_queue; Context *m_on_finish; CephContext *m_cct = nullptr; - bool m_is_primary = false; bufferlist m_out_bl; cls::rbd::MirrorImage m_mirror_image; - void send_get_mirror_image(); - Context *handle_get_mirror_image(int *result); + bool m_is_primary = false; + uint64_t m_snap_id = CEPH_NOSNAP; + + void get_mirror_image(); + void handle_get_mirror_image(int r); + + void get_tag_owner(); + void handle_get_tag_owner(int r); - void send_get_features(); - Context *handle_get_features(int *result); + void create_primary_snapshot(); + void handle_create_primary_snapshot(int r); - void send_get_tag_owner(); - Context *handle_get_tag_owner(int *result); + void image_state_update(); + void handle_image_state_update(int r); - void send_image_state_update(); - Context *handle_image_state_update(int *result); + void finish(int r); }; } // namespace mirror diff --git a/src/librbd/mirror/snapshot/CreatePrimaryRequest.cc b/src/librbd/mirror/snapshot/CreatePrimaryRequest.cc index c4e85475468..4343935eafa 100644 --- a/src/librbd/mirror/snapshot/CreatePrimaryRequest.cc +++ b/src/librbd/mirror/snapshot/CreatePrimaryRequest.cc @@ -172,9 +172,6 @@ void CreatePrimaryRequest::unlink_peer() { prev_snap_id = 0; continue; } - if (info->mirror_peer_uuids.count(peer) == 0) { - continue; - } count++; if (count == max_snapshots - 1) { prev_snap_id = snap_it.first; diff --git a/src/test/librbd/test_mirroring.cc b/src/test/librbd/test_mirroring.cc index c805fb778fe..76acec69195 100644 --- a/src/test/librbd/test_mirroring.cc +++ b/src/test/librbd/test_mirroring.cc @@ -1137,8 +1137,8 @@ TEST_F(TestMirroring, Snapshot) ASSERT_EQ(0, image.mirror_image_create_snapshot(&snap_id)); vector snaps; ASSERT_EQ(0, image.snap_list(snaps)); - ASSERT_EQ(1U, snaps.size()); - ASSERT_EQ(snaps[0].id, snap_id); + ASSERT_EQ(2U, snaps.size()); + ASSERT_EQ(snaps[1].id, snap_id); ASSERT_EQ(0, image.mirror_image_create_snapshot(&snap_id)); ASSERT_EQ(0, image.mirror_image_create_snapshot(&snap_id)); @@ -1198,8 +1198,8 @@ TEST_F(TestMirroring, SnapshotRemoveOnDisable) vector snaps; ASSERT_EQ(0, image.snap_list(snaps)); - ASSERT_EQ(1U, snaps.size()); - ASSERT_EQ(snaps[0].id, snap_id); + ASSERT_EQ(2U, snaps.size()); + ASSERT_EQ(snaps[1].id, snap_id); ASSERT_EQ(0, image.mirror_image_disable(false)); -- 2.39.5