qemu: implement vsock hotplug

Allow hotplugging the vsock device.

https://bugzilla.redhat.com/show_bug.cgi?id=1291851

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
Ján Tomko 2018-05-30 13:53:52 +02:00
parent 7ecafb4a2b
commit 8eaa31c3ad
10 changed files with 97 additions and 4 deletions

View File

@ -574,6 +574,7 @@ virDomainVideoVGAConfTypeFromString;
virDomainVideoVGAConfTypeToString; virDomainVideoVGAConfTypeToString;
virDomainVirtTypeFromString; virDomainVirtTypeFromString;
virDomainVirtTypeToString; virDomainVirtTypeToString;
virDomainVsockDefFree;
virDomainVsockDefNew; virDomainVsockDefNew;
virDomainWatchdogActionTypeFromString; virDomainWatchdogActionTypeFromString;
virDomainWatchdogActionTypeToString; virDomainWatchdogActionTypeToString;

View File

@ -533,7 +533,7 @@ qemuAssignDeviceInputAlias(virDomainDefPtr def,
} }
static int int
qemuAssignDeviceVsockAlias(virDomainVsockDefPtr vsock) qemuAssignDeviceVsockAlias(virDomainVsockDefPtr vsock)
{ {
if (vsock->info.alias) if (vsock->info.alias)

View File

@ -70,6 +70,8 @@ int qemuAssignDeviceInputAlias(virDomainDefPtr def,
virDomainInputDefPtr input, virDomainInputDefPtr input,
int idx); int idx);
int qemuAssignDeviceVsockAlias(virDomainVsockDefPtr vsock);
int qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps); int qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps);
int qemuDomainDeviceAliasIndex(const virDomainDeviceInfo *info, int qemuDomainDeviceAliasIndex(const virDomainDeviceInfo *info,

View File

@ -9912,7 +9912,7 @@ qemuBuildSeccompSandboxCommandLine(virCommandPtr cmd,
} }
static char * char *
qemuBuildVsockDevStr(virDomainDefPtr def, qemuBuildVsockDevStr(virDomainDefPtr def,
virDomainVsockDefPtr vsock, virDomainVsockDefPtr vsock,
virQEMUCapsPtr qemuCaps, virQEMUCapsPtr qemuCaps,

View File

@ -206,4 +206,12 @@ int qemuBuildInputDevStr(char **devstr,
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
ATTRIBUTE_NONNULL(4); ATTRIBUTE_NONNULL(4);
char *
qemuBuildVsockDevStr(virDomainDefPtr def,
virDomainVsockDefPtr vsock,
virQEMUCapsPtr qemuCaps,
const char *fdprefix)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
ATTRIBUTE_NONNULL(4);
#endif /* __QEMU_COMMAND_H__*/ #endif /* __QEMU_COMMAND_H__*/

View File

@ -7690,6 +7690,14 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
} }
break; break;
case VIR_DOMAIN_DEVICE_VSOCK:
ret = qemuDomainAttachVsockDevice(driver, vm, dev->data.vsock);
if (ret == 0) {
alias = dev->data.vsock->info.alias;
dev->data.vsock = NULL;
}
break;
case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_FS:
case VIR_DOMAIN_DEVICE_SOUND: case VIR_DOMAIN_DEVICE_SOUND:
@ -7702,7 +7710,6 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC: case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_IOMMU:
case VIR_DOMAIN_DEVICE_VSOCK:
case VIR_DOMAIN_DEVICE_LAST: case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("live attach of device '%s' is not supported"), _("live attach of device '%s' is not supported"),

View File

@ -3015,6 +3015,75 @@ qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
} }
int
qemuDomainAttachVsockDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainVsockDefPtr vsock)
{
qemuDomainVsockPrivatePtr vsockPriv = (qemuDomainVsockPrivatePtr)vsock->privateData;
qemuDomainObjPrivatePtr priv = vm->privateData;
virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_VSOCK,
{ .vsock = vsock } };
virErrorPtr originalError = NULL;
const char *fdprefix = "vsockfd";
bool releaseaddr = false;
char *fdname = NULL;
char *devstr = NULL;
int ret = -1;
if (vm->def->vsock) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("the domain already has a vsock device"));
return -1;
}
if (qemuDomainEnsureVirtioAddress(&releaseaddr, vm, &dev, "vsock") < 0)
return -1;
if (qemuAssignDeviceVsockAlias(vsock) < 0)
goto cleanup;
if (qemuProcessOpenVhostVsock(vsock) < 0)
goto cleanup;
if (virAsprintf(&fdname, "%s%u", fdprefix, vsockPriv->vhostfd) < 0)
goto cleanup;
if (!(devstr = qemuBuildVsockDevStr(vm->def, vsock, priv->qemuCaps, fdprefix)))
goto cleanup;
qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorAddDeviceWithFd(priv->mon, devstr, vsockPriv->vhostfd, fdname) < 0)
goto exit_monitor;
if (qemuDomainObjExitMonitor(driver, vm) < 0) {
releaseaddr = false;
goto cleanup;
}
VIR_STEAL_PTR(vm->def->vsock, vsock);
ret = 0;
cleanup:
if (ret < 0) {
virErrorPreserveLast(&originalError);
if (releaseaddr)
qemuDomainReleaseDeviceAddress(vm, &vsock->info, NULL);
virErrorRestore(&originalError);
}
VIR_FREE(devstr);
VIR_FREE(fdname);
return ret;
exit_monitor:
if (qemuDomainObjExitMonitor(driver, vm) < 0)
releaseaddr = false;
goto cleanup;
}
static int static int
qemuDomainChangeNetBridge(virDomainObjPtr vm, qemuDomainChangeNetBridge(virDomainObjPtr vm,
virDomainNetDefPtr olddev, virDomainNetDefPtr olddev,

View File

@ -139,6 +139,10 @@ int qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainInputDefPtr input); virDomainInputDefPtr input);
int qemuDomainAttachVsockDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainVsockDefPtr vsock);
int qemuDomainAttachLease(virQEMUDriverPtr driver, int qemuDomainAttachLease(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainLeaseDefPtr lease); virDomainLeaseDefPtr lease);

View File

@ -5948,7 +5948,7 @@ qemuProcessPrepareHostStorage(virQEMUDriverPtr driver,
} }
static int int
qemuProcessOpenVhostVsock(virDomainVsockDefPtr vsock) qemuProcessOpenVhostVsock(virDomainVsockDefPtr vsock)
{ {
qemuDomainVsockPrivatePtr priv = (qemuDomainVsockPrivatePtr)vsock->privateData; qemuDomainVsockPrivatePtr priv = (qemuDomainVsockPrivatePtr)vsock->privateData;

View File

@ -113,6 +113,8 @@ int qemuProcessPrepareDomain(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
unsigned int flags); unsigned int flags);
int qemuProcessOpenVhostVsock(virDomainVsockDefPtr vsock);
int qemuProcessPrepareHost(virQEMUDriverPtr driver, int qemuProcessPrepareHost(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
unsigned int flags); unsigned int flags);