Signed-off-by: Vasiliy Tolstov <v.tols...@selfip.ru> --- block/sheepdog.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-)
diff --git a/block/sheepdog.c b/block/sheepdog.c index d80e4ed..c3fae50 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -2484,8 +2484,63 @@ static int sd_snapshot_delete(BlockDriverState *bs, const char *name, Error **errp) { - /* FIXME: Delete specified snapshot id. */ - return 0; + uint32_t snap_id = 0; + uint32_t vdi = 0; + char snap_tag[SD_MAX_VDI_TAG_LEN]; + Error *local_err = NULL; + int fd, ret; + char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN]; + BDRVSheepdogState *s = bs->opaque; + unsigned int wlen = SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN, rlen = 0; + + memset(buf, 0, sizeof(buf)); + memset(snap_tag, 0, sizeof(snap_tag)); + pstrcpy(buf, SD_MAX_VDI_LEN, s->name); + snap_id = strtoul(snapshot_id, NULL, 10); + if (!snap_id) { + pstrcpy(snap_tag, sizeof(snap_tag), snapshot_id); + pstrcpy(buf + SD_MAX_VDI_LEN, SD_MAX_VDI_TAG_LEN, snap_tag); + } + + ret = find_vdi_name(s, s->name, snap_id, snap_tag, &vdi, true, &local_err); + if (ret) { + return ret; + } + + SheepdogVdiReq hdr = { + .opcode = SD_OP_DEL_VDI, + .data_length = wlen, + .flags = SD_FLAG_CMD_WRITE, + .snapid = snap_id, + }; + SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr; + + fd = connect_to_sdog(s, &local_err); + if (fd < 0) { + error_report_err(local_err); + return -1; + } + + ret = do_req(fd, s->aio_context, (SheepdogReq *)&hdr, + buf, &wlen, &rlen); + closesocket(fd); + if (ret) { + return ret; + } + + switch (rsp->result) { + case SD_RES_NO_VDI: + error_report("%s was already deleted", s->name); + case SD_RES_SUCCESS: + break; + default: + error_report("%s, %s", sd_strerror(rsp->result), s->name); + return -1; + } + +// ret = reload_inode(s, snap_id, snap_tag); + + return ret; } static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) -- 2.5.0