From nobody Mon Dec 15 23:28:17 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.zohomail.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 15108461312271023.8811407530443; Thu, 16 Nov 2017 07:28:51 -0800 (PST) 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 00E4A80F90; Thu, 16 Nov 2017 15:28: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 D02378B122; Thu, 16 Nov 2017 15:28: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 96BA21800C87; Thu, 16 Nov 2017 15:28:49 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id vAGFRqml030631 for ; Thu, 16 Nov 2017 10:27:52 -0500 Received: by smtp.corp.redhat.com (Postfix) id 9B3D85DD6D; Thu, 16 Nov 2017 15:27:52 +0000 (UTC) Received: from mx1.redhat.com (ext-mx05.extmail.prod.ext.phx2.redhat.com [10.5.110.29]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 951A42A317 for ; Thu, 16 Nov 2017 15:27:49 +0000 (UTC) Received: from relay.sw.ru (mailhub.sw.ru [195.214.232.25]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 629EEC9D2C for ; Thu, 16 Nov 2017 15:27:48 +0000 (UTC) Received: from dim-vz7.qa.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id vAGF4roL024290 for ; Thu, 16 Nov 2017 18:04:54 +0300 (MSK) From: Nikolay Shirokovskiy To: libvir-list@redhat.com Date: Thu, 16 Nov 2017 18:04:31 +0300 Message-Id: <1510844672-47857-3-git-send-email-nshirokovskiy@virtuozzo.com> In-Reply-To: <1510844672-47857-1-git-send-email-nshirokovskiy@virtuozzo.com> References: <1510844672-47857-1-git-send-email-nshirokovskiy@virtuozzo.com> X-Greylist: Delayed for 00:22:44 by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Thu, 16 Nov 2017 15:27:49 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Thu, 16 Nov 2017 15:27:49 +0000 (UTC) for IP:'195.214.232.25' DOMAIN:'mailhub.sw.ru' HELO:'relay.sw.ru' FROM:'nshirokovskiy@virtuozzo.com' RCPT:'' X-RedHat-Spam-Score: -0.001 (SPF_PASS) 195.214.232.25 mailhub.sw.ru 195.214.232.25 mailhub.sw.ru X-Scanned-By: MIMEDefang 2.78 on 10.5.110.29 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 2/3] util: add 30s connection timeout to virFDStreamConnectUNIX 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, 16 Nov 2017 15:28:50 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" There is a bug in qemu currently on hanling agent channels. As a result if you open agent channel for guest without running an agent several times in raw you get hang on connect syscall eventually. Qemu will be fixed eventually but it is nice to handle hanging connect condition in libvirt. Let's add 30s connect timeout. --- src/util/virfdstream.c | 17 +++++++++++++++ src/util/virutil.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++= ++++ src/util/virutil.h | 2 ++ 3 files changed, 78 insertions(+) diff --git a/src/util/virfdstream.c b/src/util/virfdstream.c index 1d064a7..029cc4e 100644 --- a/src/util/virfdstream.c +++ b/src/util/virfdstream.c @@ -1176,6 +1176,11 @@ int virFDStreamConnectUNIX(virStreamPtr st, goto error; } =20 + if (virSetNonBlock(fd) < 0) { + virReportSystemError(errno, "%s", _("Unable to set non-blocking mo= de")); + goto error; + } + if (virTimeBackOffStart(&timeout, 1, 3*1000 /* ms */) < 0) goto error; while (virTimeBackOffWait(&timeout)) { @@ -1189,10 +1194,22 @@ int virFDStreamConnectUNIX(virStreamPtr st, continue; } =20 + if (errno =3D=3D EINPROGRESS || errno =3D=3D EAGAIN) { + if (virConnectWait(fd, 30 * 1000) < 0) + goto error; + + break; + } + virReportSystemError(errno, "%s", _("Unable to connect to UNIX soc= ket")); goto error; } =20 + if (virSetBlocking(fd, true) < 0) { + virReportSystemError(errno, "%s", _("Unable to set blocking mode")= ); + goto error; + } + if (virFDStreamOpenInternal(st, fd, NULL, 0) < 0) goto error; return 0; diff --git a/src/util/virutil.c b/src/util/virutil.c index 8bdcb02..75abd4f 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -80,6 +80,7 @@ #include "nonblocking.h" #include "virprocess.h" #include "virstring.h" +#include "virtime.h" #include "virutil.h" =20 verify(sizeof(gid_t) <=3D sizeof(unsigned int) && @@ -195,6 +196,64 @@ int virSetSockReuseAddr(int fd, bool fatal) #endif =20 int +virConnectWait(int fd, unsigned long long timeout) +{ + struct pollfd fds[1]; + unsigned long long then; + unsigned long long now; + int rc; + int optval; + socklen_t optlen =3D sizeof(optval); + + fds[0].fd =3D fd; + fds[0].events =3D POLLOUT; + fds[0].revents =3D 0; + + if (virTimeMillisNow(&now) < 0) + return -1; + + then =3D now + timeout; + + retry: + rc =3D poll(fds, 1, then - now); + + if (rc < 0 && (errno =3D=3D EAGAIN || errno =3D=3D EINTR)) { + if (virTimeMillisNow(&now) < 0) + return -1; + + if (now >=3D then) { + virReportError(VIR_ERR_OPERATION_TIMEOUT, "%s", + _("Connection timeout expired")); + return -1; + } + + goto retry; + } + + if (rc < 0) { + virReportSystemError(errno, "%s", _("Unable to connect to socket")= ); + return -1; + } else if (rc =3D=3D 0) { + virReportError(VIR_ERR_OPERATION_TIMEOUT, "%s", + _("Connection timeout expired")); + return -1; + } + + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &optval, &optlen) < 0) { + virReportSystemError(errno, "%s", + _("Cannot check socket connection status")); + return -1; + } + + if (optval !=3D 0) { + virReportSystemError(optval, "%s", _("Unable to connect to socket"= )); + return -1; + } + + return 0; +} + +int virPipeReadUntilEOF(int outfd, int errfd, char **outbuf, char **errbuf) { =20 diff --git a/src/util/virutil.h b/src/util/virutil.h index ff89d1a..b0c9672 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -43,6 +43,8 @@ int virSetInherit(int fd, bool inherit) ATTRIBUTE_RETURN_= CHECK; int virSetCloseExec(int fd) ATTRIBUTE_RETURN_CHECK; int virSetSockReuseAddr(int fd, bool fatal) ATTRIBUTE_RETURN_CHECK; =20 +int virConnectWait(int fd, unsigned long long timeout); + int virPipeReadUntilEOF(int outfd, int errfd, char **outbuf, char **errbuf); =20 --=20 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list