summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Durgin <josh.durgin@dreamhost.com>2012-01-04 17:07:07 -0800
committerJosh Durgin <josh.durgin@dreamhost.com>2012-01-05 10:19:17 -0800
commitb6c43d2affe210115cea65fcdc4609815159bf39 (patch)
treeecaa2074dc73a09eb2aa052fd7abf90a21707641
parentbd2339102f0c650d87203fdc2336f9533a18b755 (diff)
downloadceph-b6c43d2affe210115cea65fcdc4609815159bf39.tar.gz
rbd: add a command to delete all snapshots of an image
This makes deleting images with many snapshots easier. Signed-off-by: Josh Durgin <josh.durgin@dreamhost.com>
-rw-r--r--doc/man/8/rbd.rst6
-rw-r--r--man/rbd.86
-rwxr-xr-xqa/workunits/rbd/copy.sh1
-rwxr-xr-xqa/workunits/rbd/kernel.sh1
-rw-r--r--src/rbd.cc48
-rw-r--r--src/test/cli/rbd/help.t1
-rw-r--r--src/test/cli/rbd/invalid-snap-usage.t9
7 files changed, 67 insertions, 5 deletions
diff --git a/doc/man/8/rbd.rst b/doc/man/8/rbd.rst
index 12a124401ed..fbf8e3cf638 100644
--- a/doc/man/8/rbd.rst
+++ b/doc/man/8/rbd.rst
@@ -81,7 +81,8 @@ Commands
Resizes rbd image. The size parameter also needs to be specified.
:command:`rm` [*image-name*]
- Deletes rbd image (including all data blocks)
+ Deletes an rbd image (including all data blocks). If the image has
+ snapshots, this fails and nothing is deleted.
:command:`export` [*image-name*] [*dest-path*]
Exports image to dest path.
@@ -108,6 +109,9 @@ Commands
:command:`snap` rm [*image-name*]
Removes the specified snapshot.
+:command:`snap` purge [*image-name*]
+ Removes all snapshots from an image.
+
:command:`map` [*image-name*]
Maps the specified image to a block device via the rbd kernel module.
diff --git a/man/rbd.8 b/man/rbd.8
index 16da65aea1f..0278137d857 100644
--- a/man/rbd.8
+++ b/man/rbd.8
@@ -103,7 +103,8 @@ Will create a new rbd image. You must also specify the size via \-\-size.
Resizes rbd image. The size parameter also needs to be specified.
.TP
.B \fBrm\fP [\fIimage\-name\fP]
-Deletes rbd image (including all data blocks)
+Deletes an rbd image (including all data blocks). If the image has
+snapshots, this fails and nothing is deleted.
.TP
.B \fBexport\fP [\fIimage\-name\fP] [\fIdest\-path\fP]
Exports image to dest path.
@@ -130,6 +131,9 @@ array and update the data head content to the snapshotted version.
.B \fBsnap\fP rm [\fIimage\-name\fP]
Removes the specified snapshot.
.TP
+.B \fBsnap\fP purge [\fIimage\-name\fP]
+Removes all snapshots from an image.
+.TP
.B \fBmap\fP [\fIimage\-name\fP]
Maps the specified image to a block device via the rbd kernel module.
.TP
diff --git a/qa/workunits/rbd/copy.sh b/qa/workunits/rbd/copy.sh
index 3c6bb029abd..5d922920ad9 100755
--- a/qa/workunits/rbd/copy.sh
+++ b/qa/workunits/rbd/copy.sh
@@ -2,6 +2,7 @@
TMP_FILES="/tmp/img1 /tmp/img1.new /tmp/img2 /tmp/img2.new /tmp/img3 /tmp/img3.new /tmp/img1.snap1"
+rbd snap purge testimg1 || true
rbd rm testimg1 || true
rbd rm testimg2 || true
rbd rm testimg3 || true
diff --git a/qa/workunits/rbd/kernel.sh b/qa/workunits/rbd/kernel.sh
index c0eced27193..bf8452aa578 100755
--- a/qa/workunits/rbd/kernel.sh
+++ b/qa/workunits/rbd/kernel.sh
@@ -20,6 +20,7 @@ function clean_up {
rbd unmap /dev/rbd/rbd/testimg1 || true
rbd unmap /dev/rbd/rbd/testimg1@snap1 || true
sudo chown root /sys/bus/rbd/add /sys/bus/rbd/remove
+ rbd snap purge testimg1 || true
rbd rm testimg1 || true
sudo rm -f $TMP_FILES
}
diff --git a/src/rbd.cc b/src/rbd.cc
index 216d0f9f2c7..3f86de6357f 100644
--- a/src/rbd.cc
+++ b/src/rbd.cc
@@ -78,6 +78,7 @@ void usage()
<< " snap create <--snap=name> [image-name] create a snapshot\n"
<< " snap rollback <--snap=name> [image-name] rollback image head to snapshot\n"
<< " snap rm <--snap=name> [image-name] deletes a snapshot\n"
+ << " snap purge [image-name] deletes all snapshots\n"
<< " watch [image-name] watch events on image\n"
<< " map [image-name] map the image to a block device\n"
<< " using the kernel\n"
@@ -259,6 +260,25 @@ static int do_rollback_snap(librbd::Image& image, const char *snapname)
return 0;
}
+static int do_purge_snaps(librbd::Image& image)
+{
+ MyProgressContext pc("Removing all snapshots");
+ std::vector<librbd::snap_info_t> snaps;
+ int r = image.snap_list(snaps);
+ if (r < 0) {
+ pc.fail();
+ return r;
+ }
+
+ for (size_t i = 0; i < snaps.size(); ++i) {
+ image.snap_remove(snaps[i].name.c_str());
+ pc.update_progress(i + 1, snaps.size());
+ }
+
+ pc.finish();
+ return 0;
+}
+
struct ExportContext {
int fd;
MyProgressContext pc;
@@ -815,6 +835,7 @@ enum {
OPT_SNAP_ROLLBACK,
OPT_SNAP_REMOVE,
OPT_SNAP_LIST,
+ OPT_SNAP_PURGE,
OPT_WATCH,
OPT_MAP,
OPT_UNMAP,
@@ -866,6 +887,8 @@ static int get_cmd(const char *cmd, bool snapcmd)
if (strcmp(cmd, "ls") == 0||
strcmp(cmd, "list") == 0)
return OPT_SNAP_LIST;
+ if (strcmp(cmd, "purge") == 0)
+ return OPT_SNAP_PURGE;
}
return OPT_NO_CMD;
@@ -979,6 +1002,7 @@ int main(int argc, const char **argv)
case OPT_SNAP_ROLLBACK:
case OPT_SNAP_REMOVE:
case OPT_SNAP_LIST:
+ case OPT_SNAP_PURGE:
case OPT_WATCH:
case OPT_MAP:
set_conf_param(v, &imgname, NULL);
@@ -1083,8 +1107,8 @@ int main(int argc, const char **argv)
if (imgname && talk_to_cluster &&
(opt_cmd == OPT_RESIZE || opt_cmd == OPT_INFO || opt_cmd == OPT_SNAP_LIST ||
opt_cmd == OPT_SNAP_CREATE || opt_cmd == OPT_SNAP_ROLLBACK ||
- opt_cmd == OPT_SNAP_REMOVE || opt_cmd == OPT_EXPORT || opt_cmd == OPT_WATCH ||
- opt_cmd == OPT_COPY)) {
+ opt_cmd == OPT_SNAP_REMOVE || opt_cmd == OPT_SNAP_PURGE ||
+ opt_cmd == OPT_EXPORT || opt_cmd == OPT_WATCH || opt_cmd == OPT_COPY)) {
r = rbd.open(io_ctx, image, imgname);
if (r < 0) {
cerr << "error opening image " << imgname << ": " << cpp_strerror(-r) << std::endl;
@@ -1161,7 +1185,13 @@ int main(int argc, const char **argv)
case OPT_RM:
r = do_delete(rbd, io_ctx, imgname);
if (r < 0) {
- cerr << "delete error: " << cpp_strerror(-r) << std::endl;
+ if (r == -EBUSY) {
+ cerr << "delete error: image has snapshots - these must be deleted"
+ << " with 'rbd snap purge' before the image can be removed."
+ << std::endl;
+ } else {
+ cerr << "delete error: " << cpp_strerror(-r) << std::endl;
+ }
exit(1);
}
break;
@@ -1222,6 +1252,18 @@ int main(int argc, const char **argv)
}
break;
+ case OPT_SNAP_PURGE:
+ if (!imgname) {
+ usage();
+ exit(1);
+ }
+ r = do_purge_snaps(image);
+ if (r < 0) {
+ cerr << "removing snaps failed: " << cpp_strerror(-r) << std::endl;
+ exit(1);
+ }
+ break;
+
case OPT_EXPORT:
if (!path) {
cerr << "pathname should be specified" << std::endl;
diff --git a/src/test/cli/rbd/help.t b/src/test/cli/rbd/help.t
index e9aafff4e23..3c804457b97 100644
--- a/src/test/cli/rbd/help.t
+++ b/src/test/cli/rbd/help.t
@@ -16,6 +16,7 @@
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
+ snap purge [image-name] deletes all snapshots
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
diff --git a/src/test/cli/rbd/invalid-snap-usage.t b/src/test/cli/rbd/invalid-snap-usage.t
index 44037e4b13c..771e4c2fd2b 100644
--- a/src/test/cli/rbd/invalid-snap-usage.t
+++ b/src/test/cli/rbd/invalid-snap-usage.t
@@ -17,6 +17,7 @@
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
+ snap purge [image-name] deletes all snapshots
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
@@ -59,6 +60,7 @@
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
+ snap purge [image-name] deletes all snapshots
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
@@ -101,6 +103,7 @@
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
+ snap purge [image-name] deletes all snapshots
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
@@ -143,6 +146,7 @@
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
+ snap purge [image-name] deletes all snapshots
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
@@ -185,6 +189,7 @@
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
+ snap purge [image-name] deletes all snapshots
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
@@ -227,6 +232,7 @@
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
+ snap purge [image-name] deletes all snapshots
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
@@ -269,6 +275,7 @@
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
+ snap purge [image-name] deletes all snapshots
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
@@ -311,6 +318,7 @@
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
+ snap purge [image-name] deletes all snapshots
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel
@@ -353,6 +361,7 @@
snap create <--snap=name> [image-name] create a snapshot
snap rollback <--snap=name> [image-name] rollback image head to snapshot
snap rm <--snap=name> [image-name] deletes a snapshot
+ snap purge [image-name] deletes all snapshots
watch [image-name] watch events on image
map [image-name] map the image to a block device
using the kernel