From 244bbd20b282532691cae3159f3c28dc8df600a1 Mon Sep 17 00:00:00 2001 From: Mykola Golub Date: Fri, 18 Dec 2020 10:15:11 +0000 Subject: [PATCH] librbd: don't send 'image updated' notifications when enabling/disabling group mirroring Signed-off-by: Mykola Golub Signed-off-by: Prasanna Kumar Kalever --- src/librbd/mirror/ImageRemoveRequest.cc | 90 ++++++++++++++++ src/librbd/mirror/ImageRemoveRequest.h | 18 +++- src/librbd/mirror/ImageStateUpdateRequest.cc | 108 +++++++++++++++++-- src/librbd/mirror/ImageStateUpdateRequest.h | 17 ++- 4 files changed, 225 insertions(+), 8 deletions(-) diff --git a/src/librbd/mirror/ImageRemoveRequest.cc b/src/librbd/mirror/ImageRemoveRequest.cc index 1aa265dae6033..542d38d5697ef 100644 --- a/src/librbd/mirror/ImageRemoveRequest.cc +++ b/src/librbd/mirror/ImageRemoveRequest.cc @@ -28,6 +28,90 @@ ImageRemoveRequest::ImageRemoveRequest( template void ImageRemoveRequest::send() { + get_group(); +} + +template +void ImageRemoveRequest::get_group() { + ldout(m_cct, 10) << dendl; + librados::ObjectReadOperation op; + cls_client::image_group_get_start(&op); + + auto comp = create_rados_callback< + ImageRemoveRequest, &ImageRemoveRequest::handle_get_group>(this); + m_out_bl.clear(); + int r = m_io_ctx.aio_operate(util::header_name(m_image_id), comp, &op, + &m_out_bl); + ceph_assert(r == 0); + comp->release(); +} + +template +void ImageRemoveRequest::handle_get_group(int r) { + ldout(m_cct, 10) << "r=" << r << dendl; + + if (r == 0) { + auto iter = m_out_bl.cbegin(); + r = cls_client::image_group_get_finish(&iter, &m_group_spec); + } + + if (r < 0) { + lderr(m_cct) << "failed to retrieve image group: " << cpp_strerror(r) + << dendl; + finish(r); + return; + } + + get_mirror_group(); +} + +template +void ImageRemoveRequest::get_mirror_group() { + if (!m_group_spec.is_valid()) { + m_mirror_group.state = cls::rbd::MIRROR_GROUP_STATE_DISABLED; + remove_mirror_image(); + return; + } + + ldout(m_cct, 10) << dendl; + + int r = util::create_ioctx(m_io_ctx, "group", m_group_spec.pool_id, {}, + &m_group_io_ctx); + if (r < 0) { + finish(r); + return; + } + + librados::ObjectReadOperation op; + cls_client::mirror_group_get_start(&op, m_group_spec.group_id); + + auto comp = create_rados_callback< + ImageRemoveRequest, + &ImageRemoveRequest::handle_get_mirror_group>(this); + m_out_bl.clear(); + r = m_group_io_ctx.aio_operate(RBD_MIRRORING, comp, &op, &m_out_bl); + ceph_assert(r == 0); + comp->release(); +} + +template +void ImageRemoveRequest::handle_get_mirror_group(int r) { + ldout(m_cct, 10) << "r=" << r << dendl; + + if (r == 0) { + auto iter = m_out_bl.cbegin(); + r = cls_client::mirror_group_get_finish(&iter, &m_mirror_group); + } + + if (r == -ENOENT) { + m_mirror_group.state = cls::rbd::MIRROR_GROUP_STATE_DISABLED; + } else if (r < 0) { + lderr(m_cct) << "failed to retrieve group mirroring state: " + << cpp_strerror(r) << dendl; + finish(r); + return; + } + remove_mirror_image(); } @@ -62,6 +146,12 @@ void ImageRemoveRequest::handle_remove_mirror_image(int r) { template void ImageRemoveRequest::notify_mirroring_watcher() { + // skip image notification if mirroring for the image group is disabling + if (m_mirror_group.state == cls::rbd::MIRROR_GROUP_STATE_DISABLING) { + finish(0); + return; + } + ldout(m_cct, 10) << dendl; auto ctx = util::create_context_callback< diff --git a/src/librbd/mirror/ImageRemoveRequest.h b/src/librbd/mirror/ImageRemoveRequest.h index c04f9fadc2067..0ad516622ebc8 100644 --- a/src/librbd/mirror/ImageRemoveRequest.h +++ b/src/librbd/mirror/ImageRemoveRequest.h @@ -41,10 +41,16 @@ private: * * * | + * GET_GROUP + * | + * v + * GET_MIRROR_GROUP (skip if no group) + * | + * v * REMOVE_MIRROR_IMAGE * | * v - * NOTIFY_MIRRORING_WATCHER + * NOTIFY_MIRRORING_WATCHER (skip if not needed) * | * v * @@ -58,6 +64,16 @@ private: Context* m_on_finish; CephContext* m_cct; + bufferlist m_out_bl; + librados::IoCtx m_group_io_ctx; + cls::rbd::GroupSpec m_group_spec; + cls::rbd::MirrorGroup m_mirror_group; + + void get_group(); + void handle_get_group(int r); + + void get_mirror_group(); + void handle_get_mirror_group(int r); void remove_mirror_image(); void handle_remove_mirror_image(int r); diff --git a/src/librbd/mirror/ImageStateUpdateRequest.cc b/src/librbd/mirror/ImageStateUpdateRequest.cc index fd7ec4507fa5d..34a1903e2601c 100644 --- a/src/librbd/mirror/ImageStateUpdateRequest.cc +++ b/src/librbd/mirror/ImageStateUpdateRequest.cc @@ -39,7 +39,12 @@ void ImageStateUpdateRequest::send() { template void ImageStateUpdateRequest::get_mirror_image() { if (!m_mirror_image.global_image_id.empty()) { - set_mirror_image(); + if (m_mirror_image.state == m_mirror_image_state) { + finish(0); + return; + } + + get_group(); return; } @@ -75,13 +80,54 @@ void ImageStateUpdateRequest::handle_get_mirror_image(int r) { return; } - set_mirror_image(); + if (m_mirror_image.state == m_mirror_image_state) { + finish(0); + return; + } + + get_group(); } template -void ImageStateUpdateRequest::set_mirror_image() { - if (m_mirror_image.state == m_mirror_image_state) { - finish(0); +void ImageStateUpdateRequest::get_group() { + ldout(m_cct, 10) << dendl; + librados::ObjectReadOperation op; + cls_client::image_group_get_start(&op); + + auto comp = create_rados_callback< + ImageStateUpdateRequest, + &ImageStateUpdateRequest::handle_get_group>(this); + m_out_bl.clear(); + int r = m_io_ctx.aio_operate(util::header_name(m_image_id), comp, &op, + &m_out_bl); + ceph_assert(r == 0); + comp->release(); +} + +template +void ImageStateUpdateRequest::handle_get_group(int r) { + ldout(m_cct, 10) << "r=" << r << dendl; + + if (r == 0) { + auto iter = m_out_bl.cbegin(); + r = cls_client::image_group_get_finish(&iter, &m_group_spec); + } + + if (r < 0) { + lderr(m_cct) << "failed to retrieve image group: " << cpp_strerror(r) + << dendl; + finish(r); + return; + } + + get_mirror_group(); +} + +template +void ImageStateUpdateRequest::get_mirror_group() { + if (!m_group_spec.is_valid()) { + m_mirror_group.state = cls::rbd::MIRROR_GROUP_STATE_DISABLED; + set_mirror_image(); return; } else if (m_mirror_group.state == cls::rbd::MIRROR_GROUP_STATE_ENABLED || m_mirror_group.state == cls::rbd::MIRROR_GROUP_STATE_ENABLING) { @@ -89,6 +135,50 @@ void ImageStateUpdateRequest::set_mirror_image() { m_mirror_image.group_spec = m_group_spec; } + ldout(m_cct, 10) << dendl; + + int r = util::create_ioctx(m_io_ctx, "group", m_group_spec.pool_id, {}, + &m_group_io_ctx); + if (r < 0) { + finish(r); + return; + } + + librados::ObjectReadOperation op; + cls_client::mirror_group_get_start(&op, m_group_spec.group_id); + + auto comp = create_rados_callback< + ImageStateUpdateRequest, + &ImageStateUpdateRequest::handle_get_mirror_group>(this); + m_out_bl.clear(); + r = m_group_io_ctx.aio_operate(RBD_MIRRORING, comp, &op, &m_out_bl); + ceph_assert(r == 0); + comp->release(); +} + +template +void ImageStateUpdateRequest::handle_get_mirror_group(int r) { + ldout(m_cct, 10) << "r=" << r << dendl; + + if (r == 0) { + auto iter = m_out_bl.cbegin(); + r = cls_client::mirror_group_get_finish(&iter, &m_mirror_group); + } + + if (r == -ENOENT) { + m_mirror_group.state = cls::rbd::MIRROR_GROUP_STATE_DISABLED; + } else if (r < 0) { + lderr(m_cct) << "failed to retrieve group mirroring state: " + << cpp_strerror(r) << dendl; + finish(r); + return; + } + + set_mirror_image(); +} + +template +void ImageStateUpdateRequest::set_mirror_image() { ldout(m_cct, 10) << dendl; m_mirror_image.state = m_mirror_image_state; @@ -108,7 +198,7 @@ void ImageStateUpdateRequest::handle_set_mirror_image(int r) { ldout(m_cct, 10) << "r=" << r << dendl; if (r < 0) { - lderr(m_cct) << "failed to disable mirroring image: " << cpp_strerror(r) + lderr(m_cct) << "failed to set mirror image: " << cpp_strerror(r) << dendl; finish(r); return; @@ -119,6 +209,12 @@ void ImageStateUpdateRequest::handle_set_mirror_image(int r) { template void ImageStateUpdateRequest::notify_mirroring_watcher() { + // skip image notification if mirroring for the image group is disabled + if (m_mirror_group.state != cls::rbd::MIRROR_GROUP_STATE_DISABLED) { + finish(0); + return; + } + ldout(m_cct, 10) << dendl; auto ctx = util::create_context_callback< diff --git a/src/librbd/mirror/ImageStateUpdateRequest.h b/src/librbd/mirror/ImageStateUpdateRequest.h index 9e0affe6a99a1..1db953d2da57e 100644 --- a/src/librbd/mirror/ImageStateUpdateRequest.h +++ b/src/librbd/mirror/ImageStateUpdateRequest.h @@ -51,10 +51,16 @@ private: * GET_MIRROR_IMAGE * | * v + * GET_GROUP + * | + * v + * GET_MIRROR_GROUP (skip if no group) + * | + * v * SET_MIRROR_IMAGE * | * v - * NOTIFY_MIRRORING_WATCHER + * NOTIFY_MIRRORING_WATCHER (skip if not needed) * | * v * @@ -70,10 +76,19 @@ private: CephContext* m_cct; bufferlist m_out_bl; + librados::IoCtx m_group_io_ctx; + cls::rbd::GroupSpec m_group_spec; + cls::rbd::MirrorGroup m_mirror_group; void get_mirror_image(); void handle_get_mirror_image(int r); + void get_group(); + void handle_get_group(int r); + + void get_mirror_group(); + void handle_get_mirror_group(int r); + void set_mirror_image(); void handle_set_mirror_image(int r); -- 2.39.5