From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55211) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aJAsJ-0008CY-5z for qemu-devel@nongnu.org; Tue, 12 Jan 2016 21:09:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aJAsH-00025O-Dn for qemu-devel@nongnu.org; Tue, 12 Jan 2016 21:09:27 -0500 Received: from mail-lf0-x234.google.com ([2a00:1450:4010:c07::234]:35283) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aJAsH-00025E-2Z for qemu-devel@nongnu.org; Tue, 12 Jan 2016 21:09:25 -0500 Received: by mail-lf0-x234.google.com with SMTP id c192so246466964lfe.2 for ; Tue, 12 Jan 2016 18:09:24 -0800 (PST) MIME-Version: 1.0 In-Reply-To: <1450873346-22334-1-git-send-email-mitake.hitoshi@lab.ntt.co.jp> References: <1450873346-22334-1-git-send-email-mitake.hitoshi@lab.ntt.co.jp> Date: Wed, 13 Jan 2016 11:09:23 +0900 Message-ID: From: Hitoshi Mitake Content-Type: multipart/alternative; boundary=001a114024a0b1b06205292da8ba Subject: Re: [Qemu-devel] [PATCH] sheepdog: allow to delete snapshot List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: QEMU Developers Cc: Hitoshi Mitake , Jeff Cody , sheepdog , Vasiliy Tolstov --001a114024a0b1b06205292da8ba Content-Type: text/plain; charset=UTF-8 On Wed, Dec 23, 2015 at 9:22 PM, Hitoshi Mitake < mitake.hitoshi@lab.ntt.co.jp> wrote: > From: Vasiliy Tolstov > > This patch implements a blockdriver function bdrv_snapshot_delete() in > the sheepdog driver. With the new function, snapshots of sheepdog can > be deleted from libvirt. > > Cc: Jeff Cody > Signed-off-by: Hitoshi Mitake > Signed-off-by: Vasiliy Tolstov > ping, Jeff? Thanks, Hitoshi > --- > block/sheepdog.c | 125 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 123 insertions(+), 2 deletions(-) > > diff --git a/block/sheepdog.c b/block/sheepdog.c > index d80e4ed..0a4f2fc 100644 > --- a/block/sheepdog.c > +++ b/block/sheepdog.c > @@ -283,6 +283,12 @@ static inline bool is_snapshot(struct SheepdogInode > *inode) > return !!inode->snap_ctime; > } > > +static inline size_t count_data_objs(const struct SheepdogInode *inode) > +{ > + return DIV_ROUND_UP(inode->vdi_size, > + (1UL << inode->block_size_shift)); > +} > + > #undef DPRINTF > #ifdef DEBUG_SDOG > #define DPRINTF(fmt, args...) \ > @@ -2479,13 +2485,128 @@ out: > return ret; > } > > +#define NR_BATCHED_DISCARD 128 > + > +static bool remove_objects(BDRVSheepdogState *s) > +{ > + int fd, i = 0, nr_objs = 0; > + Error *local_err = NULL; > + int ret = 0; > + bool result = true; > + SheepdogInode *inode = &s->inode; > + > + fd = connect_to_sdog(s, &local_err); > + if (fd < 0) { > + error_report_err(local_err); > + return false; > + } > + > + nr_objs = count_data_objs(inode); > + while (i < nr_objs) { > + int start_idx, nr_filled_idx; > + > + while (i < nr_objs && !inode->data_vdi_id[i]) { > + i++; > + } > + start_idx = i; > + > + nr_filled_idx = 0; > + while (i < nr_objs && nr_filled_idx < NR_BATCHED_DISCARD) { > + if (inode->data_vdi_id[i]) { > + inode->data_vdi_id[i] = 0; > + nr_filled_idx++; > + } > + > + i++; > + } > + > + ret = write_object(fd, s->aio_context, > + (char *)&inode->data_vdi_id[start_idx], > + vid_to_vdi_oid(s->inode.vdi_id), > inode->nr_copies, > + (i - start_idx) * sizeof(uint32_t), > + offsetof(struct SheepdogInode, > + data_vdi_id[start_idx]), > + false, s->cache_flags); > + if (ret < 0) { > + error_report("failed to discard snapshot inode."); > + result = false; > + goto out; > + } > + } > + > +out: > + closesocket(fd); > + return result; > +} > + > static int sd_snapshot_delete(BlockDriverState *bs, > const char *snapshot_id, > const char *name, > Error **errp) > { > - /* FIXME: Delete specified snapshot id. */ > - return 0; > + uint32_t snap_id = 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; > + uint32_t vid; > + SheepdogVdiReq hdr = { > + .opcode = SD_OP_DEL_VDI, > + .data_length = wlen, > + .flags = SD_FLAG_CMD_WRITE, > + }; > + SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr; > + > + if (!remove_objects(s)) { > + return -1; > + } > + > + memset(buf, 0, sizeof(buf)); > + memset(snap_tag, 0, sizeof(snap_tag)); > + pstrcpy(buf, SD_MAX_VDI_LEN, s->name); > + if (qemu_strtoul(snapshot_id, NULL, 10, (unsigned long *)&snap_id)) { > + return -1; > + } > + > + if (snap_id) { > + hdr.snapid = snap_id; > + } else { > + 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, &vid, true, > + &local_err); > + if (ret) { > + return ret; > + } > + > + 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; > + } > + > + return ret; > } > > static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo > **psn_tab) > -- > 1.9.1 > > --001a114024a0b1b06205292da8ba Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable


