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 <pkrempa(a)redhat.com>
---
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 10feb606ad..4301f3f89e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6794,7 +6794,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,
--
2.31.1