[Sheepdog] [PATCH 3/5] collie: add vdi snapshot support

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Mon Aug 8 18:44:17 CEST 2011


$ collie vdi snapshot -h
vdi snapshot - create a snapshot

Usage:
  collie vdi snapshot <vdiname> [-s snapshot] [-a address] [-p port] [-h]

Command parameters:
  -s, --snapshot          specify a snapshot id or tag name
  -a, --address           specify the daemon address (default: localhost)
  -p, --port              specify the daemon port
  -h, --help              display this help and exit

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 collie/collie.c |   86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/collie/collie.c b/collie/collie.c
index b89e533..0929a45 100644
--- a/collie/collie.c
+++ b/collie/collie.c
@@ -853,6 +853,54 @@ static int vdi_graph(int argc, char **argv)
 	return EXIT_SUCCESS;
 }
 
+static int find_vdi_name(char *vdiname, uint32_t snapid, const char *tag,
+			 uint32_t *vid, int for_snapshot)
+{
+	int ret, fd;
+	struct sd_vdi_req hdr;
+	struct sd_vdi_rsp *rsp = (struct sd_vdi_rsp *)&hdr;
+	unsigned int wlen, rlen = 0;
+	char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];
+
+	fd = connect_to(sdhost, sdport);
+	if (fd < 0)
+		return -1;
+
+	memset(buf, 0, sizeof(buf));
+	strncpy(buf, vdiname, SD_MAX_VDI_LEN);
+	strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN);
+
+	memset(&hdr, 0, sizeof(hdr));
+	if (for_snapshot)
+		hdr.opcode = SD_OP_GET_VDI_INFO;
+	else
+		hdr.opcode = SD_OP_LOCK_VDI;
+	wlen = SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN;
+	hdr.proto_ver = SD_PROTO_VER;
+	hdr.data_length = wlen;
+	hdr.snapid = snapid;
+	hdr.flags = SD_FLAG_CMD_WRITE;
+
+	ret = exec_req(fd, (struct sd_req *)&hdr, buf, &wlen, &rlen);
+	if (ret) {
+		ret = -1;
+		goto out;
+	}
+
+	if (rsp->result != SD_RES_SUCCESS) {
+		fprintf(stderr, "cannot get vdi info, %s, %s %d %s\n",
+			sd_strerror(rsp->result), vdiname, snapid, tag);
+		ret = -1;
+		goto out;
+	}
+	*vid = rsp->vdi_id;
+
+	ret = 0;
+out:
+	close(fd);
+	return ret;
+}
+
 static int do_vdi_create(char *vdiname, int64_t vdi_size, uint32_t base_vid,
 			 uint32_t *vdi_id, int snapshot)
 {
@@ -971,6 +1019,42 @@ out:
 	return ret;
 }
 
+static int vdi_snapshot(int argc, char **argv)
+{
+	char *vdiname = argv[optind++];
+	uint32_t vid;
+	int ret;
+	char buf[SD_INODE_HEADER_SIZE];
+	struct sheepdog_inode *inode = (struct sheepdog_inode *)buf;
+
+	if (vdi_cmd_data.snapshot_id != 0) {
+		fprintf(stderr, "please specify a non-integer value for "
+			"a snapshot tag name\n");
+		return EXIT_USAGE;
+	}
+
+	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, SD_INODE_HEADER_SIZE, 0);
+	if (ret != SD_RES_SUCCESS) {
+		fprintf(stderr, "failed to read an inode header\n");
+		return EXIT_FAILURE;
+	}
+
+	if (vdi_cmd_data.snapshot_tag[0]) {
+		ret = sd_write_object(vid_to_vdi_oid(vid), vdi_cmd_data.snapshot_tag,
+				      SD_MAX_VDI_TAG_LEN,
+				      offsetof(struct sheepdog_inode, tag),
+				      0, inode->nr_copies, 0);
+	}
+
+	return do_vdi_create(vdiname, inode->vdi_size, vid, NULL, 1);
+}
+
 static int vdi_delete(int argc, char **argv)
 {
 	char *data = argv[optind];
@@ -1260,6 +1344,8 @@ static int vdi_getattr(int argc, char **argv)
 static struct subcommand vdi_cmd[] = {
 	{"create", "<vdiname> <size>", "Paph", "create a image",
 	 SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG, vdi_create},
+	{"snapshot", "<vdiname>", "saph", "create a snapshot",
+	 SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG, vdi_snapshot},
 	{"delete", "<vdiname>", "saph", "delete a image",
 	 SUBCMD_FLAG_NEED_NODELIST|SUBCMD_FLAG_NEED_THIRD_ARG, vdi_delete},
 	{"list", "[vdiname]", "aprh", "list images",
-- 
1.7.2.5




More information about the sheepdog mailing list