From a0ad2d11cea867eb19d40a121907ec43f37e39a3 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Tue, 6 Dec 2016 15:51:51 -0500 Subject: [PATCH] librbd: delay mirror registration when creating clones Fixes: http://tracker.ceph.com/issues/17993 Signed-off-by: Jason Dillaman (cherry picked from commit 778e1126a0343e2221446b8e13b48df5ccac263c) --- src/librbd/Journal.cc | 37 ++++-- src/librbd/Journal.h | 3 + src/librbd/image/CreateRequest.cc | 125 +++--------------- src/librbd/image/CreateRequest.h | 21 +-- src/librbd/internal.cc | 42 +++++- src/librbd/internal.h | 3 +- src/librbd/librbd.cc | 4 +- src/librbd/mirror/EnableRequest.cc | 89 +++++++------ src/librbd/mirror/EnableRequest.h | 24 +++- src/test/librbd/test_mock_Journal.cc | 1 - .../test_mock_CreateImageRequest.cc | 4 + .../image_replayer/CreateImageRequest.cc | 2 +- 12 files changed, 164 insertions(+), 191 deletions(-) diff --git a/src/librbd/Journal.cc b/src/librbd/Journal.cc index 8cca965ce7269..f799f6b8d1424 100644 --- a/src/librbd/Journal.cc +++ b/src/librbd/Journal.cc @@ -53,25 +53,29 @@ public: template struct C_IsTagOwner : public Context { - I *image_ctx; + librados::IoCtx &io_ctx; + std::string image_id; bool *is_tag_owner; + ContextWQ *op_work_queue; Context *on_finish; + CephContext *cct = nullptr; Journaler *journaler; cls::journal::Client client; journal::ImageClientMeta client_meta; uint64_t tag_tid; journal::TagData tag_data; - C_IsTagOwner(I *image_ctx, bool *is_tag_owner, Context *on_finish) - : image_ctx(image_ctx), is_tag_owner(is_tag_owner), on_finish(on_finish), - journaler(new Journaler(image_ctx->md_ctx, image_ctx->id, - Journal<>::IMAGE_CLIENT_ID, {})) { + C_IsTagOwner(librados::IoCtx &io_ctx, const std::string &image_id, + bool *is_tag_owner, ContextWQ *op_work_queue, Context *on_finish) + : io_ctx(io_ctx), image_id(image_id), is_tag_owner(is_tag_owner), + op_work_queue(op_work_queue), on_finish(on_finish), + cct(reinterpret_cast(io_ctx.cct())), + journaler(new Journaler(io_ctx, image_id, Journal<>::IMAGE_CLIENT_ID, + {})) { } virtual void finish(int r) { - CephContext *cct = image_ctx->cct; - ldout(cct, 20) << this << " C_IsTagOwner::" << __func__ << ": r=" << r << dendl; if (r < 0) { @@ -88,7 +92,7 @@ struct C_IsTagOwner : public Context { on_finish->complete(r); delete journaler; }); - image_ctx->op_work_queue->queue(ctx, r); + op_work_queue->queue(ctx, r); } }; @@ -432,7 +436,8 @@ int Journal::reset(librados::IoCtx &io_ctx, const std::string &image_id) { template int Journal::is_tag_owner(I *image_ctx, bool *is_tag_owner) { - return Journal<>::is_tag_owner(image_ctx->md_ctx, image_ctx->id, is_tag_owner); + return Journal<>::is_tag_owner(image_ctx->md_ctx, image_ctx->id, + is_tag_owner); } template @@ -449,13 +454,21 @@ int Journal::is_tag_owner(IoCtx& io_ctx, std::string& image_id, } template -void Journal::is_tag_owner(I *image_ctx, bool *is_tag_owner, +void Journal::is_tag_owner(I *image_ctx, bool *owner, Context *on_finish) { - CephContext *cct = image_ctx->cct; + is_tag_owner(image_ctx->md_ctx, image_ctx->id, owner, + image_ctx->op_work_queue, on_finish); +} + +template +void Journal::is_tag_owner(librados::IoCtx& io_ctx, std::string& image_id, + bool *is_tag_owner, ContextWQ *op_work_queue, + Context *on_finish) { + CephContext *cct = reinterpret_cast(io_ctx.cct()); ldout(cct, 20) << __func__ << dendl; C_IsTagOwner *is_tag_owner_ctx = new C_IsTagOwner( - image_ctx, is_tag_owner, on_finish); + io_ctx, image_id, is_tag_owner, op_work_queue, on_finish); get_tags(cct, is_tag_owner_ctx->journaler, &is_tag_owner_ctx->client, &is_tag_owner_ctx->client_meta, &is_tag_owner_ctx->tag_tid, &is_tag_owner_ctx->tag_data, is_tag_owner_ctx); diff --git a/src/librbd/Journal.h b/src/librbd/Journal.h index 345310ebaa1ca..a7fa1a5e5c4af 100644 --- a/src/librbd/Journal.h +++ b/src/librbd/Journal.h @@ -107,6 +107,9 @@ public: bool *is_tag_owner); static void is_tag_owner(ImageCtxT *image_ctx, bool *is_tag_owner, Context *on_finish); + static void is_tag_owner(librados::IoCtx& io_ctx, std::string& image_id, + bool *is_tag_owner, ContextWQ *op_work_queue, + Context *on_finish); static int get_tag_owner(ImageCtxT *image_ctx, std::string *mirror_uuid); static int get_tag_owner(librados::IoCtx& io_ctx, std::string& image_id, std::string *mirror_uuid); diff --git a/src/librbd/image/CreateRequest.cc b/src/librbd/image/CreateRequest.cc index f71642ddc8bd2..2a9dfac2fc1f2 100644 --- a/src/librbd/image/CreateRequest.cc +++ b/src/librbd/image/CreateRequest.cc @@ -10,10 +10,11 @@ #include "common/ceph_context.h" #include "librbd/AioCompletion.h" #include "librbd/Journal.h" +#include "librbd/MirroringWatcher.h" #include "librbd/journal/CreateRequest.h" #include "librbd/journal/RemoveRequest.h" +#include "librbd/mirror/EnableRequest.h" #include "journal/Journaler.h" -#include "librbd/MirroringWatcher.h" #define dout_subsys ceph_subsys_rbd #undef dout_prefix @@ -122,10 +123,12 @@ CreateRequest::CreateRequest(IoCtx &ioctx, const std::string &image_name, const ImageOptions &image_options, const std::string &non_primary_global_image_id, const std::string &primary_mirror_uuid, + bool skip_mirror_enable, ContextWQ *op_work_queue, Context *on_finish) : m_image_name(image_name), m_image_id(image_id), m_size(size), m_non_primary_global_image_id(non_primary_global_image_id), m_primary_mirror_uuid(primary_mirror_uuid), + m_skip_mirror_enable(skip_mirror_enable), m_op_work_queue(op_work_queue), m_on_finish(on_finish) { m_ioctx.dup(ioctx); m_cct = reinterpret_cast(m_ioctx.cct()); @@ -639,86 +642,25 @@ Context* CreateRequest::handle_journal_create(int *result) { return nullptr; } - fetch_mirror_image(); + mirror_image_enable(); return nullptr; } template -void CreateRequest::fetch_mirror_image() { - if ((m_mirror_mode != RBD_MIRROR_MODE_POOL) && !m_force_non_primary) { +void CreateRequest::mirror_image_enable() { + if (((m_mirror_mode != RBD_MIRROR_MODE_POOL) && !m_force_non_primary) || + m_skip_mirror_enable) { complete(0); return; } ldout(m_cct, 20) << this << " " << __func__ << dendl; - - librados::ObjectReadOperation op; - cls_client::mirror_image_get_start(&op, m_image_id); - - using klass = CreateRequest; - librados::AioCompletion *comp = - create_rados_ack_callback(this); - m_outbl.clear(); - int r = m_ioctx.aio_operate(RBD_MIRRORING, comp, &op, &m_outbl); - assert(r == 0); - comp->release(); -} - -template -Context *CreateRequest::handle_fetch_mirror_image(int *result) { - ldout(m_cct, 20) << __func__ << ": r=" << *result << dendl; - - if ((*result < 0) && (*result != -ENOENT)) { - lderr(m_cct) << "cannot enable mirroring: " << cpp_strerror(*result) << dendl; - - m_r_saved = *result; - journal_remove(); - return nullptr; - } - - if (*result == 0) { - bufferlist::iterator it = m_outbl.begin(); - *result = cls_client::mirror_image_get_finish(&it, &m_mirror_image_internal); - if (*result < 0) { - lderr(m_cct) << "cannot enable mirroring: " << cpp_strerror(*result) << dendl; - - m_r_saved = *result; - journal_remove(); - return nullptr; - } - - if (m_mirror_image_internal.state == cls::rbd::MIRROR_IMAGE_STATE_ENABLED) { - return m_on_finish; - } - } - - // enable image mirroring (-ENOENT or disabled earlier) - mirror_image_enable(); - return nullptr; -} - -template -void CreateRequest::mirror_image_enable() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - m_mirror_image_internal.state = cls::rbd::MIRROR_IMAGE_STATE_ENABLED; - if (m_non_primary_global_image_id.empty()) { - uuid_d uuid_gen; - uuid_gen.generate_random(); - m_mirror_image_internal.global_image_id = uuid_gen.to_string(); - } else { - m_mirror_image_internal.global_image_id = m_non_primary_global_image_id; - } - - librados::ObjectWriteOperation op; - cls_client::mirror_image_set(&op, m_image_id, m_mirror_image_internal); - - using klass = CreateRequest; - librados::AioCompletion *comp = - create_rados_ack_callback(this); - int r = m_ioctx.aio_operate(RBD_MIRRORING, comp, &op); - assert(r == 0); - comp->release(); + auto ctx = create_context_callback< + CreateRequest, &CreateRequest::handle_mirror_image_enable>(this); + auto req = mirror::EnableRequest::create(m_ioctx, m_image_id, + m_non_primary_global_image_id, + m_op_work_queue, ctx); + req->send(); } template @@ -726,47 +668,14 @@ Context *CreateRequest::handle_mirror_image_enable(int *result) { ldout(m_cct, 20) << __func__ << ": r=" << *result << dendl; if (*result < 0) { - lderr(m_cct) << "cannot enable mirroring: " << cpp_strerror(*result) << dendl; + lderr(m_cct) << "cannot enable mirroring: " << cpp_strerror(*result) + << dendl; m_r_saved = *result; journal_remove(); return nullptr; } - - send_watcher_notification(); - return nullptr; -} - -// TODO: make this *really* async -template -void CreateRequest::send_watcher_notification() { - ldout(m_cct, 20) << this << " " << __func__ << dendl; - - Context *ctx = new FunctionContext([this](int r) { - r = MirroringWatcher<>::notify_image_updated( - m_ioctx, cls::rbd::MIRROR_IMAGE_STATE_ENABLED, - m_image_id, m_mirror_image_internal.global_image_id); - handle_watcher_notify(r); - }); - - m_op_work_queue->queue(ctx, 0); -} - -template -void CreateRequest::handle_watcher_notify(int r) { - ldout(m_cct, 20) << __func__ << ": r=" << r << dendl; - - if (r < 0) { - // non fatal error -- watchers would cope up upon noticing missing - // updates. just log and move on... - ldout(m_cct, 10) << "failed to send update notification: " << cpp_strerror(r) - << dendl; - } else { - ldout(m_cct, 20) << "image mirroring is enabled: global_id=" << - m_mirror_image_internal.global_image_id << dendl; - } - - complete(0); + return m_on_finish; } template diff --git a/src/librbd/image/CreateRequest.h b/src/librbd/image/CreateRequest.h index 9841af941d9a1..865fd77226827 100644 --- a/src/librbd/image/CreateRequest.h +++ b/src/librbd/image/CreateRequest.h @@ -35,10 +35,12 @@ public: const ImageOptions &image_options, const std::string &non_primary_global_image_id, const std::string &primary_mirror_uuid, + bool skip_mirror_enable, ContextWQ *op_work_queue, Context *on_finish) { return new CreateRequest(ioctx, image_name, image_id, size, image_options, non_primary_global_image_id, primary_mirror_uuid, - op_work_queue, on_finish); + skip_mirror_enable, op_work_queue, + on_finish); } static int validate_order(CephContext *cct, uint8_t order); @@ -79,14 +81,9 @@ private: * | |\ JOURNAL CREATE . * | | \ / | . * v | *<------------/ v . - * | | FETCH MIRROR IMAGE v + * | | MIRROR IMAGE ENABLE . * | | / | . - * | JOURNAL REMOVE<--------/ v . - * | \ MIRROR IMAGE ENABLE . - * | \ / | . - * | *<------------/ v . - * | NOTIFY WATCHERS . - * | | . + * | JOURNAL REMOVE*<-------/ | . * | v . * |_____________>___________________ . . . . < . . . . * @@ -98,6 +95,7 @@ private: const ImageOptions &image_options, const std::string &non_primary_global_image_id, const std::string &primary_mirror_uuid, + bool skip_mirror_enable, ContextWQ *op_work_queue, Context *on_finish); IoCtx m_ioctx; @@ -115,6 +113,7 @@ private: int64_t m_data_pool_id = -1; const std::string m_non_primary_global_image_id; const std::string m_primary_mirror_uuid; + bool m_skip_mirror_enable; bool m_negotiate_features = false; ContextWQ *m_op_work_queue; @@ -157,15 +156,9 @@ private: void journal_create(); Context *handle_journal_create(int *result); - void fetch_mirror_image(); - Context *handle_fetch_mirror_image(int *result); - void mirror_image_enable(); Context *handle_mirror_image_enable(int *result); - void send_watcher_notification(); - void handle_watcher_notify(int r); - void complete(int r); // cleanup diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 84b4d977a5f79..ecae4f787d982 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -908,7 +908,7 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force, int r = opts.set(RBD_IMAGE_OPTION_ORDER, order_); assert(r == 0); - r = create(io_ctx, imgname, size, opts, "", ""); + r = create(io_ctx, imgname, size, opts, "", "", false); int r1 = opts.get(RBD_IMAGE_OPTION_ORDER, &order_); assert(r1 == 0); @@ -940,7 +940,7 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force, r = opts.set(RBD_IMAGE_OPTION_STRIPE_COUNT, stripe_count); assert(r == 0); - r = create(io_ctx, imgname, size, opts, "", ""); + r = create(io_ctx, imgname, size, opts, "", "", false); int r1 = opts.get(RBD_IMAGE_OPTION_ORDER, &order_); assert(r1 == 0); @@ -952,7 +952,8 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force, int create(IoCtx& io_ctx, const char *imgname, uint64_t size, ImageOptions& opts, const std::string &non_primary_global_image_id, - const std::string &primary_mirror_uuid) + const std::string &primary_mirror_uuid, + bool skip_mirror_enable) { CephContext *cct = (CephContext *)io_ctx.cct(); ldout(cct, 10) << __func__ << " name=" << imgname << ", " @@ -995,7 +996,7 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force, std::string id = util::generate_image_id(io_ctx); image::CreateRequest<> *req = image::CreateRequest<>::create( io_ctx, imgname, id, size, opts, non_primary_global_image_id, - primary_mirror_uuid, &op_work_queue, &cond); + primary_mirror_uuid, skip_mirror_enable, &op_work_queue, &cond); req->send(); r = cond.wait(); @@ -1176,7 +1177,7 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force, c_opts.set(RBD_IMAGE_OPTION_FEATURES, features); r = create(c_ioctx, c_name, size, c_opts, non_primary_global_image_id, - primary_mirror_uuid); + primary_mirror_uuid, true); if (r < 0) { lderr(cct) << "error creating child: " << cpp_strerror(r) << dendl; return r; @@ -1227,6 +1228,35 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force, } } + if (c_imctx->test_features(RBD_FEATURE_JOURNALING)) { + cls::rbd::MirrorMode mirror_mode_internal = + cls::rbd::MIRROR_MODE_DISABLED; + r = cls_client::mirror_mode_get(&c_imctx->md_ctx, &mirror_mode_internal); + if (r < 0 && r != -ENOENT) { + lderr(cct) << "failed to retrieve mirror mode: " << cpp_strerror(r) + << dendl; + goto err_remove_child; + } + + // enable mirroring now that clone has been fully created + if (mirror_mode_internal == cls::rbd::MIRROR_MODE_POOL || + !non_primary_global_image_id.empty()) { + C_SaferCond ctx; + mirror::EnableRequest *req = + mirror::EnableRequest::create(c_imctx->md_ctx, c_imctx->id, + non_primary_global_image_id, + c_imctx->op_work_queue, &ctx); + req->send(); + + r = ctx.wait(); + if (r < 0) { + lderr(cct) << "failed to enable mirroring: " << cpp_strerror(r) + << dendl; + goto err_remove_child; + } + } + } + ldout(cct, 2) << "done." << dendl; r = c_imctx->state->close(); return r; @@ -1926,7 +1956,7 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force, return -ENOSYS; } - int r = create(dest_md_ctx, destname, src_size, opts, "", ""); + int r = create(dest_md_ctx, destname, src_size, opts, "", "", false); if (r < 0) { lderr(cct) << "header creation failed" << dendl; return r; diff --git a/src/librbd/internal.h b/src/librbd/internal.h index b4e1ad959a675..550eecf9ac5c7 100644 --- a/src/librbd/internal.h +++ b/src/librbd/internal.h @@ -107,7 +107,8 @@ namespace librbd { int create(IoCtx& io_ctx, const char *imgname, uint64_t size, ImageOptions& opts, const std::string &non_primary_global_image_id, - const std::string &primary_mirror_uuid); + const std::string &primary_mirror_uuid, + bool skip_mirror_enable); int clone(IoCtx& p_ioctx, const char *p_name, const char *p_snap_name, IoCtx& c_ioctx, const char *c_name, uint64_t features, int *c_order, diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index 28d1792158d1e..abbc873ff5c16 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -324,7 +324,7 @@ namespace librbd { { TracepointProvider::initialize(get_cct(io_ctx)); tracepoint(librbd, create4_enter, io_ctx.get_pool_name().c_str(), io_ctx.get_id(), name, size, opts.opts); - int r = librbd::create(io_ctx, name, size, opts, "", ""); + int r = librbd::create(io_ctx, name, size, opts, "", "", false); tracepoint(librbd, create4_exit, r); return r; } @@ -1755,7 +1755,7 @@ extern "C" int rbd_create4(rados_ioctx_t p, const char *name, TracepointProvider::initialize(get_cct(io_ctx)); tracepoint(librbd, create4_enter, io_ctx.get_pool_name().c_str(), io_ctx.get_id(), name, size, opts); librbd::ImageOptions opts_(opts); - int r = librbd::create(io_ctx, name, size, opts_, "", ""); + int r = librbd::create(io_ctx, name, size, opts_, "", "", false); tracepoint(librbd, create4_exit, r); return r; } diff --git a/src/librbd/mirror/EnableRequest.cc b/src/librbd/mirror/EnableRequest.cc index a9b03a23d12d2..8f621e4cc03ce 100644 --- a/src/librbd/mirror/EnableRequest.cc +++ b/src/librbd/mirror/EnableRequest.cc @@ -21,9 +21,14 @@ using util::create_context_callback; using util::create_rados_ack_callback; template -EnableRequest::EnableRequest(I *image_ctx, Context *on_finish) - : m_io_ctx(&image_ctx->md_ctx), m_image_ctx(image_ctx), - m_on_finish(on_finish) { +EnableRequest::EnableRequest(librados::IoCtx &io_ctx, + const std::string &image_id, + 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_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())) { } template @@ -33,29 +38,31 @@ void EnableRequest::send() { template void EnableRequest::send_get_tag_owner() { - CephContext *cct = m_image_ctx->cct; - ldout(cct, 10) << this << " " << __func__ << dendl; + if (!m_non_primary_global_image_id.empty()) { + return + send_get_mirror_image(); + } + ldout(m_cct, 10) << this << " " << __func__ << dendl; using klass = EnableRequest; Context *ctx = create_context_callback< klass, &klass::handle_get_tag_owner>(this); - - librbd::Journal<>::is_tag_owner(m_image_ctx, &m_is_primary, ctx); + librbd::Journal<>::is_tag_owner(m_io_ctx, m_image_id, &m_is_primary, + m_op_work_queue, ctx); } template Context *EnableRequest::handle_get_tag_owner(int *result) { - CephContext *cct = m_image_ctx->cct; - ldout(cct, 10) << this << " " << __func__ << ": r=" << *result << dendl; + ldout(m_cct, 10) << this << " " << __func__ << ": r=" << *result << dendl; if (*result < 0) { - lderr(cct) << "failed to check tag ownership: " << cpp_strerror(*result) - << dendl; + lderr(m_cct) << "failed to check tag ownership: " << cpp_strerror(*result) + << dendl; return m_on_finish; } if (!m_is_primary) { - lderr(cct) << "last journal tag not owned by local cluster" << dendl; + lderr(m_cct) << "last journal tag not owned by local cluster" << dendl; *result = -EINVAL; return m_on_finish; } @@ -66,25 +73,23 @@ Context *EnableRequest::handle_get_tag_owner(int *result) { template void EnableRequest::send_get_mirror_image() { - CephContext *cct = m_image_ctx->cct; - ldout(cct, 10) << this << " " << __func__ << dendl; + ldout(m_cct, 10) << this << " " << __func__ << dendl; librados::ObjectReadOperation op; - cls_client::mirror_image_get_start(&op, m_image_ctx->id); + cls_client::mirror_image_get_start(&op, m_image_id); using klass = EnableRequest; librados::AioCompletion *comp = create_rados_ack_callback(this); m_out_bl.clear(); - int r = m_image_ctx->md_ctx.aio_operate(RBD_MIRRORING, comp, &op, &m_out_bl); + int r = m_io_ctx.aio_operate(RBD_MIRRORING, comp, &op, &m_out_bl); assert(r == 0); comp->release(); } template Context *EnableRequest::handle_get_mirror_image(int *result) { - CephContext *cct = m_image_ctx->cct; - ldout(cct, 10) << this << " " << __func__ << ": r=" << *result << dendl; + ldout(m_cct, 10) << this << " " << __func__ << ": r=" << *result << dendl; if (*result == 0) { bufferlist::iterator iter = m_out_bl.begin(); @@ -93,26 +98,30 @@ Context *EnableRequest::handle_get_mirror_image(int *result) { if (*result == 0) { if (m_mirror_image.state == cls::rbd::MIRROR_IMAGE_STATE_ENABLED) { - ldout(cct, 10) << this << " " << __func__ - << ": mirroring is already enabled" << dendl; + ldout(m_cct, 10) << this << " " << __func__ + << ": mirroring is already enabled" << dendl; } else { - lderr(cct) << "currently disabling" << dendl; + lderr(m_cct) << "currently disabling" << dendl; *result = -EINVAL; } return m_on_finish; } if (*result != -ENOENT) { - lderr(cct) << "failed to retreive mirror image: " << cpp_strerror(*result) - << dendl; + lderr(m_cct) << "failed to retreive mirror image: " << cpp_strerror(*result) + << dendl; return m_on_finish; } *result = 0; m_mirror_image.state = cls::rbd::MIRROR_IMAGE_STATE_ENABLED; - uuid_d uuid_gen; - uuid_gen.generate_random(); - m_mirror_image.global_image_id = uuid_gen.to_string(); + if (m_non_primary_global_image_id.empty()) { + uuid_d uuid_gen; + uuid_gen.generate_random(); + m_mirror_image.global_image_id = uuid_gen.to_string(); + } else { + m_mirror_image.global_image_id = m_non_primary_global_image_id; + } send_set_mirror_image(); return nullptr; @@ -120,29 +129,27 @@ Context *EnableRequest::handle_get_mirror_image(int *result) { template void EnableRequest::send_set_mirror_image() { - CephContext *cct = m_image_ctx->cct; - ldout(cct, 10) << this << " " << __func__ << dendl; + ldout(m_cct, 10) << this << " " << __func__ << dendl; librados::ObjectWriteOperation op; - cls_client::mirror_image_set(&op, m_image_ctx->id, m_mirror_image); + cls_client::mirror_image_set(&op, m_image_id, m_mirror_image); using klass = EnableRequest; librados::AioCompletion *comp = create_rados_ack_callback(this); m_out_bl.clear(); - int r = m_image_ctx->md_ctx.aio_operate(RBD_MIRRORING, comp, &op); + int r = m_io_ctx.aio_operate(RBD_MIRRORING, comp, &op); assert(r == 0); comp->release(); } template Context *EnableRequest::handle_set_mirror_image(int *result) { - CephContext *cct = m_image_ctx->cct; - ldout(cct, 10) << this << " " << __func__ << ": r=" << *result << dendl; + ldout(m_cct, 10) << this << " " << __func__ << ": r=" << *result << dendl; if (*result < 0) { - lderr(cct) << "failed to enable mirroring: " << cpp_strerror(*result) - << dendl; + lderr(m_cct) << "failed to enable mirroring: " << cpp_strerror(*result) + << dendl; return m_on_finish; } @@ -152,27 +159,25 @@ Context *EnableRequest::handle_set_mirror_image(int *result) { template void EnableRequest::send_notify_mirroring_watcher() { - CephContext *cct = m_image_ctx->cct; - ldout(cct, 10) << this << " " << __func__ << dendl; + ldout(m_cct, 10) << this << " " << __func__ << dendl; using klass = EnableRequest; Context *ctx = create_context_callback< klass, &klass::handle_notify_mirroring_watcher>(this); - MirroringWatcher<>::notify_image_updated(m_image_ctx->md_ctx, + MirroringWatcher<>::notify_image_updated(m_io_ctx, cls::rbd::MIRROR_IMAGE_STATE_ENABLED, - m_image_ctx->id, + m_image_id, m_mirror_image.global_image_id, ctx); } template Context *EnableRequest::handle_notify_mirroring_watcher(int *result) { - CephContext *cct = m_image_ctx->cct; - ldout(cct, 10) << this << " " << __func__ << ": r=" << *result << dendl; + ldout(m_cct, 10) << this << " " << __func__ << ": r=" << *result << dendl; if (*result < 0) { - lderr(cct) << "failed to send update notification: " - << cpp_strerror(*result) << dendl; + lderr(m_cct) << "failed to send update notification: " + << cpp_strerror(*result) << dendl; *result = 0; } diff --git a/src/librbd/mirror/EnableRequest.h b/src/librbd/mirror/EnableRequest.h index 8860365de3c57..e2145374a2cbf 100644 --- a/src/librbd/mirror/EnableRequest.h +++ b/src/librbd/mirror/EnableRequest.h @@ -10,6 +10,7 @@ #include class Context; +class ContextWQ; namespace librados { class IoCtx; } @@ -23,7 +24,15 @@ template class EnableRequest { public: static EnableRequest *create(ImageCtxT *image_ctx, Context *on_finish) { - return new EnableRequest(image_ctx, on_finish); + return create(image_ctx->md_ctx, image_ctx->id, "", + image_ctx->op_work_queue, on_finish); + } + static EnableRequest *create(librados::IoCtx &io_ctx, + const std::string &image_id, + const std::string &non_primary_global_image_id, + ContextWQ *op_work_queue, Context *on_finish) { + return new EnableRequest(io_ctx, image_id, non_primary_global_image_id, + op_work_queue, on_finish); } void send(); @@ -35,6 +44,9 @@ private: * * | * v + * GET_MIRROR_MODE * * * * * * * + * | * + * v * * GET_TAG_OWNER * * * * * * * * * | * * v * @@ -52,13 +64,17 @@ private: * @endverbatim */ - EnableRequest(ImageCtxT *image_ctx, Context *on_finish); + EnableRequest(librados::IoCtx &io_ctx, const std::string &image_id, + const std::string &non_primary_global_image_id, + ContextWQ *op_work_queue, Context *on_finish); - librados::IoCtx *m_io_ctx = nullptr; + librados::IoCtx &m_io_ctx; std::string m_image_id; - ImageCtxT *m_image_ctx = nullptr; + 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; diff --git a/src/test/librbd/test_mock_Journal.cc b/src/test/librbd/test_mock_Journal.cc index ced44da91efc2..0683ca282c646 100644 --- a/src/test/librbd/test_mock_Journal.cc +++ b/src/test/librbd/test_mock_Journal.cc @@ -186,7 +186,6 @@ OpenRequest *OpenRequest::s_instance = // template definitions #include "librbd/Journal.cc" -template class librbd::Journal; using ::testing::_; using ::testing::DoAll; diff --git a/src/test/rbd_mirror/image_replayer/test_mock_CreateImageRequest.cc b/src/test/rbd_mirror/image_replayer/test_mock_CreateImageRequest.cc index 3796d7af37469..d18fade118318 100644 --- a/src/test/rbd_mirror/image_replayer/test_mock_CreateImageRequest.cc +++ b/src/test/rbd_mirror/image_replayer/test_mock_CreateImageRequest.cc @@ -40,9 +40,13 @@ struct CreateRequest { const librbd::ImageOptions &image_options, const std::string &non_primary_global_image_id, const std::string &primary_mirror_uuid, + bool skip_mirror_enable, MockContextWQ *op_work_queue, Context *on_finish) { assert(s_instance != nullptr); + EXPECT_FALSE(non_primary_global_image_id.empty()); + EXPECT_FALSE(primary_mirror_uuid.empty()); + EXPECT_FALSE(skip_mirror_enable); s_instance->on_finish = on_finish; s_instance->construct(ioctx); return s_instance; diff --git a/src/tools/rbd_mirror/image_replayer/CreateImageRequest.cc b/src/tools/rbd_mirror/image_replayer/CreateImageRequest.cc index 27c6c1ca2bde6..ae55f62a4fe83 100644 --- a/src/tools/rbd_mirror/image_replayer/CreateImageRequest.cc +++ b/src/tools/rbd_mirror/image_replayer/CreateImageRequest.cc @@ -77,7 +77,7 @@ void CreateImageRequest::create_image() { librbd::image::CreateRequest *req = librbd::image::CreateRequest::create( m_local_io_ctx, m_local_image_name, id, m_remote_image_ctx->size, - image_options, m_global_image_id, m_remote_mirror_uuid, + image_options, m_global_image_id, m_remote_mirror_uuid, false, m_remote_image_ctx->op_work_queue, ctx); req->send(); } -- 2.39.5