static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)

{

    BDRVSheepdogState *s = bs->opaque;

    SheepdogReq req;

    int fd, nr = 1024, ret, max = BITS_TO_LONGS(SD_NR_VDIS) * sizeof(long);

    QEMUSnapshotInfo *sn_tab = NULL;

    unsigned wlen, rlen;

    int found = 0;

    static SheepdogInode inode;

    unsigned long *vdi_inuse;

    unsigned int start_nr;

    uint64_t hval;

    uint32_t vid;



    vdi_inuse = g_malloc(max);



    fd = connect_to_sdog(s->addr, s->port);

    if (fd < 0) {

        ret = fd;

        goto out;

    }



    rlen = max;

    wlen = 0;



    memset(&req, 0, sizeof(req));



    req.opcode = SD_OP_READ_VDIS;

    req.data_length = max;



    ret = do_req(fd, (SheepdogReq *)&req, vdi_inuse, &wlen, &rlen);



    closesocket(fd);

    if (ret) {

        goto out;

    }



    sn_tab = g_malloc0(nr * sizeof(*sn_tab));



    /* calculate a vdi id with hash function */

    hval = fnv_64a_buf(s->name, strlen(s->name), FNV1A_64_INIT);

    start_nr = hval & (SD_NR_VDIS - 1);



    fd = connect_to_sdog(s->addr, s->port);

    if (fd < 0) {

        error_report("failed to connect");

        ret = fd;

        goto out;

    }



    for (vid = start_nr; found < nr; vid = (vid + 1) % SD_NR_VDIS) {

        if (!test_bit(vid, vdi_inuse)) {

            break;

        }



        /* we don't need to read entire object */

        ret = read_object(fd, (char *)&inode, vid_to_vdi_oid(vid),

                          0, SD_INODE_SIZE - sizeof(inode.data_vdi_id), 0,

                          s->cache_enabled);



        if (ret) {

            continue;

        }



        if (!strcmp(inode.name, s->name) && is_snapshot(&inode)) {

            sn_tab[found].date_sec = inode.snap_ctime >> 32;

            sn_tab[found].date_nsec = inode.snap_ctime & 0xffffffff;

            sn_tab[found].vm_state_size = inode.vm_state_size;

            sn_tab[found].vm_clock_nsec = inode.vm_clock_nsec;



            snprintf(sn_tab[found].id_str, sizeof(sn_tab[found].id_str), "%u",

                     inode.snap_id);

            pstrcpy(sn_tab[found].name,

                    MIN(sizeof(sn_tab[found].name), sizeof(inode.tag)),

                    inode.tag);

            found++;

        }

    }



    closesocket(fd);

out:

    *psn_tab = sn_tab;



    g_free(vdi_inuse);



    if (ret < 0) {

        return ret;

    }



    return found;

}

static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)

