]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: fix rollback if failed to disable mirroring for image 11260/head
authorrunsisi <runsisi@hust.edu.cn>
Thu, 29 Sep 2016 07:57:20 +0000 (15:57 +0800)
committerrunsisi <runsisi@hust.edu.cn>
Sat, 1 Oct 2016 05:29:23 +0000 (13:29 +0800)
Signed-off-by: runsisi <runsisi@zte.com.cn>
src/librbd/internal.cc

index fe8f0f4680f5d922131c58c573dcebe31f66e621..17dd6e57cdb34696a5743ad77e784f93bffe26e0 100644 (file)
@@ -2467,10 +2467,9 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
       return r;
     } else {
       bool rollback = false;
-      BOOST_SCOPE_EXIT_ALL(ictx, rollback) {
+      BOOST_SCOPE_EXIT_ALL(ictx, &mirror_image_internal, &rollback) {
         if (rollback) {
           CephContext *cct = ictx->cct;
-          cls::rbd::MirrorImage mirror_image_internal;
           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) {
@@ -2480,46 +2479,50 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
         }
       };
 
-      RWLock::RLocker l(ictx->snap_lock);
-      map<librados::snap_t, SnapInfo> snap_info = ictx->snap_info;
-      for (auto &info : snap_info) {
-        librbd::parent_spec parent_spec(ictx->md_ctx.get_id(), ictx->id, info.first);
-        map< pair<int64_t, string>, set<string> > image_info;
+      {
+        RWLock::RLocker l(ictx->snap_lock);
+        map<librados::snap_t, SnapInfo> snap_info = ictx->snap_info;
+        for (auto &info : snap_info) {
+          librbd::parent_spec parent_spec(ictx->md_ctx.get_id(), ictx->id, info.first);
+          map< pair<int64_t, string>, set<string> > image_info;
 
-        r = list_children_info(ictx, parent_spec, image_info);
-        if (r < 0) {
-          rollback = true;
-          return r;
-        }
-        if (image_info.empty())
-          continue;
-
-        Rados rados(ictx->md_ctx);
-        for (auto &info: image_info) {
-          IoCtx ioctx;
-          r = rados.ioctx_create2(info.first.first, ioctx);
+          r = list_children_info(ictx, parent_spec, image_info);
           if (r < 0) {
             rollback = true;
-            lderr(cct) << "Error accessing child image pool " << info.first.second  << dendl; 
             return r;
           }
-          for (auto &id_it : info.second) {
-            cls::rbd::MirrorImage mirror_image_internal;
-            r = cls_client::mirror_image_get(&ioctx, id_it, &mirror_image_internal);
-            if (r != -ENOENT) {
+          if (image_info.empty())
+            continue;
+
+          Rados rados(ictx->md_ctx);
+          for (auto &info: image_info) {
+            IoCtx ioctx;
+            r = rados.ioctx_create2(info.first.first, ioctx);
+            if (r < 0) {
               rollback = true;
-              lderr(cct) << "mirroring is enabled on one or more children " << dendl;
-              return -EBUSY;
+              lderr(cct) << "Error accessing child image pool " << info.first.second  << dendl;
+              return r;
+            }
+            for (auto &id_it : info.second) {
+              cls::rbd::MirrorImage mirror_image_internal;
+              r = cls_client::mirror_image_get(&ioctx, id_it, &mirror_image_internal);
+              if (r != -ENOENT) {
+                rollback = true;
+                lderr(cct) << "mirroring is enabled on one or more children " << dendl;
+                return -EBUSY;
+              }
             }
           }
         }
       }
-    }
 
-    r = mirror_image_disable_internal(ictx, force);
-    if (r < 0) {
-      return r;
+      r = mirror_image_disable_internal(ictx, force);
+      if (r < 0) {
+        rollback = true;
+        return r;
+      }
     }
+
     return 0;
   }