]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: trash move should disable mirroring first if snapshot-based
authorJason Dillaman <dillaman@redhat.com>
Thu, 27 Feb 2020 02:31:46 +0000 (21:31 -0500)
committerJason Dillaman <dillaman@redhat.com>
Thu, 27 Feb 2020 21:33:21 +0000 (16:33 -0500)
The remote rbd-mirror might own the exclusive lock (if any) which would
normally prevent 'trash move' from functioning. If using snapshot-based
mirroring, disable mirroring first to ensure the remote rbd-mirror
will have lost the lock.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/api/Trash.cc

index 8987f4d03d526fef1e9457bc58d30bee24c6454c..7d615050a254bfa2d783ceb0992b5ab8f2eaff51 100644 (file)
@@ -43,25 +43,12 @@ namespace {
 
 template <typename I>
 int disable_mirroring(I *ictx) {
-  cls::rbd::MirrorImage mirror_image;
-  int r = cls_client::mirror_image_get(&ictx->md_ctx, ictx->id, &mirror_image);
-  if (r == -ENOENT) {
-    ldout(ictx->cct, 10) << "mirroring is not enabled for this image" << dendl;
-    return 0;
-  }
-
-  if (r < 0) {
-    lderr(ictx->cct) << "failed to retrieve mirror image: " << cpp_strerror(r)
-                     << dendl;
-    return r;
-  }
-
   ldout(ictx->cct, 10) << dendl;
 
   C_SaferCond ctx;
   auto req = mirror::DisableRequest<I>::create(ictx, false, true, &ctx);
   req->send();
-  r = ctx.wait();
+  int r = ctx.wait();
   if (r < 0) {
     lderr(ictx->cct) << "failed to disable mirroring: " << cpp_strerror(r)
                      << dendl;
@@ -141,6 +128,26 @@ int Trash<I>::move(librados::IoCtx &io_ctx, rbd_trash_image_source_t source,
   }
 
   if (r == 0) {
+    cls::rbd::MirrorImage mirror_image;
+    int mirror_r = cls_client::mirror_image_get(&ictx->md_ctx, ictx->id,
+                                                &mirror_image);
+    if (mirror_r == -ENOENT) {
+      ldout(ictx->cct, 10) << "mirroring is not enabled for this image"
+                           << dendl;
+    } else if (mirror_r < 0) {
+      lderr(ictx->cct) << "failed to retrieve mirror image: "
+                       << cpp_strerror(mirror_r) << dendl;
+      return mirror_r;
+    } else if (mirror_image.mode == cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT) {
+      // a remote rbd-mirror might own the exclusive-lock on this image
+      // and therefore we need to disable mirroring so that it closes the image
+      r = disable_mirroring<I>(ictx);
+      if (r < 0) {
+        ictx->state->close();
+        return r;
+      }
+    }
+
     if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
       std::unique_lock image_locker{ictx->image_lock};
       ictx->set_journal_policy(new journal::DisabledPolicy());
@@ -170,10 +177,13 @@ int Trash<I>::move(librados::IoCtx &io_ctx, rbd_trash_image_source_t source,
     }
     ictx->image_lock.unlock_shared();
 
-    r = disable_mirroring<I>(ictx);
-    if (r < 0) {
-      ictx->state->close();
-      return r;
+    if (mirror_r >= 0 &&
+        mirror_image.mode != cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT) {
+      r = disable_mirroring<I>(ictx);
+      if (r < 0) {
+        ictx->state->close();
+        return r;
+      }
     }
 
     ictx->state->close();