[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