<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Dec 23, 2015 at 9:22 PM, Hitoshi Mitake <span dir="ltr"><<a href="mailto:mitake.hitoshi@lab.ntt.co.jp" target="_blank">mitake.hitoshi@lab.ntt.co.jp</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Vasiliy Tolstov <<a href="mailto:v.tolstov@selfip.ru">v.tolstov@selfip.ru</a>><br>
<br>
This patch implements a blockdriver function bdrv_snapshot_delete() in<br>
the sheepdog driver. With the new function, snapshots of sheepdog can<br>
be deleted from libvirt.<br>
<br>
Cc: Jeff Cody <<a href="mailto:jcody@redhat.com">jcody@redhat.com</a>><br>
Signed-off-by: Hitoshi Mitake <<a href="mailto:mitake.hitoshi@lab.ntt.co.jp">mitake.hitoshi@lab.ntt.co.jp</a>><br>
Signed-off-by: Vasiliy Tolstov <<a href="mailto:v.tolstov@selfip.ru">v.tolstov@selfip.ru</a>><br></blockquote><div><br></div><div>ping, Jeff?</div><div><br></div><div>Thanks,</div><div>Hitoshi</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
---<br>
block/sheepdog.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-<br>
1 file changed, 123 insertions(+), 2 deletions(-)<br>
<br>
diff --git a/block/sheepdog.c b/block/sheepdog.c<br>
index d80e4ed..0a4f2fc 100644<br>
--- a/block/sheepdog.c<br>
+++ b/block/sheepdog.c<br>
@@ -283,6 +283,12 @@ static inline bool is_snapshot(struct SheepdogInode *inode)<br>
return !!inode->snap_ctime;<br>
}<br>
<br>
+static inline size_t count_data_objs(const struct SheepdogInode *inode)<br>
+{<br>
+ return DIV_ROUND_UP(inode->vdi_size,<br>
+ (1UL << inode->block_size_shift));<br>
+}<br>
+<br>
#undef DPRINTF<br>
#ifdef DEBUG_SDOG<br>
#define DPRINTF(fmt, args...) \<br>
@@ -2479,13 +2485,128 @@ out:<br>
return ret;<br>
}<br>
<br>
+#define NR_BATCHED_DISCARD 128<br>
+<br>
+static bool remove_objects(BDRVSheepdogState *s)<br>
+{<br>
+ int fd, i = 0, nr_objs = 0;<br>
+ Error *local_err = NULL;<br>
+ int ret = 0;<br>
+ bool result = true;<br>
+ SheepdogInode *inode = &s->inode;<br>
+<br>
+ fd = connect_to_sdog(s, &local_err);<br>
+ if (fd < 0) {<br>
+ error_report_err(local_err);<br>
+ return false;<br>
+ }<br>
+<br>
+ nr_objs = count_data_objs(inode);<br>
+ while (i < nr_objs) {<br>
+ int start_idx, nr_filled_idx;<br>
+<br>
+ while (i < nr_objs && !inode->data_vdi_id[i]) {<br>
+ i++;<br>
+ }<br>
+ start_idx = i;<br>
+<br>
+ nr_filled_idx = 0;<br>
+ while (i < nr_objs && nr_filled_idx < NR_BATCHED_DISCARD) {<br>
+ if (inode->data_vdi_id[i]) {<br>
+ inode->data_vdi_id[i] = 0;<br>
+ nr_filled_idx++;<br>
+ }<br>
+<br>
+ i++;<br>
+ }<br>
+<br>
+ ret = write_object(fd, s->aio_context,<br>
+ (char *)&inode->data_vdi_id[start_idx],<br>
+ vid_to_vdi_oid(s->inode.vdi_id), inode->nr_copies,<br>
+ (i - start_idx) * sizeof(uint32_t),<br>
+ offsetof(struct SheepdogInode,<br>
+ data_vdi_id[start_idx]),<br>
+ false, s->cache_flags);<br>
+ if (ret < 0) {<br>
+ error_report("failed to discard snapshot inode.");<br>
+ result = false;<br>
+ goto out;<br>
+ }<br>
+ }<br>
+<br>
+out:<br>
+ closesocket(fd);<br>
+ return result;<br>
+}<br>
+<br>
static int sd_snapshot_delete(BlockDriverState *bs,<br>
const char *snapshot_id,<br>
const char *name,<br>
Error **errp)<br>
{<br>
- /* FIXME: Delete specified snapshot id. */<br>
- return 0;<br>
+ uint32_t snap_id = 0;<br>
+ char snap_tag[SD_MAX_VDI_TAG_LEN];<br>
+ Error *local_err = NULL;<br>
+ int fd, ret;<br>
+ char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];<br>
+ BDRVSheepdogState *s = bs->opaque;<br>
+ unsigned int wlen = SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN, rlen = 0;<br>
+ uint32_t vid;<br>
+ SheepdogVdiReq hdr = {<br>
+ .opcode = SD_OP_DEL_VDI,<br>
+ .data_length = wlen,<br>
+ .flags = SD_FLAG_CMD_WRITE,<br>
+ };<br>
+ SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;<br>
+<br>
+ if (!remove_objects(s)) {<br>
+ return -1;<br>
+ }<br>
+<br>
+ memset(buf, 0, sizeof(buf));<br>
+ memset(snap_tag, 0, sizeof(snap_tag));<br>
+ pstrcpy(buf, SD_MAX_VDI_LEN, s->name);<br>
+ if (qemu_strtoul(snapshot_id, NULL, 10, (unsigned long *)&snap_id)) {<br>
+ return -1;<br>
+ }<br>
+<br>
+ if (snap_id) {<br>
+ hdr.snapid = snap_id;<br>
+ } else {<br>
+ pstrcpy(snap_tag, sizeof(snap_tag), snapshot_id);<br>
+ pstrcpy(buf + SD_MAX_VDI_LEN, SD_MAX_VDI_TAG_LEN, snap_tag);<br>
+ }<br>
+<br>
+ ret = find_vdi_name(s, s->name, snap_id, snap_tag, &vid, true,<br>
+ &local_err);<br>
+ if (ret) {<br>
+ return ret;<br>
+ }<br>
+<br>
+ fd = connect_to_sdog(s, &local_err);<br>
+ if (fd < 0) {<br>
+ error_report_err(local_err);<br>
+ return -1;<br>
+ }<br>
+<br>
+ ret = do_req(fd, s->aio_context, (SheepdogReq *)&hdr,<br>
+ buf, &wlen, &rlen);<br>
+ closesocket(fd);<br>
+ if (ret) {<br>
+ return ret;<br>
+ }<br>
+<br>
+ switch (rsp->result) {<br>
+ case SD_RES_NO_VDI:<br>
+ error_report("%s was already deleted", s->name);<br>
+ case SD_RES_SUCCESS:<br>
+ break;<br>
+ default:<br>
+ error_report("%s, %s", sd_strerror(rsp->result), s->name);<br>
+ return -1;<br>
+ }<br>
+<br>
+ return ret;<br>
}<br>
<br>
static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.9.1<br>
<br>
</font></span></blockquote></div><br></div></div>