{

    BDRVSheepdogState *s = bs->opaque;

    SheepdogReq req;

    int fd, nr = 1024, ret, max = BITS_TO_LONGS(SD_NR_VDIS) * sizeof(long);

    QEMUSnapshotInfo *sn_tab = NULL;

    unsigned wlen, rlen;

    int found = 0;

    static SheepdogInode inode;

    unsigned long *vdi_inuse;

    unsigned int start_nr;

    uint64_t hval;

    uint32_t vid;



    vdi_inuse = g_malloc(max);



    fd = connect_to_sdog(s->addr, s->port);

    if (fd < 0) {

        ret = fd;

        goto out;

    }



    rlen = max;

    wlen = 0;



    memset(&req, 0, sizeof(req));



    req.opcode = SD_OP_READ_VDIS;

    req.data_length = max;



    ret = do_req(fd, (SheepdogReq *)&req, vdi_inuse, &wlen, &rlen);



    closesocket(fd);

    if (ret) {

        goto out;

    }



    sn_tab = g_malloc0(nr * sizeof(*sn_tab));



    

    hval = fnv_64a_buf(s->name, strlen(s->name), FNV1A_64_INIT);

    start_nr = hval & (SD_NR_VDIS - 1);



    fd = connect_to_sdog(s->addr, s->port);

    if (fd < 0) {

        error_report("failed to connect");

        ret = fd;

        goto out;

    }



    for (vid = start_nr; found < nr; vid = (vid + 1) % SD_NR_VDIS) {

        if (!test_bit(vid, vdi_inuse)) {

            break;

        }



        

        ret = read_object(fd, (char *)&inode, vid_to_vdi_oid(vid),

                          0, SD_INODE_SIZE - sizeof(inode.data_vdi_id), 0,

                          s->cache_enabled);



        if (ret) {

            continue;

        }



        if (!strcmp(inode.name, s->name) && is_snapshot(&inode)) {

            sn_tab[found].date_sec = inode.snap_ctime >> 32;

            sn_tab[found].date_nsec = inode.snap_ctime & 0xffffffff;

            sn_tab[found].vm_state_size = inode.vm_state_size;

            sn_tab[found].vm_clock_nsec = inode.vm_clock_nsec;



            snprintf(sn_tab[found].id_str, sizeof(sn_tab[found].id_str), "%u",

                     inode.snap_id);

            pstrcpy(sn_tab[found].name,

                    MIN(sizeof(sn_tab[found].name), sizeof(inode.tag)),

                    inode.tag);

            found++;

        }

    }



    closesocket(fd);

out:

    *psn_tab = sn_tab;



    g_free(vdi_inuse);



    if (ret < 0) {

        return ret;

    }



    return found;

}

static int FUNC_0(BlockDriverState *VAR_0, QEMUSnapshotInfo **VAR_1)

{

    BDRVSheepdogState *s = VAR_0->opaque;

    SheepdogReq req;

    int VAR_2, VAR_3 = 1024, VAR_4, VAR_5 = BITS_TO_LONGS(SD_NR_VDIS) * sizeof(long);

    QEMUSnapshotInfo *sn_tab = NULL;

    unsigned VAR_6, VAR_7;

    int VAR_8 = 0;

    static SheepdogInode VAR_9;

    unsigned long *VAR_10;

    unsigned int VAR_11;

    uint64_t hval;

    uint32_t vid;



    VAR_10 = g_malloc(VAR_5);



    VAR_2 = connect_to_sdog(s->addr, s->port);

    if (VAR_2 < 0) {

        VAR_4 = VAR_2;

        goto out;

    }



    VAR_7 = VAR_5;

    VAR_6 = 0;



    memset(&req, 0, sizeof(req));



    req.opcode = SD_OP_READ_VDIS;

    req.data_length = VAR_5;



    VAR_4 = do_req(VAR_2, (SheepdogReq *)&req, VAR_10, &VAR_6, &VAR_7);



    closesocket(VAR_2);

    if (VAR_4) {

        goto out;

    }



    sn_tab = g_malloc0(VAR_3 * sizeof(*sn_tab));



    

    hval = fnv_64a_buf(s->name, strlen(s->name), FNV1A_64_INIT);

    VAR_11 = hval & (SD_NR_VDIS - 1);



    VAR_2 = connect_to_sdog(s->addr, s->port);

    if (VAR_2 < 0) {

        error_report("failed to connect");

        VAR_4 = VAR_2;

        goto out;

    }



    for (vid = VAR_11; VAR_8 < VAR_3; vid = (vid + 1) % SD_NR_VDIS) {

        if (!test_bit(vid, VAR_10)) {

            break;

        }



        

        VAR_4 = read_object(VAR_2, (char *)&VAR_9, vid_to_vdi_oid(vid),

                          0, SD_INODE_SIZE - sizeof(VAR_9.data_vdi_id), 0,

                          s->cache_enabled);



        if (VAR_4) {

            continue;

        }



        if (!strcmp(VAR_9.name, s->name) && is_snapshot(&VAR_9)) {

            sn_tab[VAR_8].date_sec = VAR_9.snap_ctime >> 32;

            sn_tab[VAR_8].date_nsec = VAR_9.snap_ctime & 0xffffffff;

            sn_tab[VAR_8].vm_state_size = VAR_9.vm_state_size;

            sn_tab[VAR_8].vm_clock_nsec = VAR_9.vm_clock_nsec;



            snprintf(sn_tab[VAR_8].id_str, sizeof(sn_tab[VAR_8].id_str), "%u",

                     VAR_9.snap_id);

            pstrcpy(sn_tab[VAR_8].name,

                    MIN(sizeof(sn_tab[VAR_8].name), sizeof(VAR_9.tag)),

                    VAR_9.tag);

            VAR_8++;

        }

    }



    closesocket(VAR_2);

out:

    *VAR_1 = sn_tab;



    g_free(VAR_10);



    if (VAR_4 < 0) {

        return VAR_4;

    }



    return VAR_8;

}

