Build the properties of 'vhost-vsock' device via JSON. In comparison to previous similar refactors this also modifies the hotplug code to attach the vhost fd handle explicitly rather than using 'qemuMonitorAddDeviceWithFd'. The properties of vhost-vsock have the following types according to QEMU: guest-cid=<uint64> - (default: 0) vhostfd=<str> Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- src/qemu/qemu_command.c | 36 ++++++++++++++++++++---------------- src/qemu/qemu_command.h | 12 +++++------- src/qemu/qemu_hotplug.c | 21 ++++++++++++++++----- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a92bdd62f9..c566ab7bd5 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -10553,27 +10553,30 @@ qemuBuildSeccompSandboxCommandLine(virCommand *cmd, } -char * -qemuBuildVsockDevStr(virDomainDef *def, - virDomainVsockDef *vsock, - virQEMUCaps *qemuCaps, - const char *fdprefix) +virJSONValue * +qemuBuildVsockDevProps(virDomainDef *def, + virDomainVsockDef *vsock, + virQEMUCaps *qemuCaps, + const char *fdprefix) { qemuDomainVsockPrivate *priv = (qemuDomainVsockPrivate *)vsock->privateData; - g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + g_autoptr(virJSONValue) props = NULL; + g_autofree char *vhostfd = g_strdup_printf("%s%u", fdprefix, priv->vhostfd); - if (qemuBuildVirtioDevStr(&buf, qemuCaps, VIR_DOMAIN_DEVICE_VSOCK, vsock) < 0) { + if (!(props = qemuBuildVirtioDevProps(VIR_DOMAIN_DEVICE_VSOCK, vsock, qemuCaps))) return NULL; - } - virBufferAsprintf(&buf, ",id=%s", vsock->info.alias); - virBufferAsprintf(&buf, ",guest-cid=%u", vsock->guest_cid); - virBufferAsprintf(&buf, ",vhostfd=%s%u", fdprefix, priv->vhostfd); + if (virJSONValueObjectAdd(props, + "s:id", vsock->info.alias, + "u:guest-cid", vsock->guest_cid, + "s:vhostfd", vhostfd, + NULL) < 0) + return NULL; - if (qemuBuildDeviceAddressStr(&buf, def, &vsock->info) < 0) + if (qemuBuildDeviceAddressProps(props, def, &vsock->info) < 0) return NULL; - return virBufferContentAndReset(&buf); + return g_steal_pointer(&props); } @@ -10584,9 +10587,9 @@ qemuBuildVsockCommandLine(virCommand *cmd, virQEMUCaps *qemuCaps) { qemuDomainVsockPrivate *priv = (qemuDomainVsockPrivate *)vsock->privateData; - g_autofree char *devstr = NULL; + g_autoptr(virJSONValue) devprops = NULL; - if (!(devstr = qemuBuildVsockDevStr(def, vsock, qemuCaps, ""))) + if (!(devprops = qemuBuildVsockDevProps(def, vsock, qemuCaps, ""))) return -1; virCommandPassFD(cmd, priv->vhostfd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); @@ -10595,7 +10598,8 @@ qemuBuildVsockCommandLine(virCommand *cmd, if (qemuCommandAddExtDevice(cmd, &vsock->info, qemuCaps) < 0) return -1; - virCommandAddArgList(cmd, "-device", devstr, NULL); + if (qemuBuildDeviceCommandlineFromJSON(cmd, devprops, qemuCaps) < 0) + return -1; return 0; } diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 2a87a8a929..56999b7424 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -248,13 +248,11 @@ virJSONValue * qemuBuildInputUSBDevProps(const virDomainDef *def, virDomainInputDef *dev); -char * -qemuBuildVsockDevStr(virDomainDef *def, - virDomainVsockDef *vsock, - virQEMUCaps *qemuCaps, - const char *fdprefix) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) - ATTRIBUTE_NONNULL(4); +virJSONValue * +qemuBuildVsockDevProps(virDomainDef *def, + virDomainVsockDef *vsock, + virQEMUCaps *qemuCaps, + const char *fdprefix); /* this function is exported so that tests can mock the FDs */ int diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 1e91fb393e..b9937220db 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -3349,7 +3349,9 @@ qemuDomainAttachVsockDevice(virQEMUDriver *driver, const char *fdprefix = "vsockfd"; bool releaseaddr = false; g_autofree char *fdname = NULL; - g_autofree char *devstr = NULL; + g_autoptr(virJSONValue) devprops = NULL; + bool removeextension = false; + bool removehandle = false; int ret = -1; if (vm->def->vsock) { @@ -3369,7 +3371,7 @@ qemuDomainAttachVsockDevice(virQEMUDriver *driver, fdname = g_strdup_printf("%s%u", fdprefix, vsockPriv->vhostfd); - if (!(devstr = qemuBuildVsockDevStr(vm->def, vsock, priv->qemuCaps, fdprefix))) + if (!(devprops = qemuBuildVsockDevProps(vm->def, vsock, priv->qemuCaps, fdprefix))) goto cleanup; qemuDomainObjEnterMonitor(driver, vm); @@ -3377,10 +3379,15 @@ qemuDomainAttachVsockDevice(virQEMUDriver *driver, if (qemuDomainAttachExtensionDevice(priv->mon, &vsock->info) < 0) goto exit_monitor; - if (qemuMonitorAddDeviceWithFd(priv->mon, devstr, vsockPriv->vhostfd, fdname) < 0) { - ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &vsock->info)); + removeextension = true; + + if ((ret = qemuMonitorSendFileHandle(priv->mon, fdname, vsockPriv->vhostfd)) < 0) + goto exit_monitor; + + removehandle = true; + + if ((ret = qemuMonitorAddDeviceProps(priv->mon, &devprops)) < 0) goto exit_monitor; - } if (qemuDomainObjExitMonitor(driver, vm) < 0) { releaseaddr = false; @@ -3402,6 +3409,10 @@ qemuDomainAttachVsockDevice(virQEMUDriver *driver, return ret; exit_monitor: + if (removehandle) + ignore_value(qemuMonitorCloseFileHandle(priv->mon, fdname)); + if (removeextension) + ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &vsock->info)); if (qemuDomainObjExitMonitor(driver, vm) < 0) releaseaddr = false; goto cleanup; -- 2.31.1