diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ea2c82f513..5d3a8f3b39 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4979,30 +4979,33 @@ qemuBuildSCSIiSCSIHostdevDrvStr(virDomainHostdevDef *dev) return virBufferContentAndReset(&buf); } -char * -qemuBuildSCSIVHostHostdevDevStr(const virDomainDef *def, - virDomainHostdevDef *dev, - virQEMUCaps *qemuCaps, - char *vhostfdName) + +virJSONValue * +qemuBuildSCSIVHostHostdevDevProps(const virDomainDef *def, + virDomainHostdevDef *dev, + virQEMUCaps *qemuCaps, + char *vhostfdName) { - g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + g_autoptr(virJSONValue) props = NULL; virDomainHostdevSubsysSCSIVHost *hostsrc = &dev->source.subsys.u.scsi_host; - if (qemuBuildVirtioDevStr(&buf, qemuCaps, VIR_DOMAIN_DEVICE_HOSTDEV, dev) < 0) { - return NULL; - } - - virBufferAsprintf(&buf, ",wwpn=%s,vhostfd=%s,id=%s", - hostsrc->wwpn, - vhostfdName, - dev->info->alias); - - if (qemuBuildDeviceAddressStr(&buf, def, dev->info) < 0) + if (!(props = qemuBuildVirtioDevProps(VIR_DOMAIN_DEVICE_HOSTDEV, dev, qemuCaps))) return NULL; - return virBufferContentAndReset(&buf); + if (virJSONValueObjectAdd(props, + "s:wwpn", hostsrc->wwpn, + "s:vhostfd", vhostfdName, + "s:id", dev->info->alias, + NULL) < 0) + return NULL; + + if (qemuBuildDeviceAddressProps(props, def, dev->info) < 0) + return NULL; + + return g_steal_pointer(&props); } + static char * qemuBuildSCSIHostdevDrvStr(virDomainHostdevDef *dev) { @@ -5565,7 +5568,6 @@ qemuBuildHostdevCommandLine(virCommand *cmd, virDomainHostdevDef *hostdev = def->hostdevs[i]; virDomainHostdevSubsys *subsys = &hostdev->source.subsys; virDomainHostdevSubsysMediatedDev *mdevsrc = &subsys->u.mdev; - g_autofree char *devstr = NULL; g_autoptr(virJSONValue) devprops = NULL; g_autofree char *vhostfdName = NULL; int vhostfd = -1; @@ -5618,14 +5620,14 @@ qemuBuildHostdevCommandLine(virCommand *cmd, virCommandPassFD(cmd, vhostfd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); - virCommandAddArg(cmd, "-device"); - if (!(devstr = qemuBuildSCSIVHostHostdevDevStr(def, - hostdev, - qemuCaps, - vhostfdName))) + if (!(devprops = qemuBuildSCSIVHostHostdevDevProps(def, + hostdev, + qemuCaps, + vhostfdName))) return -1; - virCommandAddArg(cmd, devstr); + if (qemuBuildDeviceCommandlineFromJSON(cmd, devprops, qemuCaps) < 0) + return -1; } break; diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 65e896b634..2a87a8a929 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -195,11 +195,11 @@ qemuBlockStorageSourceAttachData * qemuBuildHostdevSCSIDetachPrepare(virDomainHostdevDef *hostdev, virQEMUCaps *qemuCaps); -char * -qemuBuildSCSIVHostHostdevDevStr(const virDomainDef *def, - virDomainHostdevDef *dev, - virQEMUCaps *qemuCaps, - char *vhostfdName); +virJSONValue * +qemuBuildSCSIVHostHostdevDevProps(const virDomainDef *def, + virDomainHostdevDef *dev, + virQEMUCaps *qemuCaps, + char *vhostfdName); virJSONValue * qemuBuildHostdevMediatedDevProps(const virDomainDef *def, diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index c7da38b49b..1e91fb393e 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2743,7 +2743,9 @@ qemuDomainAttachSCSIVHostDevice(virQEMUDriver *driver, virDomainCCWAddressSet *ccwaddrs = NULL; g_autofree char *vhostfdName = NULL; int vhostfd = -1; - g_autofree char *devstr = NULL; + g_autoptr(virJSONValue) devprops = NULL; + bool removeextension = false; + bool removehandle = false; bool teardowncgroup = false; bool teardownlabel = false; bool teardowndevice = false; @@ -2790,10 +2792,10 @@ qemuDomainAttachSCSIVHostDevice(virQEMUDriver *driver, if (qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1) < 0) goto cleanup; - if (!(devstr = qemuBuildSCSIVHostHostdevDevStr(vm->def, - hostdev, - priv->qemuCaps, - vhostfdName))) + if (!(devprops = qemuBuildSCSIVHostHostdevDevProps(vm->def, + hostdev, + priv->qemuCaps, + vhostfdName))) goto cleanup; VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1); @@ -2803,13 +2805,24 @@ qemuDomainAttachSCSIVHostDevice(virQEMUDriver *driver, if ((ret = qemuDomainAttachExtensionDevice(priv->mon, hostdev->info)) < 0) goto exit_monitor; - if ((ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr, vhostfd, - vhostfdName)) < 0) { - ignore_value(qemuDomainDetachExtensionDevice(priv->mon, hostdev->info)); + removeextension = true; + + if ((ret = qemuMonitorSendFileHandle(priv->mon, vhostfdName, vhostfd))) goto exit_monitor; - } + + removehandle = true; + + if ((ret = qemuMonitorAddDeviceProps(priv->mon, &devprops)) < 0) + goto exit_monitor; + + removeextension = false; + removehandle = false; exit_monitor: + if (removehandle) + ignore_value(qemuMonitorCloseFileHandle(priv->mon, vhostfdName)); + if (removeextension) + ignore_value(qemuDomainDetachExtensionDevice(priv->mon, hostdev->info)); if (qemuDomainObjExitMonitor(driver, vm) < 0 || ret < 0) goto audit;