From nobody Wed May 14 01:26:40 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; 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 1526564470433986.1382281757758; Thu, 17 May 2018 06:41:10 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6FEE830D264B; Thu, 17 May 2018 13:41:08 +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 0908D94351; Thu, 17 May 2018 13:41:08 +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 A1EE14CAA7; Thu, 17 May 2018 13:41:07 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w4HDer2v007145 for ; Thu, 17 May 2018 09:40:53 -0400 Received: by smtp.corp.redhat.com (Postfix) id 6BACD10B2B4F; Thu, 17 May 2018 13:40:53 +0000 (UTC) Received: from t460.redhat.com (unknown [10.33.36.69]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6389F10B2B4E; Thu, 17 May 2018 13:40:52 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Thu, 17 May 2018 14:40:44 +0100 Message-Id: <20180517134045.21610-4-berrange@redhat.com> In-Reply-To: <20180517134045.21610-1-berrange@redhat.com> References: <20180517134045.21610-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 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.84 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Thu, 17 May 2018 13:41:09 +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. Reviewed-by: John Ferlan Signed-off-by: Daniel P. Berrang=C3=A9 --- 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 9a2b976e46..2d6776ab4a 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -4175,7 +4175,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 3d7ca3ccfc..ef1f7321b2 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -341,6 +341,7 @@ qemuMonitorDispose(void *obj) static int qemuMonitorOpenUnix(const char *monitor, pid_t cpid, + bool retry, unsigned long long timeout) { struct sockaddr_un addr; @@ -362,31 +363,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; @@ -906,6 +915,7 @@ qemuMonitorPtr qemuMonitorOpen(virDomainObjPtr vm, virDomainChrSourceDefPtr config, bool json, + bool retry, unsigned long long timeout, qemuMonitorCallbacksPtr cb, void *opaque) @@ -920,7 +930,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 33dc521e83..5821847f5a 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 5b73a61962..84b66521fa 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1772,7 +1772,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; @@ -1803,6 +1803,7 @@ qemuConnectMonitor(virQEMUDriverPtr driver, virDomain= ObjPtr vm, int asyncJob, mon =3D qemuMonitorOpen(vm, monConfig, priv->monJSON, + retry, timeout, &monitorCallbacks, driver); @@ -2180,17 +2181,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); @@ -7468,6 +7475,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 @@ -7498,10 +7506,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 62f68ee699..789eb72196 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.17.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list