On Wed, Dec 23, 2015 at 9:22 PM, Hitoshi Mitake <<= a href=3D"mailto:mitake.hitoshi@lab.ntt.co.jp" target=3D"_blank">mitake.hit= oshi@lab.ntt.co.jp> wrote:
= From: Vasiliy Tolstov <v.tolstov@= selfip.ru>

This patch implements a blockdriver function bdrv_snapshot_delete() in
the sheepdog driver. With the new function, snapshots of sheepdog can
be deleted from libvirt.

Cc: Jeff Cody <jcody@redhat.com&= gt;
Signed-off-by: Hitoshi Mitake <mitake.hitoshi@lab.ntt.co.jp>
Signed-off-by: Vasiliy Tolstov <v= .tolstov@selfip.ru>

ping, Jeff?<= /div>

Thanks,
Hitoshi
=C2=A0
---
=C2=A0block/sheepdog.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++= ++++++++-
=C2=A01 file changed, 123 insertions(+), 2 deletions(-)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index d80e4ed..0a4f2fc 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -283,6 +283,12 @@ static inline bool is_snapshot(struct SheepdogInode *i= node)
=C2=A0 =C2=A0 =C2=A0return !!inode->snap_ctime;
=C2=A0}

+static inline size_t count_data_objs(const struct SheepdogInode *inode) +{
+=C2=A0 =C2=A0 return DIV_ROUND_UP(inode->vdi_size,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (1UL << inode->block_size_shift));
+}
+
=C2=A0#undef DPRINTF
=C2=A0#ifdef DEBUG_SDOG
=C2=A0#define DPRINTF(fmt, args...)=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0\
@@ -2479,13 +2485,128 @@ out:
=C2=A0 =C2=A0 =C2=A0return ret;
=C2=A0}

