[sheepdog] [PATCH v2 1/2] collie: add vdi rollback support

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Sat Sep 1 14:18:30 CEST 2012


This adds a new command 'vdi rollback' to rollback to the requested
snapshot.

Here is an example:

  $ collie vdi create test 4G
  $ echo snap1 | collie vdi write test 0 512
  $ collie vdi snapshot test -s snap1
  $ echo snap2 | collie vdi write test 0 512
  $ collie vdi snapshot test -s snap2
  $ collie vdi read test 0 512
  snap2
  $ collie vdi rollback test -s snap1
  $ collie vdi read test 0 512
  snap1
  $ collie vdi rollback test -s snap2
  $ collie vdi read test 0 512
  snap2
  $ collie vdi list
    Name        Id    Size    Used  Shared    Creation time   VDI id  Copies  Tag
  s test         1  4.0 GB  4.0 MB  0.0 MB 2012-09-01 09:29   7c2b25     1         snap1
  s test         2  4.0 GB  4.0 MB  0.0 MB 2012-09-01 09:30   7c2b26     1         snap2
    test         3  4.0 GB  0.0 MB  4.0 MB 2012-09-01 09:30   7c2b29     1

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 collie/vdi.c |   67 +++++++++++++++++++++++++++++++++++++++++++++++++--------
 man/collie.8 |    3 ++
 2 files changed, 60 insertions(+), 10 deletions(-)

diff --git a/collie/vdi.c b/collie/vdi.c
index 966fb9f..e84bb76 100644
--- a/collie/vdi.c
+++ b/collie/vdi.c
@@ -707,32 +707,31 @@ static int vdi_resize(int argc, char **argv)
 	return EXIT_SUCCESS;
 }
 
-static int vdi_delete(int argc, char **argv)
+static int do_vdi_delete(const char *vdiname, int snap_id, const char *snap_tag)
 {
-	char *data = argv[optind];
 	int fd, ret;
 	struct sd_req hdr;
 	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
 	unsigned rlen, wlen;
-	char vdiname[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];
+	char data[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];
 
 	fd = connect_to(sdhost, sdport);
 	if (fd < 0)
 		return EXIT_SYSFAIL;
 
 	rlen = 0;
-	wlen = sizeof(vdiname);
+	wlen = sizeof(data);
 
 	sd_init_req(&hdr, SD_OP_DEL_VDI);
 	hdr.flags = SD_FLAG_CMD_WRITE;
 	hdr.data_length = wlen;
-	hdr.vdi.snapid = vdi_cmd_data.snapshot_id;
-	memset(vdiname, 0, sizeof(vdiname));
-	strncpy(vdiname, data, SD_MAX_VDI_LEN);
-	strncpy(vdiname + SD_MAX_VDI_LEN, vdi_cmd_data.snapshot_tag,
-		SD_MAX_VDI_TAG_LEN);
+	hdr.vdi.snapid = snap_id;
+	memset(data, 0, sizeof(data));
+	strncpy(data, vdiname, SD_MAX_VDI_LEN);
+	if (snap_tag)
+		strncpy(data + SD_MAX_VDI_LEN, snap_tag, SD_MAX_VDI_TAG_LEN);
 
-	ret = exec_req(fd, &hdr, vdiname, &wlen, &rlen);
+	ret = exec_req(fd, &hdr, data, &wlen, &rlen);
 	close(fd);
 
 	if (ret) {
@@ -752,6 +751,51 @@ static int vdi_delete(int argc, char **argv)
 	return EXIT_SUCCESS;
 }
 
+static int vdi_delete(int argc, char **argv)
+{
+	char *vdiname = argv[optind];
+
+	return do_vdi_delete(vdiname, vdi_cmd_data.snapshot_id,
+			     vdi_cmd_data.snapshot_tag);
+}
+
+static int vdi_rollback(int argc, char **argv)
+{
+	char *vdiname = argv[optind++];
+	uint32_t base_vid;
+	int ret;
+	char buf[SD_INODE_HEADER_SIZE];
+	struct sheepdog_inode *inode = (struct sheepdog_inode *)buf;
+
+	if (!vdi_cmd_data.snapshot_id && !vdi_cmd_data.snapshot_tag[0]) {
+		fprintf(stderr, "Please specify the '-s' option\n");
+		return EXIT_USAGE;
+	}
+
+	ret = find_vdi_name(vdiname, vdi_cmd_data.snapshot_id,
+			    vdi_cmd_data.snapshot_tag, &base_vid, 0);
+	if (ret < 0) {
+		fprintf(stderr, "Failed to open VDI %s\n", vdiname);
+		return EXIT_FAILURE;
+	}
+
+	ret = sd_read_object(vid_to_vdi_oid(base_vid), inode,
+			     SD_INODE_HEADER_SIZE, 0);
+	if (ret != SD_RES_SUCCESS) {
+		fprintf(stderr, "Failed to read an inode\n");
+		return EXIT_FAILURE;
+	}
+
+	ret = do_vdi_delete(vdiname, 0, NULL);
+	if (ret != SD_RES_SUCCESS) {
+		fprintf(stderr, "Failed to delete the current state\n");
+		return EXIT_FAILURE;
+	}
+
+	return do_vdi_create(vdiname, inode->vdi_size, base_vid, NULL,
+			     inode->snap_id, vdi_cmd_data.nr_copies);
+}
+
 static int vdi_object(int argc, char **argv)
 {
 	char *vdiname = argv[optind];
@@ -1537,6 +1581,9 @@ static struct subcommand vdi_cmd[] = {
 	{"delete", "<vdiname>", "saph", "delete an image",
 	 NULL, SUBCMD_FLAG_NEED_THIRD_ARG,
 	 vdi_delete, vdi_options},
+	{"rollback", "<vdiname>", "saph", "rollback to a snapshot",
+	 NULL, SUBCMD_FLAG_NEED_THIRD_ARG,
+	 vdi_rollback, vdi_options},
 	{"list", "[vdiname]", "aprh", "list images",
 	 NULL, 0, vdi_list, vdi_options},
 	{"tree", NULL, "aph", "show images in tree view format",
diff --git a/man/collie.8 b/man/collie.8
index eb16795..9061bc8 100644
--- a/man/collie.8
+++ b/man/collie.8
@@ -76,6 +76,9 @@ This command clones an image.
 .BI "vdi delete [-s snapshot] [-a address] [-p port] [-h] <vdiname>"
 This command deletes an image.
 .TP
+.BI "vdi rollback [-s snapshot] [-a address] [-p port] [-h] <vdiname>"
+This command rollbacks the current vdi to the requested snapshot.
+.TP
 .BI "vdi list [-a address] [-p port] [-r] [-h] [vdiname]"
 This command lists images.
 .TP
-- 
1.7.2.5




More information about the sheepdog mailing list