From 9d138465f63a72e89ec0eeb9b0ef2fd0ba918709 Mon Sep 17 00:00:00 2001 From: Prasanna Kumar Kalever Date: Thu, 17 Apr 2025 20:34:21 +0530 Subject: [PATCH] librbd/api: fix mirror group demote Signed-off-by: Prasanna Kumar Kalever --- src/librbd/api/Mirror.cc | 72 +++++++++++++--------------------------- 1 file changed, 23 insertions(+), 49 deletions(-) diff --git a/src/librbd/api/Mirror.cc b/src/librbd/api/Mirror.cc index 58d0d8e0caa..ca43cbf4b69 100644 --- a/src/librbd/api/Mirror.cc +++ b/src/librbd/api/Mirror.cc @@ -3444,7 +3444,6 @@ int Mirror::group_demote(IoCtx& group_ioctx, int ret_code = 0; std::vector snap_ids(image_ctxs.size(), CEPH_NOSNAP); std::vector on_finishes(image_ctxs.size(), nullptr); - C_SaferCond* on_finish; for (size_t i = 0; i < image_ctxs.size(); i++) { C_SaferCond* on_finish = new C_SaferCond; @@ -3467,62 +3466,37 @@ int Mirror::group_demote(IoCtx& group_ioctx, } std::string group_header_oid = librbd::util::group_header_name(group_id); - if (ret_code < 0) { - // undo - ldout(cct, 20) << "undoing group demote: " << ret_code << dendl; - remove_group_snap(group_ioctx, group_id, &group_snap, &image_ctxs); - std::fill(snap_ids.begin(), snap_ids.end(), CEPH_NOSNAP); - group_snap.snaps.clear(); - close_images(&image_ctxs); - - r = prepare_group_images(group_ioctx, group_id, mirror_group.state, - &image_ctxs, &group_snap, quiesce_requests, - cls::rbd::MIRROR_SNAPSHOT_STATE_PRIMARY_DEMOTED, - &mirror_peer_uuids, - SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE); - if (r != 0) { - return r; - } - for (size_t i = 0; i < image_ctxs.size(); ++i) { - ImageCtx *ictx = image_ctxs[i]; - ldout(cct, 20) << "promoting individual images: " - << ictx->name.c_str() << dendl; - - on_finish = new C_SaferCond; - image_promote(ictx, group_snap_id, false, &snap_ids[i], on_finish); // No force? - on_finishes[i] = on_finish; - } - - for (int i = 0, n = image_ctxs.size(); i < n; ++i) { - if (!on_finishes[i]) { - continue; - } - r = on_finishes[i]->wait(); - delete on_finishes[i]; - if (r < 0) { - lderr(cct) << "failed promoting image: " << image_ctxs[i]->name - << ": " << cpp_strerror(r) << dendl; - // just report error, but don't abort the process - } else { - group_snap.snaps[i].snap_id = snap_ids[i]; - } - } - } - if (!ret_code) { group_snap.state = cls::rbd::GROUP_SNAPSHOT_STATE_COMPLETE; r = cls_client::group_snap_set(&group_ioctx, group_header_oid, group_snap); if (r < 0) { lderr(cct) << "failed to update group snapshot metadata: " << cpp_strerror(r) << dendl; + } else { + group_unlink_peer(group_ioctx, group_id, &mirror_peer_uuids, &image_ctxs); + + // mask the bit for treating the non-primary feature as read-only + for (size_t i = 0; i < image_ctxs.size(); ++i) { + ImageCtx *ictx = image_ctxs[i]; + ictx->image_lock.lock(); + ictx->read_only_mask |= IMAGE_READ_ONLY_FLAG_NON_PRIMARY; + ictx->image_lock.unlock(); + } } - group_unlink_peer(group_ioctx, group_id, &mirror_peer_uuids, &image_ctxs); + ret_code = r; } - for (size_t i = 0; i < image_ctxs.size(); ++i) { - ImageCtx *ictx = image_ctxs[i]; - ictx->image_lock.lock(); - ictx->read_only_mask |= IMAGE_READ_ONLY_FLAG_NON_PRIMARY; - ictx->image_lock.unlock(); + + if (ret_code < 0) { + // undo + ldout(cct, 20) << "undoing group demote: " << ret_code << dendl; + remove_group_snap(group_ioctx, group_id, &group_snap, &image_ctxs); + // don't let the non-primary feature bit prevent image updates + for (size_t i = 0; i < image_ctxs.size(); ++i) { + ImageCtx *ictx = image_ctxs[i]; + ictx->image_lock.lock(); + ictx->read_only_mask &= ~IMAGE_READ_ONLY_FLAG_NON_PRIMARY; + ictx->image_lock.unlock(); + } } close_images(&image_ctxs); -- 2.39.5