qemuBuildHostdevCommandLine: Generate via JSON

Build the properties of 'vhost-scsi' 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 'vhost-scsi' device doesn't have any special (non-string) properties.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2021-10-05 15:39:42 +02:00
parent 9ac91fcceb
commit 44b52c18e3
3 changed files with 53 additions and 38 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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;