]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: allow remove all unprotected snapshots 20608/head
authorsongweibin <song.weibin@zte.com.cn>
Thu, 1 Mar 2018 12:28:12 +0000 (20:28 +0800)
committersongweibin <song.weibin@zte.com.cn>
Thu, 1 Mar 2018 13:01:24 +0000 (21:01 +0800)
allow remove all unprotected snapshots when exiting
protected snapshots in the same image.
Fixes: http://tracker.ceph.com/issues/23126
Signed-off-by: songweibin <song.weibin@zte.com.cn>
doc/man/8/rbd.rst
src/test/cli/rbd/help.t
src/tools/rbd/action/Snap.cc

index 1f2ba758f0e78def8bb536e2ddd8083c3d8cd0b1..fbbbc9aaecda6e2c8ee0492c720b49f41d02694e 100644 (file)
@@ -510,7 +510,7 @@ Commands
   This requires image format 2.
 
 :command:`snap purge` *image-spec*
-  Remove all snapshots from an image.
+  Remove all unprotected snapshots from an image.
 
 :command:`snap rename` *src-snap-spec* *dest-snap-spec*
   Rename a snapshot. Note: rename across pools and images is not supported.
index f87d3347c614a85fd0506f4743682ff66589b932..dc0f40e653df261b46e28120dac4f621689ae8aa 100644 (file)
@@ -93,7 +93,7 @@
       snap limit set                      Limit the number of snapshots.
       snap list (snap ls)                 Dump list of image snapshots.
       snap protect                        Prevent a snapshot from being deleted.
-      snap purge                          Delete all snapshots.
+      snap purge                          Delete all unprotected snapshots.
       snap remove (snap rm)               Delete a snapshot.
       snap rename                         Rename a snapshot.
       snap rollback (snap revert)         Rollback image to snapshot.
                         [--image-id <image-id>] [--no-progress] 
                         <image-spec> 
   
-  Delete all snapshots.
+  Delete all unprotected snapshots.
   
   Positional arguments
     <image-spec>         image specification
index e471c0710450d6c4638d416283c7316941baca21..70b822130285c475834659434a8bdac4978a7665 100644 (file)
@@ -194,28 +194,42 @@ int do_purge_snaps(librbd::Image& image, bool no_progress)
   } else if (0 == snaps.size()) {
     return 0;
   } else {
-    for (size_t i = 0; i < snaps.size(); ++i) {
-      r = image.snap_is_protected(snaps[i].name.c_str(), &is_protected);
+    list<std::string> protect;
+    for (auto it = snaps.begin(); it != snaps.end();) {
+      r = image.snap_is_protected(it->name.c_str(), &is_protected);
       if (r < 0) {
         pc.fail();
         return r;
       } else if (is_protected == true) {
-        pc.fail();
-        std::cerr << "\r" << "rbd: snapshot '" << snaps[i].name.c_str()
-                  << "' is protected from removal." << std::endl;
-        return -EBUSY;
+        protect.push_back(it->name.c_str());
+        snaps.erase(it);
+      } else {
+        ++it;
       }
     }
+
+    if (!protect.empty()) {
+      std::cout << "rbd: error removing snapshot(s) '" << protect << "', which "
+                << (1 == protect.size() ? "is" : "are")
+                << " protected - these must be unprotected with "
+                << "`rbd snap unprotect`."
+                << std::endl;
+    }
     for (size_t i = 0; i < snaps.size(); ++i) {
       r = image.snap_remove(snaps[i].name.c_str());
       if (r < 0) {
         pc.fail();
         return r;
       }
-      pc.update_progress(i + 1, snaps.size());
+      pc.update_progress(i + 1, snaps.size() + protect.size());
+    }
+
+    if (!protect.empty()) {
+      pc.fail();
+    } else if (snaps.size() > 0) {
+      pc.finish();
     }
 
-    pc.finish();
     return 0;
   }
 }
@@ -832,7 +846,7 @@ Shell::Action action_remove(
   {"snap", "remove"}, {"snap", "rm"}, "Delete a snapshot.", "",
   &get_remove_arguments, &execute_remove);
 Shell::Action action_purge(
-  {"snap", "purge"}, {}, "Delete all snapshots.", "",
+  {"snap", "purge"}, {}, "Delete all unprotected snapshots.", "",
   &get_purge_arguments, &execute_purge);
 Shell::Action action_rollback(
   {"snap", "rollback"}, {"snap", "revert"}, "Rollback image to snapshot.", "",