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;
virDomainVirtTypeFromString;
virDomainVirtTypeToString;
virDomainVsockDefFree;
virDomainVsockDefNew;
virDomainWatchdogActionTypeFromString;
virDomainWatchdogActionTypeToString;

View File

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

View File

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

View File

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

View File

@ -206,4 +206,12 @@ int qemuBuildInputDevStr(char **devstr,
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
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__*/

View File

@ -7690,6 +7690,14 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
}
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_FS:
case VIR_DOMAIN_DEVICE_SOUND:
@ -7702,7 +7710,6 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_IOMMU:
case VIR_DOMAIN_DEVICE_VSOCK:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("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
qemuDomainChangeNetBridge(virDomainObjPtr vm,
virDomainNetDefPtr olddev,

View File

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

View File

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

View File

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