static int FUNC_0(BlockDriverState *VAR_0, QEMUSnapshotInfo **VAR_1)
{ BDRVSheepdogState *s = VAR_0->opaque; SheepdogReq req; int VAR_2, VAR_3 = 1024, VAR_4, VAR_5 = BITS_TO_LONGS(SD_NR_VDIS) * sizeof(long); QEMUSnapshotInfo *sn_tab = NULL; unsigned VAR_6, VAR_7; int VAR_8 = 0; static SheepdogInode VAR_9; unsigned long *VAR_10; unsigned int VAR_11; uint64_t hval; uint32_t vid; VAR_10 = g_malloc(VAR_5); VAR_2 = connect_to_sdog(s->addr, s->port); if (VAR_2 < 0) { VAR_4 = VAR_2; goto out; } VAR_7 = VAR_5; VAR_6 = 0; memset(&req, 0, sizeof(req)); req.opcode = SD_OP_READ_VDIS; req.data_length = VAR_5; VAR_4 = do_req(VAR_2, (SheepdogReq *)&req, VAR_10, &VAR_6, &VAR_7); closesocket(VAR_2); if (VAR_4) { goto out; } sn_tab = g_malloc0(VAR_3 * sizeof(*sn_tab)); hval = fnv_64a_buf(s->name, strlen(s->name), FNV1A_64_INIT); VAR_11 = hval & (SD_NR_VDIS - 1); VAR_2 = connect_to_sdog(s->addr, s->port); if (VAR_2 < 0) { error_report("failed to connect"); VAR_4 = VAR_2; goto out; } for (vid = VAR_11; VAR_8 < VAR_3; vid = (vid + 1) % SD_NR_VDIS) { if (!test_bit(vid, VAR_10)) { break; } VAR_4 = read_object(VAR_2, (char *)&VAR_9, vid_to_vdi_oid(vid),
0, SD_INODE_SIZE - sizeof(VAR_9.data_vdi_id), 0,
s->cache_enabled); if (VAR_4) { continue; } if (!strcmp(VAR_9.name, s->name) && is_snapshot(&VAR_9)) { sn_tab[VAR_8].date_sec = VAR_9.snap_ctime >> 32; sn_tab[VAR_8].date_nsec = VAR_9.snap_ctime & 0xffffffff; sn_tab[VAR_8].vm_state_size = VAR_9.vm_state_size; sn_tab[VAR_8].vm_clock_nsec = VAR_9.vm_clock_nsec; snprintf(sn_tab[VAR_8].id_str, sizeof(sn_tab[VAR_8].id_str), "%u",
VAR_9.snap_id); pstrcpy(sn_tab[VAR_8].name,
MIN(sizeof(sn_tab[VAR_8].name), sizeof(VAR_9.tag)),
VAR_9.tag); VAR_8++; } } closesocket(VAR_2); out:
*VAR_1 = sn_tab; g_free(VAR_10); if (VAR_4 < 0) { return VAR_4; } return VAR_8; }