[Sheepdog] [PATCH 3/5] add bdrv_snapshot_list support

FUJITA Tomonori fujita.tomonori at lab.ntt.co.jp
Tue Jan 26 05:32:08 CET 2010


This supports `qemu-img snapshot -l`.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
---
 block/sheepdog.c |  123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 123 insertions(+), 0 deletions(-)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 1ef970e..a564738 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -90,6 +90,8 @@
 
 #define CURRENT_VDI_ID 0
 
+#define SD_MAX_VDI_LEN 256
+
 #undef eprintf
 #define eprintf(fmt, args...)						\
 do {									\
@@ -1738,6 +1740,126 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
 	return ret;
 }
 
+struct sd_so_req {
+	uint8_t		proto_ver;
+	uint8_t		opcode;
+	uint16_t	flags;
+	uint32_t	epoch;
+	uint32_t        id;
+	uint32_t        data_length;
+	uint64_t	oid;
+	uint64_t	ctime;
+	uint32_t	copies;
+	uint32_t	tag;
+	uint32_t	opcode_specific[2];
+};
+
+struct sd_so_rsp {
+	uint8_t		proto_ver;
+	uint8_t		opcode;
+	uint16_t	flags;
+	uint32_t	epoch;
+	uint32_t        id;
+	uint32_t        data_length;
+	uint32_t        result;
+	uint32_t	copies;
+	uint64_t	ctime;
+	uint64_t	oid;
+	uint32_t	opcode_specific[2];
+};
+
+struct sheepdog_vdi_info {
+	uint64_t oid;
+	uint16_t id;
+	uint16_t name_len;
+	uint16_t tag_len;
+	uint8_t type;
+	uint8_t flags;
+	uint32_t epoch;
+	char name[SD_MAX_VDI_LEN];
+	char tag[SD_MAX_VDI_LEN];
+};
+
+#define SD_OP_SO_READ_VDIS   0x64
+
+static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
+{
+	struct bdrv_sd_state *s = bs->opaque;
+	struct sd_so_req req;
+	struct sd_rsp *rsp;
+	struct sheepdog_vdi_info *vi;
+	int i, fd, nr = 0, ret, max = 1024; /* FIXME */
+	char name[SD_MAX_VDI_LEN];
+	QEMUSnapshotInfo *sn_tab = NULL;
+	unsigned wlen, rlen;
+	char hostname[] = "localhost";
+	int found = 0;
+	struct sd_inode inode;
+
+	vi = malloc(max * sizeof(*vi));
+	if (!vi)
+		return 0;
+
+	memset(name, 0, sizeof(name));
+	snprintf(name, sizeof(name), "%s", s->name);
+
+	fd = connect_to_vost(hostname, DOG_PORT);
+	if (fd < 0)
+		goto out;
+
+	wlen = 0;
+	rlen = max * sizeof(*vi);
+
+	memset(&req, 0, sizeof(req));
+
+	req.opcode = SD_OP_SO_READ_VDIS;
+	req.data_length = rlen;
+	req.epoch = s_epoch;
+
+	ret = do_req(fd, (struct sd_req *)&req, vi, &wlen, &rlen);
+
+	close(fd);
+	if (ret)
+		goto out;
+
+	rsp = (struct sd_rsp *)&req;
+	if (rsp->result != SD_RES_SUCCESS)
+		goto out;
+
+	nr = rsp->data_length / sizeof(*vi);
+	sn_tab = malloc(nr * sizeof(*sn_tab));
+	if (!sn_tab)
+		goto out;
+
+	memset(sn_tab, 0, nr * sizeof(*sn_tab));
+
+	for (i = 0; i < nr; i++) {
+		int copies;
+
+		if (strcmp(vi[i].name, s->name) || !vi[i].id)
+			continue;
+
+		ret = read_vdi_obj((char *)&inode, vi[i].oid, node_list_entries,
+				   nr_nodes, &copies);
+		if (ret)
+			continue;
+
+		sn_tab[found].date_sec = inode.ctime >> 32;
+		sn_tab[found].date_nsec = inode.ctime & 0xffffffff;
+
+		snprintf(sn_tab[found].id_str, sizeof(sn_tab[found].id_str), "%u",
+			vi[i].id);
+		found++;
+	}
+out:
+	*psn_tab = sn_tab;
+
+	free(vi);
+
+	return found;
+}
+
+
 static QEMUOptionParameter sd_create_options[] = {
 	{
 		.name = BLOCK_OPT_SIZE,
@@ -1766,6 +1888,7 @@ BlockDriver bdrv_sheepdog = {
 	.bdrv_aio_writev = sd_aio_writev,
 
 	.bdrv_snapshot_create = sd_snapshot_create,
+	.bdrv_snapshot_list = sd_snapshot_list,
 	.create_options = sd_create_options,
 };
 
-- 
1.5.6.5




More information about the sheepdog mailing list