}
-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);
}
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);
if (qemuCommandAddExtDevice(cmd, &vsock->info, qemuCaps) < 0)
return -1;
- virCommandAddArgList(cmd, "-device", devstr, NULL);
+ if (qemuBuildDeviceCommandlineFromJSON(cmd, devprops, qemuCaps) < 0)
+ return -1;
return 0;
}
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
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) {
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);
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;
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;