From 7deeef91645e225f11ef1accc7f679d72d0ed4dc Mon Sep 17 00:00:00 2001 From: songweibin Date: Thu, 1 Mar 2018 20:28:12 +0800 Subject: [PATCH] rbd: allow remove all unprotected snapshots allow remove all unprotected snapshots when exiting protected snapshots in the same image. Fixes: http://tracker.ceph.com/issues/23126 Signed-off-by: songweibin --- doc/man/8/rbd.rst | 2 +- src/test/cli/rbd/help.t | 4 ++-- src/tools/rbd/action/Snap.cc | 32 +++++++++++++++++++++++--------- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/doc/man/8/rbd.rst b/doc/man/8/rbd.rst index 1f2ba758f0e..fbbbc9aaecd 100644 --- a/doc/man/8/rbd.rst +++ b/doc/man/8/rbd.rst @@ -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. diff --git a/src/test/cli/rbd/help.t b/src/test/cli/rbd/help.t index f87d3347c61..dc0f40e653d 100644 --- a/src/test/cli/rbd/help.t +++ b/src/test/cli/rbd/help.t @@ -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. @@ -1480,7 +1480,7 @@ [--image-id ] [--no-progress] - Delete all snapshots. + Delete all unprotected snapshots. Positional arguments image specification diff --git a/src/tools/rbd/action/Snap.cc b/src/tools/rbd/action/Snap.cc index e471c071045..70b82213028 100644 --- a/src/tools/rbd/action/Snap.cc +++ b/src/tools/rbd/action/Snap.cc @@ -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 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.", "", -- 2.39.5