[sheepdog] [PATCH] collie: add command 'collie vdi reset' to reset a cloned VDI

levin li levin108 at gmail.com
Wed Aug 29 07:57:57 CEST 2012


From: levin li <xingke.lwp at taobao.com>

With this command, we can reset a cloned VDI to its initial state as
it's just cloned from a snapshot, the usage is simple:

$ collie vdi reset cloned_vdi_name

Signed-off-by: levin li <xingke.lwp at taobao.com>
---
 collie/collie.h |    1 +
 collie/common.c |   35 ++++++++++++++++++++++++++++++
 collie/vdi.c    |   63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/collie/collie.h b/collie/collie.h
index 7f93ded..5ef2534 100644
--- a/collie/collie.h
+++ b/collie/collie.h
@@ -74,6 +74,7 @@ int sd_read_object(uint64_t oid, void *data, unsigned int datalen,
 		   uint64_t offset);
 int sd_write_object(uint64_t oid, uint64_t cow_oid, void *data, unsigned int datalen,
 		    uint64_t offset, uint32_t flags, int copies, int create);
+int sd_remove_object(uint64_t oid, int copies);
 int send_light_req(struct sd_req *hdr, const char *host, int port);
 int send_light_req_get_response(struct sd_req *hdr, const char *host, int port);
 
diff --git a/collie/common.c b/collie/common.c
index ce8dcf7..c66c3ff 100644
--- a/collie/common.c
+++ b/collie/common.c
@@ -124,6 +124,41 @@ int sd_write_object(uint64_t oid, uint64_t cow_oid, void *data, unsigned int dat
 	return SD_RES_SUCCESS;
 }
 
+int sd_remove_object(uint64_t oid, int copies)
+{
+	struct sd_req hdr;
+	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
+	int fd, ret;
+	unsigned wlen = 0, rlen = 0;
+
+	fd = connect_to(sdhost, sdport);
+	if (fd < 0) {
+		fprintf(stderr, "Failed to connect\n");
+		return SD_RES_EIO;
+	}
+
+	sd_init_req(&hdr, SD_OP_REMOVE_OBJ);
+	hdr.epoch = sd_epoch;
+	hdr.data_length = wlen;
+	hdr.obj.copies = copies;
+	hdr.obj.oid = oid;
+
+	ret = exec_req(fd, &hdr, NULL, &wlen, &rlen);
+	close(fd);
+
+	if (ret) {
+		fprintf(stderr, "Failed to remove object %" PRIx64 "\n", oid);
+		return SD_RES_EIO;
+	}
+	if (rsp->result != SD_RES_SUCCESS) {
+		fprintf(stderr, "Failed to remove object %" PRIx64 ": %s\n", oid,
+				sd_strerror(rsp->result));
+		return rsp->result;
+	}
+
+	return SD_RES_SUCCESS;
+}
+
 int parse_vdi(vdi_parser_func_t func, size_t size, void *data)
 {
 	int ret, fd, count;
diff --git a/collie/vdi.c b/collie/vdi.c
index 7e2f5b0..4ac69db 100644
--- a/collie/vdi.c
+++ b/collie/vdi.c
@@ -753,6 +753,66 @@ static int vdi_delete(int argc, char **argv)
 	return EXIT_SUCCESS;
 }
 
+static int vdi_reset(int argc, char **argv)
+{
+	char *vdiname = argv[optind++];
+	int ret, i;
+	struct sheepdog_inode inode, pinode;
+	uint32_t vid, pvid;
+
+	ret = find_vdi_name(vdiname, 0, "", &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(vid), &inode, sizeof(inode), 0);
+	if (ret != SD_RES_SUCCESS) {
+		fprintf(stderr, "Failed to read VDI %" PRIx32 "\n", vid);
+		return EXIT_FAILURE;
+	}
+
+	/* check whether it's a cloned VDI */
+	if (inode.snap_id != 1 || inode.parent_vdi_id == 0) {
+		fprintf(stderr, "Can not reset a non-cloned VDI\n");
+		return EXIT_FAILURE;
+	}
+
+	pvid = inode.parent_vdi_id;
+	ret = sd_read_object(vid_to_vdi_oid(pvid), &pinode, sizeof(pinode), 0);
+	if (ret != SD_RES_SUCCESS) {
+		fprintf(stderr, "Can not read parent VDI %" PRIx32 "\n", pvid);
+		return EXIT_FAILURE;
+	}
+
+	for (i = 0; i < MAX_DATA_OBJS; i++) {
+		uint64_t oid;
+
+		if (!inode.data_vdi_id[i])
+			continue;
+
+		if (!is_data_obj_writeable(&inode, i))
+			continue;
+
+		oid = vid_to_data_oid(inode.data_vdi_id[i], i);
+		ret = sd_remove_object(oid, inode.nr_copies);
+		if (ret != SD_RES_SUCCESS)
+			fprintf(stderr, "Failed to remove object %" PRIx64
+				"\n", oid);
+	}
+
+	memcpy(inode.data_vdi_id, pinode.data_vdi_id,
+	       sizeof(inode.data_vdi_id));
+
+	ret = sd_write_object(vid_to_vdi_oid(vid), 0, &inode, sizeof(inode),
+			      0, 0, inode.nr_copies, 0);
+	if (ret != SD_RES_SUCCESS)
+		fprintf(stderr, "Failed to write object %" PRIx64 "\n",
+			vid_to_vdi_oid(vid));
+
+	return SD_RES_SUCCESS;
+}
+
 static int vdi_object(int argc, char **argv)
 {
 	char *vdiname = argv[optind];
@@ -1538,6 +1598,9 @@ static struct subcommand vdi_cmd[] = {
 	{"delete", "<vdiname>", "saph", "delete an image",
 	 NULL, SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG,
 	 vdi_delete, vdi_options},
+	{"reset", "<vdiname>", "aph", "reset an cloned image",
+	 NULL, SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG,
+	 vdi_reset, vdi_options},
 	{"list", "[vdiname]", "aprh", "list images",
 	 NULL, SUBCMD_FLAG_NEED_NODELIST, vdi_list, vdi_options},
 	{"tree", NULL, "aph", "show images in tree view format",
-- 
1.7.1




More information about the sheepdog mailing list