From nobody Sun Feb 8 20:08:43 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1494945667763764.7047082552136; Tue, 16 May 2017 07:41:07 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B222E2D9FF8; Tue, 16 May 2017 14:40:18 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 147EF183E3; Tue, 16 May 2017 14:40:09 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id ED6584BB7F; Tue, 16 May 2017 14:39:44 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v4GE4q5E028028 for ; Tue, 16 May 2017 10:04:52 -0400 Received: by smtp.corp.redhat.com (Postfix) id 5E03B860E0; Tue, 16 May 2017 14:04:52 +0000 (UTC) Received: from moe.brq.redhat.com (dhcp129-131.brq.redhat.com [10.34.129.131]) by smtp.corp.redhat.com (Postfix) with ESMTP id DA23262926 for ; Tue, 16 May 2017 14:04:51 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com B222E2D9FF8 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com B222E2D9FF8 From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 16 May 2017 16:04:11 +0200 Message-Id: <14ba6ce85934cc2cd53286c71f0805c63ed76719.1494943031.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 31/31] virsh: Implement sparse stream to vol-upload X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Tue, 16 May 2017 14:41:06 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Similarly to previous commit, implement sparse streams feature for vol-upload. This is, however, slightly different approach, because we must implement a function that will tell us whether we are in a data section or in a hole. But there's no magic hidden in here. Signed-off-by: Michal Privoznik Reviewed-by: John Ferlan --- tools/virsh-util.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh-util.h | 24 ++++++++++++++++++++++++ tools/virsh-volume.c | 38 +++++++++++++++++++++++++------------- tools/virsh.pod | 3 ++- 4 files changed, 98 insertions(+), 14 deletions(-) diff --git a/tools/virsh-util.c b/tools/virsh-util.c index 198625bdb..44be3ad64 100644 --- a/tools/virsh-util.c +++ b/tools/virsh-util.c @@ -153,6 +153,35 @@ virshStreamSink(virStreamPtr st ATTRIBUTE_UNUSED, } =20 =20 +int +virshStreamSource(virStreamPtr st ATTRIBUTE_UNUSED, + char *bytes, + size_t nbytes, + void *opaque) +{ + virshStreamCallbackDataPtr cbData =3D opaque; + int fd =3D cbData->fd; + + return saferead(fd, bytes, nbytes); +} + + +int +virshStreamSourceSkip(virStreamPtr st ATTRIBUTE_UNUSED, + long long offset, + void *opaque) +{ + virshStreamCallbackDataPtr cbData =3D opaque; + int fd =3D cbData->fd; + off_t cur; + + if ((cur =3D lseek(fd, offset, SEEK_CUR)) =3D=3D (off_t) -1) + return -1; + + return 0; +} + + int virshStreamSkip(virStreamPtr st ATTRIBUTE_UNUSED, long long offset, @@ -171,6 +200,24 @@ virshStreamSkip(virStreamPtr st ATTRIBUTE_UNUSED, } =20 =20 +int +virshStreamInData(virStreamPtr st ATTRIBUTE_UNUSED, + int *inData, + long long *offset, + void *opaque) +{ + virshStreamCallbackDataPtr cbData =3D opaque; + vshControl *ctl =3D cbData->ctl; + int fd =3D cbData->fd; + int ret; + + if ((ret =3D virFileInData(fd, inData, offset)) < 0) + vshError(ctl, "%s", _("Unable to get current position in stream")); + + return ret; +} + + void virshDomainFree(virDomainPtr dom) { diff --git a/tools/virsh-util.h b/tools/virsh-util.h index 0aba247f6..9a0af3513 100644 --- a/tools/virsh-util.h +++ b/tools/virsh-util.h @@ -57,11 +57,35 @@ virshStreamSink(virStreamPtr st, size_t nbytes, void *opaque); =20 +typedef struct _virshStreamCallbackData virshStreamCallbackData; +typedef virshStreamCallbackData *virshStreamCallbackDataPtr; +struct _virshStreamCallbackData { + vshControl *ctl; + int fd; +}; + +int +virshStreamSource(virStreamPtr st, + char *bytes, + size_t nbytes, + void *opaque); + +int +virshStreamSourceSkip(virStreamPtr st, + long long offset, + void *opaque); + int virshStreamSkip(virStreamPtr st, long long offset, void *opaque); =20 +int +virshStreamInData(virStreamPtr st, + int *inData, + long long *offset, + void *opaque); + int virshDomainGetXMLFromDom(vshControl *ctl, virDomainPtr dom, diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c index 3d19b745e..0736bdcdb 100644 --- a/tools/virsh-volume.c +++ b/tools/virsh-volume.c @@ -660,18 +660,13 @@ static const vshCmdOptDef opts_vol_upload[] =3D { .type =3D VSH_OT_INT, .help =3D N_("amount of data to upload") }, + {.name =3D "sparse", + .type =3D VSH_OT_BOOL, + .help =3D N_("preserve sparseness of volume") + }, {.name =3D NULL} }; =20 -static int -cmdVolUploadSource(virStreamPtr st ATTRIBUTE_UNUSED, - char *bytes, size_t nbytes, void *opaque) -{ - int *fd =3D opaque; - - return saferead(*fd, bytes, nbytes); -} - static bool cmdVolUpload(vshControl *ctl, const vshCmd *cmd) { @@ -683,6 +678,8 @@ cmdVolUpload(vshControl *ctl, const vshCmd *cmd) const char *name =3D NULL; unsigned long long offset =3D 0, length =3D 0; virshControlPtr priv =3D ctl->privData; + unsigned int flags =3D 0; + virshStreamCallbackData cbData; =20 if (vshCommandOptULongLong(ctl, cmd, "offset", &offset) < 0) return false; @@ -701,19 +698,34 @@ cmdVolUpload(vshControl *ctl, const vshCmd *cmd) goto cleanup; } =20 + cbData.ctl =3D ctl; + cbData.fd =3D fd; + + if (vshCommandOptBool(cmd, "sparse")) + flags |=3D VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM; + if (!(st =3D virStreamNew(priv->conn, 0))) { vshError(ctl, _("cannot create a new stream")); goto cleanup; } =20 - if (virStorageVolUpload(vol, st, offset, length, 0) < 0) { + if (virStorageVolUpload(vol, st, offset, length, flags) < 0) { vshError(ctl, _("cannot upload to volume %s"), name); goto cleanup; } =20 - if (virStreamSendAll(st, cmdVolUploadSource, &fd) < 0) { - vshError(ctl, _("cannot send data to volume %s"), name); - goto cleanup; + if (flags & VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM) { + if (virStreamSparseSendAll(st, virshStreamSource, + virshStreamInData, + virshStreamSourceSkip, &cbData) < 0) { + vshError(ctl, _("cannot send data to volume %s"), name); + goto cleanup; + } + } else { + if (virStreamSendAll(st, virshStreamSource, &cbData) < 0) { + vshError(ctl, _("cannot send data to volume %s"), name); + goto cleanup; + } } =20 if (VIR_CLOSE(fd) < 0) { diff --git a/tools/virsh.pod b/tools/virsh.pod index dcaa0c170..42769170d 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -3924,13 +3924,14 @@ the storage volume should be deleted as well. Not a= ll storage drivers support this option, presently only rbd. =20 =3Ditem B [I<--pool> I] [I<--offset> I] -[I<--length> I] I I +[I<--length> I] [I<--sparse>] I I =20 Upload the contents of I to a storage volume. I<--pool> I is the name or UUID of the storage pool the volu= me is in. I is the name or key or path of the volume where = the file will be uploaded. +If I<--sparse> is specified, this command will preserve volume sparseness. I<--offset> is the position in the storage volume at which to start writing the data. The value must be 0 or larger. I<--length> is an upper bound of the amount of data to be uploaded. A negative value is interpreted --=20 2.13.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list