]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: unlink the individual image snapshots taken as part of group snapshot
authorPrasanna Kumar Kalever <prasanna.kalever@redhat.com>
Thu, 24 Apr 2025 07:14:24 +0000 (12:44 +0530)
committerPrasanna Kumar Kalever <prasanna.kalever@redhat.com>
Wed, 30 Jul 2025 17:06:06 +0000 (22:36 +0530)
... but are not linked to group snapshot. This can happen when a mirror group
snapshot process crashes and the group snapshot is left in INCOMPLETE
state. The fix is to crawl through the list of images in the group and
match the individual image snapshots with a matching group snap id in
them and removing them.

Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
src/librbd/mirror/snapshot/GroupUnlinkPeerRequest.cc

index a7e4375b60974aa12ee3017eb1b1966b42ec691f..98f14be5c528fd3a997cdf7424a0fc0643f721c7 100644 (file)
@@ -206,6 +206,38 @@ void GroupUnlinkPeerRequest<I>::remove_group_snapshot(
                               cls::rbd::GroupSnapshot group_snap) {
   ldout(m_cct, 10) << "group snap id: " << group_snap.id << dendl;
 
+  auto ctx = create_context_callback<
+      GroupUnlinkPeerRequest,
+      &GroupUnlinkPeerRequest<I>::handle_remove_group_snapshot>(this);
+
+  m_group_snap_id = group_snap.id;
+
+  C_Gather *gather_ctx = new C_Gather(m_cct, ctx);
+  if (group_snap.state == cls::rbd::GROUP_SNAPSHOT_STATE_INCOMPLETE) {
+    for (size_t i = 0; i < m_image_ctxs->size(); ++i) {
+      ImageCtx *ictx = (*m_image_ctxs)[i];
+      for (auto it = ictx->snap_info.rbegin();
+           it != ictx->snap_info.rend(); it++) {
+        if (it->first == CEPH_NOSNAP) {
+          continue;
+        }
+        auto mirror_ns = std::get_if<cls::rbd::MirrorSnapshotNamespace>(
+            &it->second.snap_namespace);
+        if (mirror_ns == nullptr) {
+          continue;
+        }
+        if (mirror_ns->group_snap_id == m_group_snap_id) {
+          ldout(m_cct, 10) << "removing individual snapshot: "
+                           << it->first << ", from image id:"
+                           << ictx->id << dendl;
+          remove_image_snapshot(ictx, it->first, gather_ctx);
+        }
+      }
+    }
+    gather_ctx->activate();
+    return;
+  }
+
   //TODO: Handle dynamic group membership
   if (!m_image_ctxs->empty() && m_image_ctx_map.empty()) {
     for (size_t i = 0; i < m_image_ctxs->size(); ++i) {
@@ -214,13 +246,6 @@ void GroupUnlinkPeerRequest<I>::remove_group_snapshot(
     }
   }
 
-  auto ctx = create_context_callback<
-      GroupUnlinkPeerRequest,
-      &GroupUnlinkPeerRequest<I>::handle_remove_group_snapshot>(this);
-
-  m_group_snap_id = group_snap.id;
-
-  C_Gather *gather_ctx = new C_Gather(m_cct, ctx);
   for (auto &snap : group_snap.snaps) {
     if (snap.snap_id == CEPH_NOSNAP) {
       continue;
@@ -240,9 +265,7 @@ void GroupUnlinkPeerRequest<I>::remove_group_snapshot(
                      << snap.image_id << dendl;
     remove_image_snapshot(ictx, snap.snap_id, gather_ctx);
   }
-
   gather_ctx->activate();
-
 }
 
 template <typename I>