qemu: Move qemuDomainAttachDeviceLive() into qemu_hotplug.c

There is no good reason for qemuDomainAttachDeviceLive() to live
in (ever growing) qemu_driver.c while we have qemu_hotplug.c
which already contains the rest of hotplug code. Move the
function to its new home.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Kristina Hanicova <khanicov@redhat.com>
This commit is contained in:
Michal Privoznik 2023-04-20 16:52:43 +02:00
parent c8b286935d
commit f5d6290bfe
3 changed files with 174 additions and 170 deletions

View File

@ -6671,176 +6671,6 @@ qemuDomainUndefine(virDomainPtr dom)
return qemuDomainUndefineFlags(dom, 0);
}
static int
qemuDomainAttachDeviceLive(virDomainObj *vm,
virDomainDeviceDef *dev,
virQEMUDriver *driver)
{
int ret = -1;
const char *alias = NULL;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
struct qemuDomainPrepareChardevSourceData chardevBackendData = { .cfg = cfg,
.hotplug = true };
if (qemuDomainDeviceBackendChardevForeachOne(dev,
qemuDomainPrepareChardevSourceOne,
&chardevBackendData) < 0)
return -1;
switch ((virDomainDeviceType)dev->type) {
case VIR_DOMAIN_DEVICE_DISK:
qemuDomainObjCheckDiskTaint(driver, vm, dev->data.disk, NULL);
ret = qemuDomainAttachDeviceDiskLive(driver, vm, dev);
if (!ret) {
alias = dev->data.disk->info.alias;
dev->data.disk = NULL;
}
break;
case VIR_DOMAIN_DEVICE_CONTROLLER:
ret = qemuDomainAttachControllerDevice(vm, dev->data.controller);
if (!ret) {
alias = dev->data.controller->info.alias;
dev->data.controller = NULL;
}
break;
case VIR_DOMAIN_DEVICE_LEASE:
ret = qemuDomainAttachLease(driver, vm,
dev->data.lease);
if (ret == 0)
dev->data.lease = NULL;
break;
case VIR_DOMAIN_DEVICE_NET:
qemuDomainObjCheckNetTaint(driver, vm, dev->data.net, NULL);
ret = qemuDomainAttachNetDevice(driver, vm, dev->data.net);
if (!ret) {
alias = dev->data.net->info.alias;
dev->data.net = NULL;
}
break;
case VIR_DOMAIN_DEVICE_HOSTDEV:
qemuDomainObjCheckHostdevTaint(driver, vm, dev->data.hostdev, NULL);
ret = qemuDomainAttachHostDevice(driver, vm,
dev->data.hostdev);
if (!ret) {
alias = dev->data.hostdev->info->alias;
dev->data.hostdev = NULL;
}
break;
case VIR_DOMAIN_DEVICE_REDIRDEV:
ret = qemuDomainAttachRedirdevDevice(driver, vm,
dev->data.redirdev);
if (!ret) {
alias = dev->data.redirdev->info.alias;
dev->data.redirdev = NULL;
}
break;
case VIR_DOMAIN_DEVICE_CHR:
ret = qemuDomainAttachChrDevice(driver, vm, dev);
if (!ret) {
alias = dev->data.chr->info.alias;
dev->data.chr = NULL;
}
break;
case VIR_DOMAIN_DEVICE_RNG:
ret = qemuDomainAttachRNGDevice(driver, vm,
dev->data.rng);
if (!ret) {
alias = dev->data.rng->info.alias;
dev->data.rng = NULL;
}
break;
case VIR_DOMAIN_DEVICE_MEMORY:
/* note that qemuDomainAttachMemory always consumes dev->data.memory
* and dispatches DeviceAdded event on success */
ret = qemuDomainAttachMemory(driver, vm,
dev->data.memory);
dev->data.memory = NULL;
break;
case VIR_DOMAIN_DEVICE_SHMEM:
ret = qemuDomainAttachShmemDevice(vm, dev->data.shmem);
if (!ret) {
alias = dev->data.shmem->info.alias;
dev->data.shmem = NULL;
}
break;
case VIR_DOMAIN_DEVICE_WATCHDOG:
ret = qemuDomainAttachWatchdog(vm, dev->data.watchdog);
if (!ret) {
alias = dev->data.watchdog->info.alias;
dev->data.watchdog = NULL;
}
break;
case VIR_DOMAIN_DEVICE_INPUT:
ret = qemuDomainAttachInputDevice(vm, dev->data.input);
if (ret == 0) {
alias = dev->data.input->info.alias;
dev->data.input = NULL;
}
break;
case VIR_DOMAIN_DEVICE_VSOCK:
ret = qemuDomainAttachVsockDevice(vm, dev->data.vsock);
if (ret == 0) {
alias = dev->data.vsock->info.alias;
dev->data.vsock = NULL;
}
break;
case VIR_DOMAIN_DEVICE_FS:
ret = qemuDomainAttachFSDevice(driver, vm, dev->data.fs);
if (ret == 0) {
alias = dev->data.fs->info.alias;
dev->data.fs = NULL;
}
break;
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_SOUND:
case VIR_DOMAIN_DEVICE_VIDEO:
case VIR_DOMAIN_DEVICE_GRAPHICS:
case VIR_DOMAIN_DEVICE_HUB:
case VIR_DOMAIN_DEVICE_SMARTCARD:
case VIR_DOMAIN_DEVICE_MEMBALLOON:
case VIR_DOMAIN_DEVICE_NVRAM:
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_IOMMU:
case VIR_DOMAIN_DEVICE_AUDIO:
case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("live attach of device '%1$s' is not supported"),
virDomainDeviceTypeToString(dev->type));
break;
}
if (alias) {
/* queue the event before the alias has a chance to get freed
* if the domain disappears while qemuDomainUpdateDeviceList
* is in monitor */
virObjectEvent *event;
event = virDomainEventDeviceAddedNewFromObj(vm, alias);
virObjectEventStateQueue(driver->domainEventState, event);
}
if (ret == 0)
ret = qemuDomainUpdateDeviceList(vm, VIR_ASYNC_JOB_NONE);
return ret;
}
static int
qemuDomainChangeDiskLive(virDomainObj *vm,
virDomainDeviceDef *dev,

View File

@ -3320,6 +3320,176 @@ qemuDomainAttachLease(virQEMUDriver *driver,
}
int
qemuDomainAttachDeviceLive(virDomainObj *vm,
virDomainDeviceDef *dev,
virQEMUDriver *driver)
{
int ret = -1;
const char *alias = NULL;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
struct qemuDomainPrepareChardevSourceData chardevBackendData = { .cfg = cfg,
.hotplug = true };
if (qemuDomainDeviceBackendChardevForeachOne(dev,
qemuDomainPrepareChardevSourceOne,
&chardevBackendData) < 0)
return -1;
switch ((virDomainDeviceType)dev->type) {
case VIR_DOMAIN_DEVICE_DISK:
qemuDomainObjCheckDiskTaint(driver, vm, dev->data.disk, NULL);
ret = qemuDomainAttachDeviceDiskLive(driver, vm, dev);
if (!ret) {
alias = dev->data.disk->info.alias;
dev->data.disk = NULL;
}
break;
case VIR_DOMAIN_DEVICE_CONTROLLER:
ret = qemuDomainAttachControllerDevice(vm, dev->data.controller);
if (!ret) {
alias = dev->data.controller->info.alias;
dev->data.controller = NULL;
}
break;
case VIR_DOMAIN_DEVICE_LEASE:
ret = qemuDomainAttachLease(driver, vm,
dev->data.lease);
if (ret == 0)
dev->data.lease = NULL;
break;
case VIR_DOMAIN_DEVICE_NET:
qemuDomainObjCheckNetTaint(driver, vm, dev->data.net, NULL);
ret = qemuDomainAttachNetDevice(driver, vm, dev->data.net);
if (!ret) {
alias = dev->data.net->info.alias;
dev->data.net = NULL;
}
break;
case VIR_DOMAIN_DEVICE_HOSTDEV:
qemuDomainObjCheckHostdevTaint(driver, vm, dev->data.hostdev, NULL);
ret = qemuDomainAttachHostDevice(driver, vm,
dev->data.hostdev);
if (!ret) {
alias = dev->data.hostdev->info->alias;
dev->data.hostdev = NULL;
}
break;
case VIR_DOMAIN_DEVICE_REDIRDEV:
ret = qemuDomainAttachRedirdevDevice(driver, vm,
dev->data.redirdev);
if (!ret) {
alias = dev->data.redirdev->info.alias;
dev->data.redirdev = NULL;
}
break;
case VIR_DOMAIN_DEVICE_CHR:
ret = qemuDomainAttachChrDevice(driver, vm, dev);
if (!ret) {
alias = dev->data.chr->info.alias;
dev->data.chr = NULL;
}
break;
case VIR_DOMAIN_DEVICE_RNG:
ret = qemuDomainAttachRNGDevice(driver, vm,
dev->data.rng);
if (!ret) {
alias = dev->data.rng->info.alias;
dev->data.rng = NULL;
}
break;
case VIR_DOMAIN_DEVICE_MEMORY:
/* note that qemuDomainAttachMemory always consumes dev->data.memory
* and dispatches DeviceAdded event on success */
ret = qemuDomainAttachMemory(driver, vm,
dev->data.memory);
dev->data.memory = NULL;
break;
case VIR_DOMAIN_DEVICE_SHMEM:
ret = qemuDomainAttachShmemDevice(vm, dev->data.shmem);
if (!ret) {
alias = dev->data.shmem->info.alias;
dev->data.shmem = NULL;
}
break;
case VIR_DOMAIN_DEVICE_WATCHDOG:
ret = qemuDomainAttachWatchdog(vm, dev->data.watchdog);
if (!ret) {
alias = dev->data.watchdog->info.alias;
dev->data.watchdog = NULL;
}
break;
case VIR_DOMAIN_DEVICE_INPUT:
ret = qemuDomainAttachInputDevice(vm, dev->data.input);
if (ret == 0) {
alias = dev->data.input->info.alias;
dev->data.input = NULL;
}
break;
case VIR_DOMAIN_DEVICE_VSOCK:
ret = qemuDomainAttachVsockDevice(vm, dev->data.vsock);
if (ret == 0) {
alias = dev->data.vsock->info.alias;
dev->data.vsock = NULL;
}
break;
case VIR_DOMAIN_DEVICE_FS:
ret = qemuDomainAttachFSDevice(driver, vm, dev->data.fs);
if (ret == 0) {
alias = dev->data.fs->info.alias;
dev->data.fs = NULL;
}
break;
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_SOUND:
case VIR_DOMAIN_DEVICE_VIDEO:
case VIR_DOMAIN_DEVICE_GRAPHICS:
case VIR_DOMAIN_DEVICE_HUB:
case VIR_DOMAIN_DEVICE_SMARTCARD:
case VIR_DOMAIN_DEVICE_MEMBALLOON:
case VIR_DOMAIN_DEVICE_NVRAM:
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_IOMMU:
case VIR_DOMAIN_DEVICE_AUDIO:
case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("live attach of device '%1$s' is not supported"),
virDomainDeviceTypeToString(dev->type));
break;
}
if (alias) {
/* queue the event before the alias has a chance to get freed
* if the domain disappears while qemuDomainUpdateDeviceList
* is in monitor */
virObjectEvent *event;
event = virDomainEventDeviceAddedNewFromObj(vm, alias);
virObjectEventStateQueue(driver->domainEventState, event);
}
if (ret == 0)
ret = qemuDomainUpdateDeviceList(vm, VIR_ASYNC_JOB_NONE);
return ret;
}
static int
qemuDomainChangeNetBridge(virDomainObj *vm,
virDomainNetDef *olddev,

View File

@ -111,6 +111,10 @@ int qemuDomainAttachRNGDevice(virQEMUDriver *driver,
virDomainObj *vm,
virDomainRNGDef *rng);
int qemuDomainAttachDeviceLive(virDomainObj *vm,
virDomainDeviceDef *dev,
virQEMUDriver *driver);
int qemuDomainDetachDeviceLive(virDomainObj *vm,
virDomainDeviceDef *match,
virQEMUDriver *driver,