From nobody Thu Jul 3 16:34:07 2025 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 1498135291156981.4485245766534; Thu, 22 Jun 2017 05:41:31 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2DF4F42BD8; Thu, 22 Jun 2017 12:41:28 +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 02F7A5D96B; Thu, 22 Jun 2017 12:41:28 +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 B43D84E986; Thu, 22 Jun 2017 12:41:27 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v5MCV5r2023570 for ; Thu, 22 Jun 2017 08:31:05 -0400 Received: by smtp.corp.redhat.com (Postfix) id E0FB219147; Thu, 22 Jun 2017 12:31:05 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6AF361915B for ; Thu, 22 Jun 2017 12:31:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 2DF4F42BD8 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 2DF4F42BD8 From: Michal Privoznik To: libvir-list@redhat.com Date: Thu, 22 Jun 2017 14:30:50 +0200 Message-Id: <1e7e0f6e024dcd4e82be026e3123506b318516bb.1498134243.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v4 6/6] virStream*All: Report error if a callback fails 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.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 22 Jun 2017 12:41:29 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" All of these four functions (virStreamRecvAll, virStreamSendAll, virStreamSparseRecvAll, virStreamSparseSendAll) take one or more callback that handle various aspects of streams. However, if any of them fails no error is reported therefore caller does not know what went wrong. At the same time, we silently presumed callbacks to set errno on failure. With this change we should document it explicitly as the error is not properly reported. Signed-off-by: Michal Privoznik Reviewed-by: John Ferlan --- include/libvirt/libvirt-stream.h | 17 +++++++++++++- src/libvirt-stream.c | 50 +++++++++++++++++++++++++++++++++---= ---- 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/include/libvirt/libvirt-stream.h b/include/libvirt/libvirt-str= eam.h index d18d43140..86f96b158 100644 --- a/include/libvirt/libvirt-stream.h +++ b/include/libvirt/libvirt-stream.h @@ -82,7 +82,10 @@ int virStreamRecvHole(virStreamPtr, * of bytes. The callback will continue to be * invoked until it indicates the end of the source * has been reached by returning 0. A return value - * of -1 at any time will abort the send operation + * of -1 at any time will abort the send operation. + * + * Please note that for more accurate error reporting the + * callback should set appropriate errno on failure. * * Returns the number of bytes filled, 0 upon end * of file, or -1 upon error @@ -119,6 +122,9 @@ int virStreamSendAll(virStreamPtr st, * This function should not adjust the current position within * the file. * + * Please note that for more accurate error reporting the + * callback should set appropriate errno on failure. + * * Returns 0 on success, * -1 upon error */ @@ -142,6 +148,9 @@ typedef int (*virStreamSourceHoleFunc)(virStreamPtr st, * processing the hole in the stream source and then return. * A return value of -1 at any time will abort the send operation. * + * Please note that for more accurate error reporting the + * callback should set appropriate errno on failure. + * * Returns 0 on success, * -1 upon error. */ @@ -176,6 +185,9 @@ int virStreamSparseSendAll(virStreamPtr st, * has been reached. A return value of -1 at any time * will abort the receive operation * + * Please note that for more accurate error reporting the + * callback should set appropriate errno on failure. + * * Returns the number of bytes consumed or -1 upon * error */ @@ -203,6 +215,9 @@ int virStreamRecvAll(virStreamPtr st, * hole in the stream target and then return. A return value of * -1 at any time will abort the receive operation. * + * Please note that for more accurate error reporting the + * callback should set appropriate errno on failure. + * * Returns 0 on success, * -1 upon error */ diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c index 1594ed212..cf1b2293a 100644 --- a/src/libvirt-stream.c +++ b/src/libvirt-stream.c @@ -567,7 +567,7 @@ virStreamInData(virStreamPtr stream, * * Returns -1 upon any error, with virStreamAbort() already * having been called, so the caller need only call - * virStreamFree() + * virStreamFree(). */ int virStreamSendAll(virStreamPtr stream, @@ -595,9 +595,15 @@ virStreamSendAll(virStreamPtr stream, =20 for (;;) { int got, offset =3D 0; + + errno =3D 0; got =3D (handler)(stream, bytes, want, opaque); - if (got < 0) + if (got < 0) { + if (errno =3D=3D 0) + errno =3D EIO; + virReportSystemError(errno, "%s", _("send handler failed")); goto cleanup; + } if (got =3D=3D 0) break; while (offset < got) { @@ -732,17 +738,24 @@ int virStreamSparseSendAll(virStreamPtr stream, size_t want =3D bufLen; const unsigned int skipFlags =3D 0; =20 + errno =3D 0; if (!dataLen) { - if (holeHandler(stream, &inData, §ionLen, opaque) < 0) + if (holeHandler(stream, &inData, §ionLen, opaque) < 0) { + if (errno =3D=3D 0) + errno =3D EIO; + virReportSystemError(errno, "%s", _("send holeHandler fail= ed")); goto cleanup; + } =20 if (!inData && sectionLen) { if (virStreamSendHole(stream, sectionLen, skipFlags) < 0) goto cleanup; =20 if (skipHandler(stream, sectionLen, opaque) < 0) { + if (errno =3D=3D 0) + errno =3D EIO; virReportSystemError(errno, "%s", - _("unable to skip hole")); + _("send skipHandler failed")); goto cleanup; } continue; @@ -755,8 +768,13 @@ int virStreamSparseSendAll(virStreamPtr stream, want =3D dataLen; =20 got =3D (handler)(stream, bytes, want, opaque); - if (got < 0) + if (got < 0) { + if (errno =3D=3D 0) + errno =3D EIO; + virReportSystemError(errno, "%s", + _("send handler failed")); goto cleanup; + } if (got =3D=3D 0) break; while (offset < got) { @@ -854,6 +872,8 @@ virStreamRecvAll(virStreamPtr stream, =20 for (;;) { int got, offset =3D 0; + + errno =3D 0; got =3D virStreamRecv(stream, bytes, want); if (got < 0) goto cleanup; @@ -862,8 +882,13 @@ virStreamRecvAll(virStreamPtr stream, while (offset < got) { int done; done =3D (handler)(stream, bytes + offset, got - offset, opaqu= e); - if (done < 0) + if (done < 0) { + if (errno =3D=3D 0) + errno =3D EIO; + virReportSystemError(errno, "%s", + _("recv handler failed")); goto cleanup; + } offset +=3D done; } } @@ -971,13 +996,18 @@ virStreamSparseRecvAll(virStreamPtr stream, long long holeLen; const unsigned int holeFlags =3D 0; =20 + errno =3D 0; got =3D virStreamRecvFlags(stream, bytes, want, flags); if (got =3D=3D -3) { if (virStreamRecvHole(stream, &holeLen, holeFlags) < 0) goto cleanup; =20 - if (holeHandler(stream, holeLen, opaque) < 0) + if (holeHandler(stream, holeLen, opaque) < 0) { + if (errno =3D=3D 0) + errno =3D EIO; + virReportSystemError(errno, "%s", _("recv holeHandler fail= ed")); goto cleanup; + } continue; } else if (got < 0) { goto cleanup; @@ -987,8 +1017,12 @@ virStreamSparseRecvAll(virStreamPtr stream, while (offset < got) { int done; done =3D (handler)(stream, bytes + offset, got - offset, opaqu= e); - if (done < 0) + if (done < 0) { + if (errno =3D=3D 0) + errno =3D EIO; + virReportSystemError(errno, "%s", _("recv handler failed")= ); goto cleanup; + } offset +=3D done; } } --=20 2.13.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list