+#define NR_BATCHED_DISCARD 128
+
+static bool remove_objects(BDRVSheepdogState *s)
+{
+=C2=A0 =C2=A0 int fd, i =3D 0, nr_objs =3D 0;
+=C2=A0 =C2=A0 Error *local_err =3D NULL;
+=C2=A0 =C2=A0 int ret =3D 0;
+=C2=A0 =C2=A0 bool result =3D true;
+=C2=A0 =C2=A0 SheepdogInode *inode =3D &s->inode;
+
+=C2=A0 =C2=A0 fd =3D connect_to_sdog(s, &local_err);
+=C2=A0 =C2=A0 if (fd < 0) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 error_report_err(local_err);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return false;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 nr_objs =3D count_data_objs(inode);
+=C2=A0 =C2=A0 while (i < nr_objs) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 int start_idx, nr_filled_idx;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 while (i < nr_objs && !inode->da= ta_vdi_id[i]) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 i++;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 start_idx =3D i;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 nr_filled_idx =3D 0;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 while (i < nr_objs && nr_filled_idx= < NR_BATCHED_DISCARD) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (inode->data_vdi_id[i]) {<= br> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 inode->data_vdi= _id[i] =3D 0;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 nr_filled_idx++; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 i++;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret =3D write_object(fd, s->aio_context, +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0(char *)&inode->data_vdi_id[start_idx],
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0vid_to_vdi_oid(s->inode.vdi_id), inode->nr_co= pies,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0(i - start_idx) * sizeof(uint32_t),
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0offsetof(struct SheepdogInode,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 data_vdi_id[start_idx]= ),
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0false, s->cache_flags);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (ret < 0) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 error_report("failed to dis= card snapshot inode.");
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 result =3D false;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 goto out;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 }
+
+out:
+=C2=A0 =C2=A0 closesocket(fd);
+=C2=A0 =C2=A0 return result;
+}
+
=C2=A0static int sd_snapshot_delete(BlockDriverState *bs,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0const char *snapshot_id,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0const char *name,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Error **errp)
=C2=A0{
-=C2=A0 =C2=A0 /* FIXME: Delete specified snapshot id.=C2=A0 */
-=C2=A0 =C2=A0 return 0;
+=C2=A0 =C2=A0 uint32_t snap_id =3D 0;
+=C2=A0 =C2=A0 char snap_tag[SD_MAX_VDI_TAG_LEN];
+=C2=A0 =C2=A0 Error *local_err =3D NULL;
+=C2=A0 =C2=A0 int fd, ret;
+=C2=A0 =C2=A0 char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];
+=C2=A0 =C2=A0 BDRVSheepdogState *s =3D bs->opaque;
+=C2=A0 =C2=A0 unsigned int wlen =3D SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN, r= len =3D 0;
+=C2=A0 =C2=A0 uint32_t vid;
+=C2=A0 =C2=A0 SheepdogVdiReq hdr =3D {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 .opcode =3D SD_OP_DEL_VDI,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 .data_length =3D wlen,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 .flags =3D SD_FLAG_CMD_WRITE,
+=C2=A0 =C2=A0 };
+=C2=A0 =C2=A0 SheepdogVdiRsp *rsp =3D (SheepdogVdiRsp *)&hdr;
+
+=C2=A0 =C2=A0 if (!remove_objects(s)) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 memset(buf, 0, sizeof(buf));
+=C2=A0 =C2=A0 memset(snap_tag, 0, sizeof(snap_tag));
+=C2=A0 =C2=A0 pstrcpy(buf, SD_MAX_VDI_LEN, s->name);
+=C2=A0 =C2=A0 if (qemu_strtoul(snapshot_id, NULL, 10, (unsigned long *)&am= p;snap_id)) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 if (snap_id) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 hdr.snapid =3D snap_id;
+=C2=A0 =C2=A0 } else {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 pstrcpy(snap_tag, sizeof(snap_tag), snapshot_i= d);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 pstrcpy(buf + SD_MAX_VDI_LEN, SD_MAX_VDI_TAG_L= EN, snap_tag);
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 ret =3D find_vdi_name(s, s->name, snap_id, snap_tag, &= ;vid, true,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 &local_err);
+=C2=A0 =C2=A0 if (ret) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return ret;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 fd =3D connect_to_sdog(s, &local_err);
+=C2=A0 =C2=A0 if (fd < 0) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 error_report_err(local_err);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 ret =3D do_req(fd, s->aio_context, (SheepdogReq *)&hd= r,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0buf, &wl= en, &rlen);
+=C2=A0 =C2=A0 closesocket(fd);
+=C2=A0 =C2=A0 if (ret) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return ret;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 switch (rsp->result) {
+=C2=A0 =C2=A0 case SD_RES_NO_VDI:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 error_report("%s was already deleted"= ;, s->name);
+=C2=A0 =C2=A0 case SD_RES_SUCCESS:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
+=C2=A0 =C2=A0 default:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 error_report("%s, %s", sd_strerror(r= sp->result), s->name);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 return ret;
=C2=A0}

=C2=A0static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **= psn_tab)
--
1.9.1


--001a114024a0b1b06205292da8ba--