From nobody Thu May 2 17:05:06 2024 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 1496318566813610.30977304333; Thu, 1 Jun 2017 05:02:46 -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 73B97680FB; Thu, 1 Jun 2017 12:02:43 +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 064B553CD8; Thu, 1 Jun 2017 12:02:43 +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 5DD5897036; Thu, 1 Jun 2017 12:02:30 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v51C2SMM021126 for ; Thu, 1 Jun 2017 08:02:28 -0400 Received: by smtp.corp.redhat.com (Postfix) id DA3891753C; Thu, 1 Jun 2017 12:02:28 +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 62ADE7DEDA for ; Thu, 1 Jun 2017 12:02:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 73B97680FB Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.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 73B97680FB From: Michal Privoznik To: libvir-list@redhat.com Date: Thu, 1 Jun 2017 14:02:09 +0200 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 1/6] virfdstream: Check for thread error more frequently 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.38]); Thu, 01 Jun 2017 12:02:44 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" When the I/O thread quits (e.g. due to an I/O error, lseek() error, whatever), any subsequent virFDStream API should return error too. Moreover, when invoking stream event callback, we must set the VIR_STREAM_EVENT_ERROR flag so that the callback knows something bad happened. Signed-off-by: Michal Privoznik --- src/util/virfdstream.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/util/virfdstream.c b/src/util/virfdstream.c index 7ee58be13..cd24757e6 100644 --- a/src/util/virfdstream.c +++ b/src/util/virfdstream.c @@ -312,6 +312,9 @@ static void virFDStreamEvent(int watch ATTRIBUTE_UNUSED, return; } =20 + if (fdst->threadErr) + events |=3D VIR_STREAM_EVENT_ERROR; + cb =3D fdst->cb; cbopaque =3D fdst->opaque; ff =3D fdst->ff; @@ -787,10 +790,10 @@ static int virFDStreamWrite(virStreamPtr st, const ch= ar *bytes, size_t nbytes) if (fdst->thread) { char *buf; =20 - if (fdst->threadQuit) { + if (fdst->threadQuit || fdst->threadErr) { virReportSystemError(EBADF, "%s", _("cannot write to stream")); - return -1; + goto cleanup; } =20 if (VIR_ALLOC(msg) < 0 || @@ -866,7 +869,7 @@ static int virFDStreamRead(virStreamPtr st, char *bytes= , size_t nbytes) virFDStreamMsgPtr msg =3D NULL; =20 while (!(msg =3D fdst->msg)) { - if (fdst->threadQuit) { + if (fdst->threadQuit || fdst->threadErr) { if (nbytes) { virReportSystemError(EBADF, "%s", _("stream is not open")); @@ -959,6 +962,9 @@ virFDStreamSendHole(virStreamPtr st, fdst->offset +=3D length; } =20 + if (fdst->threadErr) + goto cleanup; + if (fdst->thread) { /* Things are a bit complicated here. If FDStream is in a * read mode, then if the message at the queue head is @@ -1018,6 +1024,9 @@ virFDStreamInData(virStreamPtr st, =20 virObjectLock(fdst); =20 + if (fdst->threadErr) + goto cleanup; + if (fdst->thread) { virFDStreamMsgPtr msg; =20 --=20 2.13.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 17:05:06 2024 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 1496318595714683.0893020014985; Thu, 1 Jun 2017 05:03:15 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8C4041A672F; Thu, 1 Jun 2017 12:03:12 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 65BE083E94; Thu, 1 Jun 2017 12:03:12 +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 1287B18677D2; Thu, 1 Jun 2017 12:02:51 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v51C2VwM021169 for ; Thu, 1 Jun 2017 08:02:31 -0400 Received: by smtp.corp.redhat.com (Postfix) id 5072A1754C; Thu, 1 Jun 2017 12:02:31 +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 CC9511755D for ; Thu, 1 Jun 2017 12:02:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 8C4041A672F Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.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 8C4041A672F From: Michal Privoznik To: libvir-list@redhat.com Date: Thu, 1 Jun 2017 14:02:10 +0200 Message-Id: <34f1b8cf3e116a38c6fafe0881f60aa992278c02.1496318427.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 2/6] fdstream: Report error from the I/O thread 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.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 01 Jun 2017 12:03:13 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Problem with our error reporting is that the error object is a thread local variable. That means if there's an error reported within the I/O thread it gets logged and everything, but later when the event loop aborts the stream it doesn't see the original error. So we are left with some generic error. We can do better if we copy the error message between the threads. Signed-off-by: Michal Privoznik --- daemon/stream.c | 18 ++++++++++++------ src/util/virfdstream.c | 9 ++++++--- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/daemon/stream.c b/daemon/stream.c index 1d5b50ad7..5077ac8b0 100644 --- a/daemon/stream.c +++ b/daemon/stream.c @@ -231,17 +231,23 @@ daemonStreamEvent(virStreamPtr st, int events, void *= opaque) int ret; virNetMessagePtr msg; virNetMessageError rerr; + virErrorPtr origErr =3D virSaveLastError(); =20 memset(&rerr, 0, sizeof(rerr)); stream->closed =3D true; virStreamEventRemoveCallback(stream->st); virStreamAbort(stream->st); - if (events & VIR_STREAM_EVENT_HANGUP) - virReportError(VIR_ERR_RPC, - "%s", _("stream had unexpected termination")); - else - virReportError(VIR_ERR_RPC, - "%s", _("stream had I/O failure")); + if (origErr && origErr->code !=3D VIR_ERR_OK) { + virSetError(origErr); + virFreeError(origErr); + } else { + if (events & VIR_STREAM_EVENT_HANGUP) + virReportError(VIR_ERR_RPC, + "%s", _("stream had unexpected termination"= )); + else + virReportError(VIR_ERR_RPC, + "%s", _("stream had I/O failure")); + } =20 msg =3D virNetMessageNew(false); if (!msg) { diff --git a/src/util/virfdstream.c b/src/util/virfdstream.c index cd24757e6..5b59765fa 100644 --- a/src/util/virfdstream.c +++ b/src/util/virfdstream.c @@ -106,7 +106,7 @@ struct virFDStreamData { /* Thread data */ virThreadPtr thread; virCond threadCond; - int threadErr; + virErrorPtr threadErr; bool threadQuit; bool threadAbort; bool threadDoRead; @@ -123,6 +123,7 @@ virFDStreamDataDispose(void *obj) virFDStreamDataPtr fdst =3D obj; =20 VIR_DEBUG("obj=3D%p", fdst); + virFreeError(fdst->threadErr); virFDStreamMsgQueueFree(&fdst->msg); } =20 @@ -312,8 +313,10 @@ static void virFDStreamEvent(int watch ATTRIBUTE_UNUSE= D, return; } =20 - if (fdst->threadErr) + if (fdst->threadErr) { events |=3D VIR_STREAM_EVENT_ERROR; + virSetError(fdst->threadErr); + } =20 cb =3D fdst->cb; cbopaque =3D fdst->opaque; @@ -637,7 +640,7 @@ virFDStreamThread(void *opaque) return; =20 error: - fdst->threadErr =3D errno; + fdst->threadErr =3D virSaveLastError(); goto cleanup; } =20 --=20 2.13.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 17:05:06 2024 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 1496318574366220.0732718758403; Thu, 1 Jun 2017 05:02:54 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 03D971A6732; Thu, 1 Jun 2017 12:02:50 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CCC8F83893; Thu, 1 Jun 2017 12:02:49 +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 30D2118677EE; Thu, 1 Jun 2017 12:02:37 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v51C2aZ5021271 for ; Thu, 1 Jun 2017 08:02:36 -0400 Received: by smtp.corp.redhat.com (Postfix) id 343A11753C; Thu, 1 Jun 2017 12:02:36 +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 B05847DEDA for ; Thu, 1 Jun 2017 12:02:31 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 03D971A6732 Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.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 03D971A6732 From: Michal Privoznik To: libvir-list@redhat.com Date: Thu, 1 Jun 2017 14:02:11 +0200 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 3/6] virStream*All: Call virStreamAbort() more frequently 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.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 01 Jun 2017 12:02:50 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Our documentation to all four virStreamRecvAll, virStreamSendAll, virStreamSparseRecvAll, virStreamSparseSendAll says that if these functions fail, virStreamAbort() is called. But that is not necessarily true. For instance all of these functions allocate a buffer to work with. If the allocation fails, no virStreamAbort() is called despite -1 being returned. It's the same story with argument sanity checks and a lot of other checks. Signed-off-by: Michal Privoznik --- src/libvirt-stream.c | 49 ++++++++++++++++++++----------------------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c index d7a8f5816..bff0a0571 100644 --- a/src/libvirt-stream.c +++ b/src/libvirt-stream.c @@ -596,10 +596,8 @@ virStreamSendAll(virStreamPtr stream, for (;;) { int got, offset =3D 0; got =3D (handler)(stream, bytes, want, opaque); - if (got < 0) { - virStreamAbort(stream); + if (got < 0) goto cleanup; - } if (got =3D=3D 0) break; while (offset < got) { @@ -615,8 +613,10 @@ virStreamSendAll(virStreamPtr stream, cleanup: VIR_FREE(bytes); =20 - if (ret !=3D 0) + if (ret !=3D 0) { + virStreamAbort(stream); virDispatchError(stream->conn); + } =20 return ret; } @@ -728,21 +728,16 @@ int virStreamSparseSendAll(virStreamPtr stream, const unsigned int skipFlags =3D 0; =20 if (!dataLen) { - if (holeHandler(stream, &inData, §ionLen, opaque) < 0) { - virStreamAbort(stream); + if (holeHandler(stream, &inData, §ionLen, opaque) < 0) goto cleanup; - } =20 if (!inData && sectionLen) { - if (virStreamSendHole(stream, sectionLen, skipFlags) < 0) { - virStreamAbort(stream); + if (virStreamSendHole(stream, sectionLen, skipFlags) < 0) goto cleanup; - } =20 if (skipHandler(stream, sectionLen, opaque) < 0) { virReportSystemError(errno, "%s", _("unable to skip hole")); - virStreamAbort(stream); goto cleanup; } continue; @@ -755,10 +750,8 @@ int virStreamSparseSendAll(virStreamPtr stream, want =3D dataLen; =20 got =3D (handler)(stream, bytes, want, opaque); - if (got < 0) { - virStreamAbort(stream); + if (got < 0) goto cleanup; - } if (got =3D=3D 0) break; while (offset < got) { @@ -775,8 +768,10 @@ int virStreamSparseSendAll(virStreamPtr stream, cleanup: VIR_FREE(bytes); =20 - if (ret !=3D 0) + if (ret !=3D 0) { + virStreamAbort(stream); virDispatchError(stream->conn); + } =20 return ret; } @@ -857,10 +852,8 @@ virStreamRecvAll(virStreamPtr stream, while (offset < got) { int done; done =3D (handler)(stream, bytes + offset, got - offset, opaqu= e); - if (done < 0) { - virStreamAbort(stream); + if (done < 0) goto cleanup; - } offset +=3D done; } } @@ -869,8 +862,10 @@ virStreamRecvAll(virStreamPtr stream, cleanup: VIR_FREE(bytes); =20 - if (ret !=3D 0) + if (ret !=3D 0) { + virStreamAbort(stream); virDispatchError(stream->conn); + } =20 return ret; } @@ -963,15 +958,11 @@ virStreamSparseRecvAll(virStreamPtr stream, =20 got =3D virStreamRecvFlags(stream, bytes, want, flags); if (got =3D=3D -3) { - if (virStreamRecvHole(stream, &holeLen, holeFlags) < 0) { - virStreamAbort(stream); + if (virStreamRecvHole(stream, &holeLen, holeFlags) < 0) goto cleanup; - } =20 - if (holeHandler(stream, holeLen, opaque) < 0) { - virStreamAbort(stream); + if (holeHandler(stream, holeLen, opaque) < 0) goto cleanup; - } continue; } else if (got < 0) { goto cleanup; @@ -981,10 +972,8 @@ virStreamSparseRecvAll(virStreamPtr stream, while (offset < got) { int done; done =3D (handler)(stream, bytes + offset, got - offset, opaqu= e); - if (done < 0) { - virStreamAbort(stream); + if (done < 0) goto cleanup; - } offset +=3D done; } } @@ -993,8 +982,10 @@ virStreamSparseRecvAll(virStreamPtr stream, cleanup: VIR_FREE(bytes); =20 - if (ret !=3D 0) + if (ret !=3D 0) { + virStreamAbort(stream); virDispatchError(stream->conn); + } =20 return ret; } --=20 2.13.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 17:05:06 2024 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 1496318603317789.1000228210123; Thu, 1 Jun 2017 05:03:23 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2FB3E7FD44; Thu, 1 Jun 2017 12:03:19 +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 03CF77FE8D; Thu, 1 Jun 2017 12:03:19 +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 E53E0396E; Thu, 1 Jun 2017 12:02:55 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v51C2fYi021353 for ; Thu, 1 Jun 2017 08:02:41 -0400 Received: by smtp.corp.redhat.com (Postfix) id 858B21754B; Thu, 1 Jun 2017 12:02:41 +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 067CF17550 for ; Thu, 1 Jun 2017 12:02:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 2FB3E7FD44 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.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 2FB3E7FD44 From: Michal Privoznik To: libvir-list@redhat.com Date: Thu, 1 Jun 2017 14:02:12 +0200 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 4/6] virStream*All: Preserve reported error 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.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 01 Jun 2017 12:03:20 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" If one these four functions fail (virStreamRecvAll, virStreamSendAll, virStreamSparseRecvAll, virStreamSparseSendAll) the stream is aborted by calling virStreamAbort(). This is, however, an public API - therefore the first thing it does is error reset. At that point any error that caused us to abort stream in the first place is gone. Signed-off-by: Michal Privoznik --- src/libvirt-stream.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c index bff0a0571..1594ed212 100644 --- a/src/libvirt-stream.c +++ b/src/libvirt-stream.c @@ -614,7 +614,12 @@ virStreamSendAll(virStreamPtr stream, VIR_FREE(bytes); =20 if (ret !=3D 0) { + virErrorPtr orig_err =3D virSaveLastError(); virStreamAbort(stream); + if (orig_err) { + virSetError(orig_err); + virFreeError(orig_err); + } virDispatchError(stream->conn); } =20 @@ -769,7 +774,12 @@ int virStreamSparseSendAll(virStreamPtr stream, VIR_FREE(bytes); =20 if (ret !=3D 0) { + virErrorPtr orig_err =3D virSaveLastError(); virStreamAbort(stream); + if (orig_err) { + virSetError(orig_err); + virFreeError(orig_err); + } virDispatchError(stream->conn); } =20 @@ -863,7 +873,12 @@ virStreamRecvAll(virStreamPtr stream, VIR_FREE(bytes); =20 if (ret !=3D 0) { + virErrorPtr orig_err =3D virSaveLastError(); virStreamAbort(stream); + if (orig_err) { + virSetError(orig_err); + virFreeError(orig_err); + } virDispatchError(stream->conn); } =20 @@ -983,7 +998,12 @@ virStreamSparseRecvAll(virStreamPtr stream, VIR_FREE(bytes); =20 if (ret !=3D 0) { + virErrorPtr orig_err =3D virSaveLastError(); virStreamAbort(stream); + if (orig_err) { + virSetError(orig_err); + virFreeError(orig_err); + } virDispatchError(stream->conn); } =20 --=20 2.13.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 17:05:06 2024 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 1496318594159384.32220845487086; Thu, 1 Jun 2017 05:03:14 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2393941A29; Thu, 1 Jun 2017 12:03:12 +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 EE1827FE80; Thu, 1 Jun 2017 12:03:11 +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 72DF53944; Thu, 1 Jun 2017 12:02:45 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v51C2hMr021396 for ; Thu, 1 Jun 2017 08:02:43 -0400 Received: by smtp.corp.redhat.com (Postfix) id 9C4241754B; Thu, 1 Jun 2017 12:02:43 +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 22E831755E for ; Thu, 1 Jun 2017 12:02:41 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 2393941A29 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 2393941A29 From: Michal Privoznik To: libvir-list@redhat.com Date: Thu, 1 Jun 2017 14:02:13 +0200 Message-Id: <97b1f939cdb065e71a2417bad23df4e7f5a5b761.1496318427.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 5/6] virsh: Report errors from stream callbacks 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.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 01 Jun 2017 12:03:12 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" There are couple of callbacks we pass to virStreamSendAll(), virStreamRecvAll() or its sparse variants. However, none of these callbacks reports error if one occurs and neither do the virStream* functions leaving user with very unhelpful error message: error: cannot receive data from volume fedora.img error: An error occurred, but the cause is unknown Signed-off-by: Michal Privoznik --- tools/virsh-util.c | 38 +++++++++++++++++++++++++++++--------- tools/virsh-util.h | 2 +- tools/virsh-volume.c | 8 ++++++-- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/tools/virsh-util.c b/tools/virsh-util.c index 44be3ad64..183f4c8bb 100644 --- a/tools/virsh-util.c +++ b/tools/virsh-util.c @@ -147,9 +147,15 @@ virshStreamSink(virStreamPtr st ATTRIBUTE_UNUSED, size_t nbytes, void *opaque) { - int *fd =3D opaque; + virshStreamCallbackDataPtr cbData =3D opaque; + int fd =3D cbData->fd; + const char *filename =3D cbData->filename; + int ret; =20 - return safewrite(*fd, bytes, nbytes); + if ((ret =3D safewrite(fd, bytes, nbytes)) < 0) + virReportSystemError(errno, _("unable to write to %s"), filename); + + return ret; } =20 =20 @@ -161,8 +167,13 @@ virshStreamSource(virStreamPtr st ATTRIBUTE_UNUSED, { virshStreamCallbackDataPtr cbData =3D opaque; int fd =3D cbData->fd; + const char *filename =3D cbData->filename; + int ret; =20 - return saferead(fd, bytes, nbytes); + if ((ret =3D saferead(fd, bytes, nbytes)) < 0) + virReportSystemError(errno, _("unable to read from %s"), filename); + + return ret; } =20 =20 @@ -173,10 +184,13 @@ virshStreamSourceSkip(virStreamPtr st ATTRIBUTE_UNUSE= D, { virshStreamCallbackDataPtr cbData =3D opaque; int fd =3D cbData->fd; + const char *filename =3D cbData->filename; off_t cur; =20 - if ((cur =3D lseek(fd, offset, SEEK_CUR)) =3D=3D (off_t) -1) + if ((cur =3D lseek(fd, offset, SEEK_CUR)) =3D=3D (off_t) -1) { + virReportSystemError(errno, _("unable to seek in %s"), filename); return -1; + } =20 return 0; } @@ -187,14 +201,20 @@ virshStreamSkip(virStreamPtr st ATTRIBUTE_UNUSED, long long offset, void *opaque) { - int *fd =3D opaque; + virshStreamCallbackDataPtr cbData =3D opaque; + int fd =3D cbData->fd; + const char *filename =3D cbData->filename; off_t cur; =20 - if ((cur =3D lseek(*fd, offset, SEEK_CUR)) =3D=3D (off_t) -1) + if ((cur =3D lseek(fd, offset, SEEK_CUR)) =3D=3D (off_t) -1) { + virReportSystemError(errno, _("unable to seek in %s"), filename); return -1; + } =20 - if (ftruncate(*fd, cur) < 0) + if (ftruncate(fd, cur) < 0) { + virReportSystemError(errno, _("unable to truncate %s"), filename); return -1; + } =20 return 0; } @@ -207,12 +227,12 @@ virshStreamInData(virStreamPtr st ATTRIBUTE_UNUSED, void *opaque) { virshStreamCallbackDataPtr cbData =3D opaque; - vshControl *ctl =3D cbData->ctl; int fd =3D cbData->fd; + const char *filename =3D cbData->filename; int ret; =20 if ((ret =3D virFileInData(fd, inData, offset)) < 0) - vshError(ctl, "%s", _("Unable to get current position in stream")); + virReportSystemError(errno, _("unable to seek in %s"), filename); =20 return ret; } diff --git a/tools/virsh-util.h b/tools/virsh-util.h index 9a0af3513..0babb311b 100644 --- a/tools/virsh-util.h +++ b/tools/virsh-util.h @@ -60,8 +60,8 @@ virshStreamSink(virStreamPtr st, typedef struct _virshStreamCallbackData virshStreamCallbackData; typedef virshStreamCallbackData *virshStreamCallbackDataPtr; struct _virshStreamCallbackData { - vshControl *ctl; int fd; + const char *filename; }; =20 int diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c index 0736bdcdb..ea4660fee 100644 --- a/tools/virsh-volume.c +++ b/tools/virsh-volume.c @@ -698,8 +698,8 @@ cmdVolUpload(vshControl *ctl, const vshCmd *cmd) goto cleanup; } =20 - cbData.ctl =3D ctl; cbData.fd =3D fd; + cbData.filename =3D file; =20 if (vshCommandOptBool(cmd, "sparse")) flags |=3D VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM; @@ -795,6 +795,7 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd) bool created =3D false; virshControlPtr priv =3D ctl->privData; unsigned int flags =3D 0; + virshStreamCallbackData cbData; =20 if (vshCommandOptULongLong(ctl, cmd, "offset", &offset) < 0) return false; @@ -821,6 +822,9 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd) created =3D true; } =20 + cbData.fd =3D fd; + cbData.filename =3D file; + if (!(st =3D virStreamNew(priv->conn, 0))) { vshError(ctl, _("cannot create a new stream")); goto cleanup; @@ -831,7 +835,7 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd) goto cleanup; } =20 - if (virStreamSparseRecvAll(st, virshStreamSink, virshStreamSkip, &fd) = < 0) { + if (virStreamSparseRecvAll(st, virshStreamSink, virshStreamSkip, &cbDa= ta) < 0) { vshError(ctl, _("cannot receive data from volume %s"), name); goto cleanup; } --=20 2.13.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 17:05:06 2024 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 1496318593007994.1705354112632; Thu, 1 Jun 2017 05:03:13 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B2DF37FD42; Thu, 1 Jun 2017 12:03:09 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 59ED51755E; Thu, 1 Jun 2017 12:03: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 7320F1869FF4; Thu, 1 Jun 2017 12:02:47 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v51C2jKs021433 for ; Thu, 1 Jun 2017 08:02:45 -0400 Received: by smtp.corp.redhat.com (Postfix) id C8D5F1753C; Thu, 1 Jun 2017 12:02:45 +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 4E0E81754C for ; Thu, 1 Jun 2017 12:02:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com B2DF37FD42 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.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 B2DF37FD42 From: Michal Privoznik To: libvir-list@redhat.com Date: Thu, 1 Jun 2017 14:02:14 +0200 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 6/6] streams: Report errors if sendAll/recvAll callbacks fail 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.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 01 Jun 2017 12:03:10 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" We have couple of wrappers over our low level stream APIs: virSreamRecvAll(), virStreamSendAll() and their sparse stream variants. All of them take some callbacks and call them at appropriate times. If a callback fails it aborts the whole operation. However, if it so happens that the callback fails without setting any error users are left with very unhelpful error message: error: cannot receive data from volume fedora.img error: An error occurred, but the cause is unknown One way to avoid it is to report error if callback hasn't. Signed-off-by: Michal Privoznik --- src/libvirt-stream.c | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c index 1594ed212..efdbc9e44 100644 --- a/src/libvirt-stream.c +++ b/src/libvirt-stream.c @@ -596,8 +596,12 @@ virStreamSendAll(virStreamPtr stream, for (;;) { int got, offset =3D 0; got =3D (handler)(stream, bytes, want, opaque); - if (got < 0) + if (got < 0) { + if (!virGetLastError()) + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("send handler failed")); goto cleanup; + } if (got =3D=3D 0) break; while (offset < got) { @@ -733,16 +737,21 @@ int virStreamSparseSendAll(virStreamPtr stream, const unsigned int skipFlags =3D 0; =20 if (!dataLen) { - if (holeHandler(stream, &inData, §ionLen, opaque) < 0) + if (holeHandler(stream, &inData, §ionLen, opaque) < 0) { + if (!virGetLastError()) + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("send holeHandler failed")); goto cleanup; + } =20 if (!inData && sectionLen) { if (virStreamSendHole(stream, sectionLen, skipFlags) < 0) goto cleanup; =20 if (skipHandler(stream, sectionLen, opaque) < 0) { - virReportSystemError(errno, "%s", - _("unable to skip hole")); + if (!virGetLastError()) + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("send skipHandler failed")); goto cleanup; } continue; @@ -755,8 +764,12 @@ int virStreamSparseSendAll(virStreamPtr stream, want =3D dataLen; =20 got =3D (handler)(stream, bytes, want, opaque); - if (got < 0) + if (got < 0) { + if (!virGetLastError()) + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("send handler failed")); goto cleanup; + } if (got =3D=3D 0) break; while (offset < got) { @@ -862,8 +875,12 @@ 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 (!virGetLastError()) + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("receive handler failed")); goto cleanup; + } offset +=3D done; } } @@ -976,8 +993,12 @@ virStreamSparseRecvAll(virStreamPtr stream, if (virStreamRecvHole(stream, &holeLen, holeFlags) < 0) goto cleanup; =20 - if (holeHandler(stream, holeLen, opaque) < 0) + if (holeHandler(stream, holeLen, opaque) < 0) { + if (!virGetLastError()) + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("receive holeHandler failed")); goto cleanup; + } continue; } else if (got < 0) { goto cleanup; @@ -987,8 +1008,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 (!virGetLastError()) + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("receive 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