This supports `qemu-img snapshot -l`.

Signed-off-by: FUJITA Tomonori <[email protected]>
---
 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

-- 
sheepdog mailing list
[email protected]
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to