From 5b7a777bc8b6f5e310695ef228a1bec0e67e9cc2 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Wed, 3 Nov 2021 14:12:16 +0100 Subject: [PATCH] qemu: Store chardev 'wait' flag in chardev source private data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have just one case when we wish to wait for incomming connections for a listening socket and that is for vhost-user network devices. Passing this via a flag to qemuBuildChrChardevStr is unwieldy. Add a field to qemuDomainChrSourcePrivate and populate it for our special case inside of qemuDomainPrepareChardevSourceOne. Since we wait for incomming connections only on startup of a new VM we also need to pass in a flag whether qemuDomainPrepareChardevSourceOne is called on a new start or on hotplug. Signed-off-by: Peter Krempa Reviewed-by: Ján Tomko --- src/qemu/qemu_command.c | 6 +++--- src/qemu/qemu_domain.c | 8 +++++++- src/qemu/qemu_domain.h | 2 ++ src/qemu/qemu_driver.c | 3 ++- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index b637cd2bf5..0baf3acde6 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5051,7 +5051,7 @@ qemuBuildChrChardevStr(virLogManager *logManager G_GNUC_UNUSED, const virDomainChrSourceDef *dev, const char *alias, virQEMUCaps *qemuCaps, - unsigned int cdevflags) + unsigned int cdevflags G_GNUC_UNUSED) { qemuDomainChrSourcePrivate *chrSourcePriv = QEMU_DOMAIN_CHR_SOURCE_PRIVATE(dev); g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; @@ -5148,7 +5148,7 @@ qemuBuildChrChardevStr(virLogManager *logManager G_GNUC_UNUSED, if (dev->data.tcp.listen) { virBufferAddLit(&buf, ",server=on"); - if (cdevflags & QEMU_BUILD_CHARDEV_TCP_NOWAIT) + if (!chrSourcePriv->wait) virBufferAddLit(&buf, ",wait=off"); } @@ -5199,7 +5199,7 @@ qemuBuildChrChardevStr(virLogManager *logManager G_GNUC_UNUSED, } if (dev->data.nix.listen) { virBufferAddLit(&buf, ",server=on"); - if (cdevflags & QEMU_BUILD_CHARDEV_TCP_NOWAIT) + if (!chrSourcePriv->wait) virBufferAddLit(&buf, ",wait=off"); } diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 550afca36e..e6d6bf10f1 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -9735,6 +9735,7 @@ qemuDomainPrepareChardevSourceOne(virDomainDeviceDef *dev, void *opaque) { struct qemuDomainPrepareChardevSourceData *data = opaque; + qemuDomainChrSourcePrivate *charpriv = QEMU_DOMAIN_CHR_SOURCE_PRIVATE(charsrc); switch ((virDomainDeviceType) dev->type) { @@ -9750,8 +9751,13 @@ qemuDomainPrepareChardevSourceOne(virDomainDeviceDef *dev, } break; - case VIR_DOMAIN_DEVICE_DISK: case VIR_DOMAIN_DEVICE_NET: + /* when starting a fresh VM, vhost-user network sockets wait for connection */ + if (!data->hotplug) + charpriv->wait = true; + break; + + case VIR_DOMAIN_DEVICE_DISK: case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_FS: diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index f84acf408b..2d93cf2253 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -344,6 +344,7 @@ struct _qemuDomainChrSourcePrivate { int fd; /* file descriptor of the chardev source */ int logfd; /* file descriptor of the logging source */ + bool wait; /* wait for incomming connections on chardev */ }; @@ -866,6 +867,7 @@ int qemuDomainPrepareChannel(virDomainChrDef *chr, struct qemuDomainPrepareChardevSourceData { virQEMUDriverConfig *cfg; + bool hotplug; }; int diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 829f1bae9f..e444ad2d45 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6777,7 +6777,8 @@ qemuDomainAttachDeviceLive(virDomainObj *vm, int ret = -1; const char *alias = NULL; g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); - struct qemuDomainPrepareChardevSourceData chardevBackendData = { .cfg = cfg }; + struct qemuDomainPrepareChardevSourceData chardevBackendData = { .cfg = cfg, + .hotplug = true }; if (qemuDomainDeviceBackendChardevForeachOne(dev, qemuDomainPrepareChardevSourceOne,