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) {
+ if (!(props = qemuBuildVirtioDevProps(VIR_DOMAIN_DEVICE_HOSTDEV, dev, qemuCaps)))
return NULL;
- }
- virBufferAsprintf(&buf, ",wwpn=%s,vhostfd=%s,id=%s",
- hostsrc->wwpn,
- vhostfdName,
- dev->info->alias);
+ if (virJSONValueObjectAdd(props,
+ "s:wwpn", hostsrc->wwpn,
+ "s:vhostfd", vhostfdName,
+ "s:id", dev->info->alias,
+ NULL) < 0)
+ return NULL;
- if (qemuBuildDeviceAddressStr(&buf, def, dev->info) < 0)
+ if (qemuBuildDeviceAddressProps(props, def, dev->info) < 0)
return NULL;
- return virBufferContentAndReset(&buf);
+ return g_steal_pointer(&props);
}
+
static char *
qemuBuildSCSIHostdevDrvStr(virDomainHostdevDef *dev)
{
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;
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;
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,
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;
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);
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;