From nobody Fri May 3 08:44:11 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.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; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1524072627817329.21630810537886; Wed, 18 Apr 2018 10:30:27 -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 41ECF81DE2; Wed, 18 Apr 2018 17:30:26 +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 10E4E82DDA; Wed, 18 Apr 2018 17:30:26 +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 7574D18033EB; Wed, 18 Apr 2018 17:30:25 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w3IHULMp004498 for ; Wed, 18 Apr 2018 13:30:21 -0400 Received: by smtp.corp.redhat.com (Postfix) id 90DFC50330; Wed, 18 Apr 2018 17:30:21 +0000 (UTC) Received: from t460.redhat.com (unknown [10.33.36.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id EEB401DB27; Wed, 18 Apr 2018 17:30:20 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Wed, 18 Apr 2018 18:30:14 +0100 Message-Id: <20180418173017.7346-2-berrange@redhat.com> In-Reply-To: <20180418173017.7346-1-berrange@redhat.com> References: <20180418173017.7346-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 1/4] qemu: probe for -chardev 'fd' parameter for FD passing 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: , Content-Type: text/plain; charset="utf-8" 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.25]); Wed, 18 Apr 2018 17:30:26 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 QEMU >=3D 2.12 will support passing of pre-opened file descriptors for socket based character devices. Reviewed-by: John Ferlan Signed-off-by: Daniel P. Berrang=C3=A9 --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml | 1 + tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml | 1 + 6 files changed, 7 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 4fb586f1d9..59bae67945 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -468,6 +468,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "virtio-tablet-ccw", "qcow2-luks", "pcie-pci-bridge", + "chardev-fd-pass", ); =20 =20 @@ -2425,6 +2426,7 @@ static struct virQEMUCapsCommandLineProps virQEMUCaps= CommandLine[] =3D { { "machine", "loadparm", QEMU_CAPS_LOADPARM }, { "vnc", "vnc", QEMU_CAPS_VNC_MULTI_SERVERS }, { "chardev", "reconnect", QEMU_CAPS_CHARDEV_RECONNECT }, + { "chardev", "fd", QEMU_CAPS_CHARDEV_FD_PASS }, }; =20 static int diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 2f15da0729..53de5dff9b 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -452,6 +452,7 @@ typedef enum { QEMU_CAPS_DEVICE_VIRTIO_TABLET_CCW, /* -device virtio-tablet-ccw */ QEMU_CAPS_QCOW2_LUKS, /* qcow2 format support LUKS encryption */ QEMU_CAPS_DEVICE_PCIE_PCI_BRIDGE, /* -device pcie-pci-bridge */ + QEMU_CAPS_CHARDEV_FD_PASS, /* Passing pre-opened FDs for chardevs */ =20 QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml b/tests/qem= ucapabilitiesdata/caps_2.12.0.aarch64.xml index 1eadfb6cc0..c733de7700 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml @@ -180,6 +180,7 @@ + 2011090 0 342346 diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml b/tests/qemuc= apabilitiesdata/caps_2.12.0.ppc64.xml index 34f5567146..c64ea44d4f 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml @@ -177,6 +177,7 @@ + 2011090 0 419215 diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml b/tests/qemuc= apabilitiesdata/caps_2.12.0.s390x.xml index bd675a946f..c5c48eb07c 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml @@ -142,6 +142,7 @@ + 2011090 0 0 diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml b/tests/qemu= capabilitiesdata/caps_2.12.0.x86_64.xml index 821ddca4f5..33867499ae 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml @@ -218,6 +218,7 @@ + 2011090 0 390060 --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Fri May 3 08:44:11 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.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; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1524072627089474.6269756472743; Wed, 18 Apr 2018 10:30:27 -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 7E2F231327DD; Wed, 18 Apr 2018 17:30:25 +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 505FD808D2; Wed, 18 Apr 2018 17:30:25 +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 EECC5180215F; Wed, 18 Apr 2018 17:30:24 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w3IHUMEF004508 for ; Wed, 18 Apr 2018 13:30:22 -0400 Received: by smtp.corp.redhat.com (Postfix) id 666E950330; Wed, 18 Apr 2018 17:30:22 +0000 (UTC) Received: from t460.redhat.com (unknown [10.33.36.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id C961663529; Wed, 18 Apr 2018 17:30:21 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Wed, 18 Apr 2018 18:30:15 +0100 Message-Id: <20180418173017.7346-3-berrange@redhat.com> In-Reply-To: <20180418173017.7346-1-berrange@redhat.com> References: <20180418173017.7346-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 2/4] qemu: support passing pre-opened UNIX socket listen FD 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: , Content-Type: text/plain; charset="utf-8" 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.47]); Wed, 18 Apr 2018 17:30:25 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 There is a race condition when spawning QEMU where libvirt has spawned QEMU but the monitor socket is not yet open. Libvirt has to repeatedly try to connect() to QEMU's monitor until eventually it succeeds, or times out. We use kill() to check if QEMU is still alive so we avoid waiting a long time if QEMU exited, but having a timeout at all is still unpleasant. With QEMU 2.12 we can pass in a pre-opened FD for UNIX domain or TCP sockets. If libvirt has called bind() and listen() on this FD, then we have a guarantee that libvirt can immediately call connect() and succeed without any race. Although we only really care about this for the monitor socket and agent socket, this patch does FD passing for all UNIX socket based character devices since there appears to be no downside to it. We don't do FD passing for TCP sockets, however, because it is only possible to pass a single FD, while some hostnames may require listening on multiple FDs to cover IPv4 and IPv6 concurrently. Reviewed-by: John Ferlan Signed-off-by: Daniel P. Berrang=C3=A9 --- src/qemu/qemu_command.c | 54 +++++++++++++++++++++++++++++++++++++++++++++= ++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 0c109c63e7..9fc48eb829 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5034,8 +5034,58 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager, break; =20 case VIR_DOMAIN_CHR_TYPE_UNIX: - virBufferAsprintf(&buf, "socket,id=3D%s,path=3D", charAlias); - virQEMUBuildBufferEscapeComma(&buf, dev->data.nix.path); + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_FD_PASS)) { + struct sockaddr_un addr; + socklen_t addrlen =3D sizeof(addr); + int fd; + + if ((fd =3D socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { + virReportSystemError(errno, "%s", + _("Unable to create UNIX socket")); + goto cleanup; + } + + memset(&addr, 0, sizeof(addr)); + addr.sun_family =3D AF_UNIX; + if (virStrcpyStatic(addr.sun_path, dev->data.nix.path) =3D=3D = NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("UNIX socket path '%s' too long"), + dev->data.nix.path); + VIR_FORCE_CLOSE(fd); + goto cleanup; + } + + if (unlink(dev->data.nix.path) < 0 && errno !=3D ENOENT) { + virReportSystemError(errno, + _("Unable to unlink %s"), + dev->data.nix.path); + VIR_FORCE_CLOSE(fd); + goto cleanup; + } + + if (bind(fd, (struct sockaddr *)&addr, addrlen) < 0) { + virReportSystemError(errno, + _("Unable to bind to UNIX socket path= '%s'"), + dev->data.nix.path); + VIR_FORCE_CLOSE(fd); + goto cleanup; + } + + if (listen(fd, 1) < 0) { + virReportSystemError(errno, + _("Unable to listen to UNIX socket pa= th '%s'"), + dev->data.nix.path); + VIR_FORCE_CLOSE(fd); + goto cleanup; + } + + virBufferAsprintf(&buf, "socket,id=3D%s,fd=3D%d", charAlias, f= d); + + virCommandPassFD(cmd, fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); + } else { + virBufferAsprintf(&buf, "socket,id=3D%s,path=3D", charAlias); + virQEMUBuildBufferEscapeComma(&buf, dev->data.nix.path); + } if (dev->data.nix.listen) virBufferAdd(&buf, nowait ? ",server,nowait" : ",server", -1); =20 --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Fri May 3 08:44:11 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.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; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1524072632327861.0535999618619; Wed, 18 Apr 2018 10:30:32 -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 743F93182F3B; Wed, 18 Apr 2018 17:30:30 +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 3D63C7DFC5; Wed, 18 Apr 2018 17:30:30 +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 CA7324CA9C; Wed, 18 Apr 2018 17:30:29 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w3IHUNmA004518 for ; Wed, 18 Apr 2018 13:30:23 -0400 Received: by smtp.corp.redhat.com (Postfix) id 3E0B250332; Wed, 18 Apr 2018 17:30:23 +0000 (UTC) Received: from t460.redhat.com (unknown [10.33.36.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9F8031DB20; Wed, 18 Apr 2018 17:30:22 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Wed, 18 Apr 2018 18:30:16 +0100 Message-Id: <20180418173017.7346-4-berrange@redhat.com> In-Reply-To: <20180418173017.7346-1-berrange@redhat.com> References: <20180418173017.7346-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 3/4] qemu: don't retry connect() if doing FD passing 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: , Content-Type: text/plain; charset="utf-8" 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.49]); Wed, 18 Apr 2018 17:30:31 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Since libvirt called bind() and listen() on the UNIX socket, it is guaranteed that connect() will immediately succeed, if QEMU is running normally. It will only fail if QEMU has closed the monitor socket by mistake or if QEMU has exited, letting the kernel close it. With this in mind we can remove the retry loop and timeout when connecting to the QEMU monitor if we are doing FD passing. Libvirt can go straight to sending the QMP greeting and will simply block waiting for a reply until QEMU is ready. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: John Ferlan --- src/qemu/qemu_capabilities.c | 2 +- src/qemu/qemu_monitor.c | 54 ++++++++++++++++++++++++++--------------= ---- src/qemu/qemu_monitor.h | 1 + src/qemu/qemu_process.c | 27 ++++++++++++++++------ tests/qemumonitortestutils.c | 1 + 5 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 59bae67945..f27d0544ff 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -4128,7 +4128,7 @@ virQEMUCapsInitQMPCommandRun(virQEMUCapsInitQMPComman= dPtr cmd, =20 cmd->vm->pid =3D cmd->pid; =20 - if (!(cmd->mon =3D qemuMonitorOpen(cmd->vm, &cmd->config, true, + if (!(cmd->mon =3D qemuMonitorOpen(cmd->vm, &cmd->config, true, true, 0, &callbacks, NULL))) goto ignore; =20 diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 22f05222db..130490bde8 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -349,6 +349,7 @@ qemuMonitorDispose(void *obj) static int qemuMonitorOpenUnix(const char *monitor, pid_t cpid, + bool retry, unsigned long long timeout) { struct sockaddr_un addr; @@ -370,31 +371,39 @@ qemuMonitorOpenUnix(const char *monitor, goto error; } =20 - if (virTimeBackOffStart(&timebackoff, 1, timeout * 1000) < 0) - goto error; - while (virTimeBackOffWait(&timebackoff)) { - ret =3D connect(monfd, (struct sockaddr *) &addr, sizeof(addr)); - - if (ret =3D=3D 0) - break; + if (retry) { + if (virTimeBackOffStart(&timebackoff, 1, timeout * 1000) < 0) + goto error; + while (virTimeBackOffWait(&timebackoff)) { + ret =3D connect(monfd, (struct sockaddr *) &addr, sizeof(addr)= ); =20 - if ((errno =3D=3D ENOENT || errno =3D=3D ECONNREFUSED) && - (!cpid || virProcessKill(cpid, 0) =3D=3D 0)) { - /* ENOENT : Socket may not have shown up yet - * ECONNREFUSED : Leftover socket hasn't been removed yet */ - continue; - } + if (ret =3D=3D 0) + break; =20 - virReportSystemError(errno, "%s", - _("failed to connect to monitor socket")); - goto error; + if ((errno =3D=3D ENOENT || errno =3D=3D ECONNREFUSED) && + (!cpid || virProcessKill(cpid, 0) =3D=3D 0)) { + /* ENOENT : Socket may not have shown up yet + * ECONNREFUSED : Leftover socket hasn't been removed yet = */ + continue; + } =20 - } + virReportSystemError(errno, "%s", + _("failed to connect to monitor socket")); + goto error; + } =20 - if (ret !=3D 0) { - virReportSystemError(errno, "%s", - _("monitor socket did not show up")); - goto error; + if (ret !=3D 0) { + virReportSystemError(errno, "%s", + _("monitor socket did not show up")); + goto error; + } + } else { + ret =3D connect(monfd, (struct sockaddr *) &addr, sizeof(addr)); + if (ret < 0) { + virReportSystemError(errno, "%s", + _("failed to connect to monitor socket")); + goto error; + } } =20 return monfd; @@ -914,6 +923,7 @@ qemuMonitorPtr qemuMonitorOpen(virDomainObjPtr vm, virDomainChrSourceDefPtr config, bool json, + bool retry, unsigned long long timeout, qemuMonitorCallbacksPtr cb, void *opaque) @@ -928,7 +938,7 @@ qemuMonitorOpen(virDomainObjPtr vm, case VIR_DOMAIN_CHR_TYPE_UNIX: hasSendFD =3D true; if ((fd =3D qemuMonitorOpenUnix(config->data.nix.path, - vm->pid, timeout)) < 0) + vm->pid, retry, timeout)) < 0) return NULL; break; =20 diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 9556a51341..c539c41b1d 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -320,6 +320,7 @@ char *qemuMonitorUnescapeArg(const char *in); qemuMonitorPtr qemuMonitorOpen(virDomainObjPtr vm, virDomainChrSourceDefPtr config, bool json, + bool retry, unsigned long long timeout, qemuMonitorCallbacksPtr cb, void *opaque) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index d0adc8aa3b..3c8718676d 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1771,7 +1771,7 @@ qemuProcessInitMonitor(virQEMUDriverPtr driver, =20 static int qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJ= ob, - qemuDomainLogContextPtr logCtxt) + bool retry, qemuDomainLogContextPtr logCtxt) { qemuDomainObjPrivatePtr priv =3D vm->privateData; qemuMonitorPtr mon =3D NULL; @@ -1802,6 +1802,7 @@ qemuConnectMonitor(virQEMUDriverPtr driver, virDomain= ObjPtr vm, int asyncJob, mon =3D qemuMonitorOpen(vm, monConfig, priv->monJSON, + retry, timeout, &monitorCallbacks, driver); @@ -2179,17 +2180,23 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver, { int ret =3D -1; virHashTablePtr info =3D NULL; - qemuDomainObjPrivatePtr priv; + qemuDomainObjPrivatePtr priv =3D vm->privateData; + bool retry =3D true; + + if (priv->qemuCaps && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CHARDEV_FD_PASS)) + retry =3D false; =20 - VIR_DEBUG("Connect monitor to %p '%s'", vm, vm->def->name); - if (qemuConnectMonitor(driver, vm, asyncJob, logCtxt) < 0) + VIR_DEBUG("Connect monitor to vm=3D%p name=3D'%s' retry=3D%d", + vm, vm->def->name, retry); + + if (qemuConnectMonitor(driver, vm, asyncJob, retry, logCtxt) < 0) goto cleanup; =20 /* Try to get the pty path mappings again via the monitor. This is muc= h more * reliable if it's available. * Note that the monitor itself can be on a pty, so we still need to t= ry the * log output method. */ - priv =3D vm->privateData; if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) goto cleanup; ret =3D qemuMonitorGetChardevInfo(priv->mon, &info); @@ -7263,6 +7270,7 @@ qemuProcessReconnect(void *opaque) unsigned int stopFlags =3D 0; bool jobStarted =3D false; virCapsPtr caps =3D NULL; + bool retry =3D true; =20 VIR_FREE(data); =20 @@ -7293,10 +7301,15 @@ qemuProcessReconnect(void *opaque) * allowReboot in status XML and we need to initialize it. */ qemuProcessPrepareAllowReboot(obj); =20 - VIR_DEBUG("Reconnect monitor to %p '%s'", obj, obj->def->name); + if (priv->qemuCaps && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CHARDEV_FD_PASS)) + retry =3D false; + + VIR_DEBUG("Reconnect monitor to def=3D%p name=3D'%s' retry=3D%d", + obj, obj->def->name, retry); =20 /* XXX check PID liveliness & EXE path */ - if (qemuConnectMonitor(driver, obj, QEMU_ASYNC_JOB_NONE, NULL) < 0) + if (qemuConnectMonitor(driver, obj, QEMU_ASYNC_JOB_NONE, retry, NULL) = < 0) goto error; =20 if (qemuHostdevUpdateActiveDomainDevices(driver, obj->def) < 0) diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index 66bccac9a4..9808e972c8 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -1252,6 +1252,7 @@ qemuMonitorTestNew(bool json, if (!(test->mon =3D qemuMonitorOpen(test->vm, &src, json, + true, 0, &qemuMonitorTestCallbacks, driver))) --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Fri May 3 08:44:11 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.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; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1524072636764907.510495744798; Wed, 18 Apr 2018 10:30:36 -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 53E753004411; Wed, 18 Apr 2018 17:30:35 +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 DFF2C81299; Wed, 18 Apr 2018 17:30:34 +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 7F157180BAD5; Wed, 18 Apr 2018 17:30:34 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w3IHUOCv004525 for ; Wed, 18 Apr 2018 13:30:24 -0400 Received: by smtp.corp.redhat.com (Postfix) id 13EF250332; Wed, 18 Apr 2018 17:30:24 +0000 (UTC) Received: from t460.redhat.com (unknown [10.33.36.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 769B650330; Wed, 18 Apr 2018 17:30:23 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Wed, 18 Apr 2018 18:30:17 +0100 Message-Id: <20180418173017.7346-5-berrange@redhat.com> In-Reply-To: <20180418173017.7346-1-berrange@redhat.com> References: <20180418173017.7346-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 4/4] qemu: remove pointless connect retry logic in agent 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: , Content-Type: text/plain; charset="utf-8" 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.49]); Wed, 18 Apr 2018 17:30:35 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 When the agent code was first introduced back in commit c160ce3316852a797d7b06b4ee101233866e69a9 Author: Daniel P. Berrange Date: Wed Oct 5 18:31:54 2011 +0100 QEMU guest agent support there was code that would loop and retry the connection when opening the agent socket. At this time, the only thing done in between the opening of the monitor socket & opening of the agent socket was a call to set the monitor capabilities. This was a no-op on non-QMP versions, so in theory there could be a race which let us connect to the monitor while the agent socket was still not created by QEMU. In the modern world, however, we long ago mandated the use of QMP for managing QEMU, so we're guaranteed to have a set capabilities QMP call. Once we've seen a reply to this, we're guaranteed that QEMU has fully initialized all backends and is in its event loop. We can thus be sure the QEMU agent socket is present and don't need to retry connections to it, even without having the chardev FD passing feature. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: John Ferlan --- src/qemu/qemu_agent.c | 84 +++++------------------------------------------= ---- 1 file changed, 7 insertions(+), 77 deletions(-) diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index 85af53d194..a68c1e3897 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -106,7 +106,6 @@ struct _qemuAgent { int fd; int watch; =20 - bool connectPending; bool running; =20 virDomainObjPtr vm; @@ -183,15 +182,12 @@ static void qemuAgentDispose(void *obj) } =20 static int -qemuAgentOpenUnix(const char *monitor, pid_t cpid, bool *inProgress) +qemuAgentOpenUnix(const char *monitor) { struct sockaddr_un addr; int monfd; - virTimeBackOffVar timeout; int ret =3D -1; =20 - *inProgress =3D false; - if ((monfd =3D socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { virReportSystemError(errno, "%s", _("failed to create socket")); @@ -220,39 +216,11 @@ qemuAgentOpenUnix(const char *monitor, pid_t cpid, bo= ol *inProgress) goto error; } =20 - if (virTimeBackOffStart(&timeout, 1, 3*1000 /* ms */) < 0) - goto error; - while (virTimeBackOffWait(&timeout)) { - ret =3D connect(monfd, (struct sockaddr *) &addr, sizeof(addr)); - - if (ret =3D=3D 0) - break; - - if ((errno =3D=3D ENOENT || errno =3D=3D ECONNREFUSED) && - virProcessKill(cpid, 0) =3D=3D 0) { - /* ENOENT : Socket may not have shown up yet - * ECONNREFUSED : Leftover socket hasn't been removed yet */ - continue; - } - - if ((errno =3D=3D EINPROGRESS) || - (errno =3D=3D EAGAIN)) { - VIR_DEBUG("Connection attempt continuing in background"); - *inProgress =3D true; - ret =3D 0; - break; - } - + ret =3D connect(monfd, (struct sockaddr *) &addr, sizeof(addr)); + if (ret < 0) { virReportSystemError(errno, "%s", _("failed to connect to monitor socket")); goto error; - - } - - if (ret !=3D 0) { - virReportSystemError(errno, "%s", - _("monitor socket did not show up")); - goto error; } =20 return monfd; @@ -473,35 +441,6 @@ qemuAgentIOProcess(qemuAgentPtr mon) } =20 =20 -static int -qemuAgentIOConnect(qemuAgentPtr mon) -{ - int optval; - socklen_t optlen; - - VIR_DEBUG("Checking on background connection status"); - - mon->connectPending =3D false; - - optlen =3D sizeof(optval); - - if (getsockopt(mon->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", - _("Cannot connect to agent socket")); - return -1; - } - - VIR_DEBUG("Agent is now connected"); - return 0; -} - /* * Called when the monitor is able to write data * Call this function while holding the monitor lock. @@ -633,13 +572,8 @@ qemuAgentIO(int watch, int fd, int events, void *opaqu= e) error =3D true; } else { if (events & VIR_EVENT_HANDLE_WRITABLE) { - if (mon->connectPending) { - if (qemuAgentIOConnect(mon) < 0) - error =3D true; - } else { - if (qemuAgentIOWrite(mon) < 0) - error =3D true; - } + if (qemuAgentIOWrite(mon) < 0) + error =3D true; events &=3D ~VIR_EVENT_HANDLE_WRITABLE; } =20 @@ -771,8 +705,7 @@ qemuAgentOpen(virDomainObjPtr vm, =20 switch (config->type) { case VIR_DOMAIN_CHR_TYPE_UNIX: - mon->fd =3D qemuAgentOpenUnix(config->data.nix.path, vm->pid, - &mon->connectPending); + mon->fd =3D qemuAgentOpenUnix(config->data.nix.path); break; =20 case VIR_DOMAIN_CHR_TYPE_PTY: @@ -793,10 +726,7 @@ qemuAgentOpen(virDomainObjPtr vm, if ((mon->watch =3D virEventAddHandle(mon->fd, VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR | - VIR_EVENT_HANDLE_READABLE | - (mon->connectPending ? - VIR_EVENT_HANDLE_WRITABLE : - 0), + VIR_EVENT_HANDLE_READABLE, qemuAgentIO, mon, virObjectFreeCallback)) < 0) { --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list