From nobody Wed May 14 08:05:00 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 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