From: Jason Dillaman Date: Mon, 24 Feb 2020 22:33:51 +0000 (-0500) Subject: librbd: remove snapshot mirror image-meta when disabling X-Git-Tag: v15.1.1~224^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=281a64acf9201012ae8a58aa479bd30797f4e96a;p=ceph.git librbd: remove snapshot mirror image-meta when disabling Remove the snapshot-based mirroring image-meta key/value pair (if any) when disabling mirroring. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/api/Mirror.cc b/src/librbd/api/Mirror.cc index a43c6a1557b0..849aeacfd3d8 100644 --- a/src/librbd/api/Mirror.cc +++ b/src/librbd/api/Mirror.cc @@ -28,6 +28,7 @@ #include "librbd/mirror/snapshot/CreatePrimaryRequest.h" #include "librbd/mirror/snapshot/ImageMeta.h" #include "librbd/mirror/snapshot/UnlinkPeerRequest.h" +#include "librbd/mirror/snapshot/Utils.h" #include #include #include @@ -474,89 +475,107 @@ int Mirror::image_disable(I *ictx, bool force) { if (r < 0) { lderr(cct) << "cannot disable mirroring: " << cpp_strerror(r) << dendl; return r; - } else { - bool rollback = false; - BOOST_SCOPE_EXIT_ALL(ictx, &mirror_image_internal, &rollback) { - if (rollback) { - CephContext *cct = ictx->cct; - mirror_image_internal.state = cls::rbd::MIRROR_IMAGE_STATE_ENABLED; - int r = cls_client::mirror_image_set(&ictx->md_ctx, ictx->id, - mirror_image_internal); - if (r < 0) { - lderr(cct) << "failed to re-enable image mirroring: " - << cpp_strerror(r) << dendl; - } + } + + bool rollback = false; + BOOST_SCOPE_EXIT_ALL(ictx, &mirror_image_internal, &rollback) { + if (rollback) { + CephContext *cct = ictx->cct; + mirror_image_internal.state = cls::rbd::MIRROR_IMAGE_STATE_ENABLED; + int r = cls_client::mirror_image_set(&ictx->md_ctx, ictx->id, + mirror_image_internal); + if (r < 0) { + lderr(cct) << "failed to re-enable image mirroring: " + << cpp_strerror(r) << dendl; } - }; - - { - std::shared_lock l{ictx->image_lock}; - map snap_info = ictx->snap_info; - for (auto &info : snap_info) { - cls::rbd::ParentImageSpec parent_spec{ictx->md_ctx.get_id(), - ictx->md_ctx.get_namespace(), - ictx->id, info.first}; - std::vector child_images; - r = Image::list_children(ictx, parent_spec, &child_images); + } + }; + + std::unique_lock image_locker{ictx->image_lock}; + map snap_info = ictx->snap_info; + for (auto &info : snap_info) { + cls::rbd::ParentImageSpec parent_spec{ictx->md_ctx.get_id(), + ictx->md_ctx.get_namespace(), + ictx->id, info.first}; + std::vector child_images; + r = Image::list_children(ictx, parent_spec, &child_images); + if (r < 0) { + rollback = true; + return r; + } + + if (child_images.empty()) { + continue; + } + + librados::IoCtx child_io_ctx; + int64_t child_pool_id = -1; + for (auto &child_image : child_images){ + std::string pool = child_image.pool_name; + if (child_pool_id == -1 || + child_pool_id != child_image.pool_id || + child_io_ctx.get_namespace() != child_image.pool_namespace) { + r = util::create_ioctx(ictx->md_ctx, "child image", + child_image.pool_id, + child_image.pool_namespace, + &child_io_ctx); if (r < 0) { rollback = true; return r; } - if (child_images.empty()) { - continue; - } - - librados::IoCtx child_io_ctx; - int64_t child_pool_id = -1; - for (auto &child_image : child_images){ - std::string pool = child_image.pool_name; - if (child_pool_id == -1 || - child_pool_id != child_image.pool_id || - child_io_ctx.get_namespace() != child_image.pool_namespace) { - r = util::create_ioctx(ictx->md_ctx, "child image", - child_image.pool_id, - child_image.pool_namespace, - &child_io_ctx); - if (r < 0) { - rollback = true; - return r; - } - - child_pool_id = child_image.pool_id; - } + child_pool_id = child_image.pool_id; + } - cls::rbd::MirrorImage mirror_image_internal; - r = cls_client::mirror_image_get(&child_io_ctx, child_image.image_id, - &mirror_image_internal); - if (r != -ENOENT) { - rollback = true; - lderr(cct) << "mirroring is enabled on one or more children " - << dendl; - return -EBUSY; - } - } + cls::rbd::MirrorImage child_mirror_image_internal; + r = cls_client::mirror_image_get(&child_io_ctx, child_image.image_id, + &child_mirror_image_internal); + if (r != -ENOENT) { + rollback = true; + lderr(cct) << "mirroring is enabled on one or more children " + << dendl; + return -EBUSY; } } + } + image_locker.unlock(); - C_SaferCond ctx; - auto req = mirror::DisableRequest::create(ictx, force, true, - &ctx); - req->send(); - - r = ctx.wait(); + if (mirror_image_internal.mode == cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT) { + // remove any snapshot-based mirroring image-meta from image + std::string mirror_uuid; + r = uuid_get(ictx->md_ctx, &mirror_uuid); if (r < 0) { - lderr(cct) << "cannot disable mirroring: " << cpp_strerror(r) << dendl; rollback = true; return r; } - if (mirror_image_internal.mode == cls::rbd::MIRROR_IMAGE_MODE_JOURNAL) { - r = ictx->operations->update_features(RBD_FEATURE_JOURNALING, false); - if (r < 0) { - lderr(cct) << "cannot disable journaling: " << cpp_strerror(r) << dendl; - // not fatal - } + r = ictx->operations->metadata_remove( + mirror::snapshot::util::get_image_meta_key(mirror_uuid)); + if (r < 0 && r != -ENOENT) { + lderr(cct) << "cannot remove snapshot image-meta key: " << cpp_strerror(r) + << dendl; + rollback = true; + return r; + } + } + + C_SaferCond ctx; + auto req = mirror::DisableRequest::create(ictx, force, true, + &ctx); + req->send(); + + r = ctx.wait(); + if (r < 0) { + lderr(cct) << "cannot disable mirroring: " << cpp_strerror(r) << dendl; + rollback = true; + return r; + } + + if (mirror_image_internal.mode == cls::rbd::MIRROR_IMAGE_MODE_JOURNAL) { + r = ictx->operations->update_features(RBD_FEATURE_JOURNALING, false); + if (r < 0) { + lderr(cct) << "cannot disable journaling: " << cpp_strerror(r) << dendl; + // not fatal } }