The virDomainDetachDeviceAlias API is designed so that it only sends detach request to qemu. It's user's responsibility to wait for DEVICE_DELETED event, not libvirt's. Add @async flag to qemuDomainDetach*Device() functions so that caller can chose if detach is semi-synchronous (old virDomainDetachDeviceFlags()) or fully asynchronous (new virDomainDetachDeviceFlags()). Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/qemu/qemu_driver.c | 32 +++---- src/qemu/qemu_hotplug.c | 231 ++++++++++++++++++++++++++++++++---------------- src/qemu/qemu_hotplug.h | 33 ++++--- tests/qemuhotplugtest.c | 13 +-- 4 files changed, 203 insertions(+), 106 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2347e71cfb..81a9833b39 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7726,14 +7726,15 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm, static int qemuDomainDetachDeviceControllerLive(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev) + virDomainDeviceDefPtr dev, + bool async) { virDomainControllerDefPtr cont = dev->data.controller; int ret = -1; switch (cont->type) { case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: - ret = qemuDomainDetachControllerDevice(driver, vm, dev); + ret = qemuDomainDetachControllerDevice(driver, vm, dev, async); break; default : virReportError(VIR_ERR_OPERATION_UNSUPPORTED, @@ -7746,46 +7747,47 @@ qemuDomainDetachDeviceControllerLive(virQEMUDriverPtr driver, static int qemuDomainDetachDeviceLive(virDomainObjPtr vm, virDomainDeviceDefPtr dev, - virQEMUDriverPtr driver) + virQEMUDriverPtr driver, + bool async) { int ret = -1; switch ((virDomainDeviceType)dev->type) { case VIR_DOMAIN_DEVICE_DISK: - ret = qemuDomainDetachDeviceDiskLive(driver, vm, dev); + ret = qemuDomainDetachDeviceDiskLive(driver, vm, dev, async); break; case VIR_DOMAIN_DEVICE_CONTROLLER: - ret = qemuDomainDetachDeviceControllerLive(driver, vm, dev); + ret = qemuDomainDetachDeviceControllerLive(driver, vm, dev, async); break; case VIR_DOMAIN_DEVICE_LEASE: ret = qemuDomainDetachLease(driver, vm, dev->data.lease); break; case VIR_DOMAIN_DEVICE_NET: - ret = qemuDomainDetachNetDevice(driver, vm, dev); + ret = qemuDomainDetachNetDevice(driver, vm, dev, async); break; case VIR_DOMAIN_DEVICE_HOSTDEV: - ret = qemuDomainDetachHostDevice(driver, vm, dev); + ret = qemuDomainDetachHostDevice(driver, vm, dev, async); break; case VIR_DOMAIN_DEVICE_CHR: - ret = qemuDomainDetachChrDevice(driver, vm, dev->data.chr); + ret = qemuDomainDetachChrDevice(driver, vm, dev->data.chr, async); break; case VIR_DOMAIN_DEVICE_RNG: - ret = qemuDomainDetachRNGDevice(driver, vm, dev->data.rng); + ret = qemuDomainDetachRNGDevice(driver, vm, dev->data.rng, async); break; case VIR_DOMAIN_DEVICE_MEMORY: - ret = qemuDomainDetachMemoryDevice(driver, vm, dev->data.memory); + ret = qemuDomainDetachMemoryDevice(driver, vm, dev->data.memory, async); break; case VIR_DOMAIN_DEVICE_SHMEM: - ret = qemuDomainDetachShmemDevice(driver, vm, dev->data.shmem); + ret = qemuDomainDetachShmemDevice(driver, vm, dev->data.shmem, async); break; case VIR_DOMAIN_DEVICE_WATCHDOG: - ret = qemuDomainDetachWatchdog(driver, vm, dev->data.watchdog); + ret = qemuDomainDetachWatchdog(driver, vm, dev->data.watchdog, async); break; case VIR_DOMAIN_DEVICE_INPUT: - ret = qemuDomainDetachInputDevice(vm, dev->data.input); + ret = qemuDomainDetachInputDevice(vm, dev->data.input, async); break; case VIR_DOMAIN_DEVICE_REDIRDEV: - ret = qemuDomainDetachRedirdevDevice(driver, vm, dev->data.redirdev); + ret = qemuDomainDetachRedirdevDevice(driver, vm, dev->data.redirdev, async); break; case VIR_DOMAIN_DEVICE_FS: @@ -8716,7 +8718,7 @@ qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr driver, } if (flags & VIR_DOMAIN_AFFECT_LIVE) { - if (qemuDomainDetachDeviceLive(vm, dev_copy, driver) < 0) + if (qemuDomainDetachDeviceLive(vm, dev_copy, driver, false) < 0) goto cleanup; /* * update domain status forcibly because the domain status may be diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index e84dc909b9..5b5c27b011 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -4740,7 +4740,8 @@ qemuDomainSignalDeviceRemoval(virDomainObjPtr vm, static int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDiskDefPtr detach) + virDomainDiskDefPtr detach, + bool async) { int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -4757,7 +4758,8 @@ qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver, goto cleanup; } - qemuDomainMarkDeviceForRemoval(vm, &detach->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, &detach->info); qemuDomainObjEnterMonitor(driver, vm); if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { @@ -4769,18 +4771,24 @@ qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver, if (qemuDomainObjExitMonitor(driver, vm) < 0) goto cleanup; - if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) - ret = qemuDomainRemoveDiskDevice(driver, vm, detach); + if (async) { + ret = 0; + } else { + if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) + ret = qemuDomainRemoveDiskDevice(driver, vm, detach); + } cleanup: - qemuDomainResetDeviceRemoval(vm); + if (!async) + qemuDomainResetDeviceRemoval(vm); return ret; } static int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDiskDefPtr detach) + virDomainDiskDefPtr detach, + bool async) { int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -4788,7 +4796,8 @@ qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, if (qemuDomainDiskBlockJobIsActive(detach)) goto cleanup; - qemuDomainMarkDeviceForRemoval(vm, &detach->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, &detach->info); qemuDomainObjEnterMonitor(driver, vm); if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { @@ -4800,11 +4809,16 @@ qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, if (qemuDomainObjExitMonitor(driver, vm) < 0) goto cleanup; - if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) - ret = qemuDomainRemoveDiskDevice(driver, vm, detach); + if (async) { + ret = 0; + } else { + if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) + ret = qemuDomainRemoveDiskDevice(driver, vm, detach); + } cleanup: - qemuDomainResetDeviceRemoval(vm); + if (!async) + qemuDomainResetDeviceRemoval(vm); return ret; } @@ -4824,7 +4838,8 @@ qemuFindDisk(virDomainDefPtr def, const char *dst) int qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev) + virDomainDeviceDefPtr dev, + bool async) { virDomainDiskDefPtr disk; int ret = -1; @@ -4841,10 +4856,10 @@ qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, case VIR_DOMAIN_DISK_DEVICE_DISK: case VIR_DOMAIN_DISK_DEVICE_LUN: if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) - ret = qemuDomainDetachVirtioDiskDevice(driver, vm, disk); + ret = qemuDomainDetachVirtioDiskDevice(driver, vm, disk, async); else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI || disk->bus == VIR_DOMAIN_DISK_BUS_USB) - ret = qemuDomainDetachDiskDevice(driver, vm, disk); + ret = qemuDomainDetachDiskDevice(driver, vm, disk, async); else virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", _("This type of disk cannot be hot unplugged")); @@ -4922,7 +4937,8 @@ static bool qemuDomainControllerIsBusy(virDomainObjPtr vm, int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev) + virDomainDeviceDefPtr dev, + bool async) { int idx, ret = -1; virDomainControllerDefPtr detach = NULL; @@ -4974,7 +4990,8 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, goto cleanup; } - qemuDomainMarkDeviceForRemoval(vm, &detach->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, &detach->info); qemuDomainObjEnterMonitor(driver, vm); if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) { @@ -4984,18 +5001,24 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, if (qemuDomainObjExitMonitor(driver, vm) < 0) goto cleanup; - if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) - ret = qemuDomainRemoveControllerDevice(driver, vm, detach); + if (async) { + ret = 0; + } else { + if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) + ret = qemuDomainRemoveControllerDevice(driver, vm, detach); + } cleanup: - qemuDomainResetDeviceRemoval(vm); + if (!async) + qemuDomainResetDeviceRemoval(vm); return ret; } static int qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainHostdevDefPtr detach) + virDomainHostdevDefPtr detach, + bool async) { qemuDomainObjPrivatePtr priv = vm->privateData; virDomainHostdevSubsysPCIPtr pcisrc = &detach->source.subsys.u.pci; @@ -5009,7 +5032,8 @@ qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver, return -1; } - qemuDomainMarkDeviceForRemoval(vm, detach->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, detach->info); qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); @@ -5022,7 +5046,8 @@ qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver, static int qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainHostdevDefPtr detach) + virDomainHostdevDefPtr detach, + bool async) { qemuDomainObjPrivatePtr priv = vm->privateData; int ret; @@ -5033,7 +5058,8 @@ qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver, return -1; } - qemuDomainMarkDeviceForRemoval(vm, detach->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, detach->info); qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); @@ -5046,7 +5072,8 @@ qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver, static int qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainHostdevDefPtr detach) + virDomainHostdevDefPtr detach, + bool async) { qemuDomainObjPrivatePtr priv = vm->privateData; int ret = -1; @@ -5057,7 +5084,8 @@ qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver, return -1; } - qemuDomainMarkDeviceForRemoval(vm, detach->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, detach->info); qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); @@ -5071,7 +5099,8 @@ qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver, static int qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainHostdevDefPtr detach) + virDomainHostdevDefPtr detach, + bool async) { qemuDomainObjPrivatePtr priv = vm->privateData; int ret = -1; @@ -5082,7 +5111,8 @@ qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver, return -1; } - qemuDomainMarkDeviceForRemoval(vm, detach->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, detach->info); qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); @@ -5097,7 +5127,8 @@ qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver, static int qemuDomainDetachMediatedDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainHostdevDefPtr detach) + virDomainHostdevDefPtr detach, + bool async) { int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -5108,7 +5139,8 @@ qemuDomainDetachMediatedDevice(virQEMUDriverPtr driver, return -1; } - qemuDomainMarkDeviceForRemoval(vm, detach->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, detach->info); qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); @@ -5122,7 +5154,8 @@ qemuDomainDetachMediatedDevice(virQEMUDriverPtr driver, static int qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainHostdevDefPtr detach) + virDomainHostdevDefPtr detach, + bool async) { int ret = -1; @@ -5131,19 +5164,19 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver, switch (detach->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: - ret = qemuDomainDetachHostPCIDevice(driver, vm, detach); + ret = qemuDomainDetachHostPCIDevice(driver, vm, detach, async); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: - ret = qemuDomainDetachHostUSBDevice(driver, vm, detach); + ret = qemuDomainDetachHostUSBDevice(driver, vm, detach, async); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: - ret = qemuDomainDetachHostSCSIDevice(driver, vm, detach); + ret = qemuDomainDetachHostSCSIDevice(driver, vm, detach, async); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: - ret = qemuDomainDetachSCSIVHostDevice(driver, vm, detach); + ret = qemuDomainDetachSCSIVHostDevice(driver, vm, detach, async); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: - ret = qemuDomainDetachMediatedDevice(driver, vm, detach); + ret = qemuDomainDetachMediatedDevice(driver, vm, detach, async); break; default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -5155,11 +5188,13 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver, if (ret < 0) { if (virDomainObjIsActive(vm)) virDomainAuditHostdev(vm, detach, "detach", false); - } else if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) { + } else if (!async && + (ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) { ret = qemuDomainRemoveHostDevice(driver, vm, detach); } - qemuDomainResetDeviceRemoval(vm); + if (!async) + qemuDomainResetDeviceRemoval(vm); return ret; } @@ -5167,7 +5202,8 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver, /* search for a hostdev matching dev and detach it */ int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev) + virDomainDeviceDefPtr dev, + bool async) { virDomainHostdevDefPtr hostdev = dev->data.hostdev; virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys; @@ -5242,16 +5278,17 @@ int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, * function so that mac address / virtualport are reset */ if (detach->parent.type == VIR_DOMAIN_DEVICE_NET) - return qemuDomainDetachNetDevice(driver, vm, &detach->parent); + return qemuDomainDetachNetDevice(driver, vm, &detach->parent, async); else - return qemuDomainDetachThisHostDevice(driver, vm, detach); + return qemuDomainDetachThisHostDevice(driver, vm, detach, async); } int qemuDomainDetachShmemDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainShmemDefPtr dev) + virDomainShmemDefPtr dev, + bool async) { int ret = -1; ssize_t idx = -1; @@ -5282,7 +5319,8 @@ qemuDomainDetachShmemDevice(virQEMUDriverPtr driver, return -1; } - qemuDomainMarkDeviceForRemoval(vm, &shmem->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, &shmem->info); qemuDomainObjEnterMonitor(driver, vm); if (qemuMonitorDelDevice(priv->mon, shmem->info.alias) < 0) { @@ -5304,7 +5342,8 @@ qemuDomainDetachShmemDevice(virQEMUDriverPtr driver, int qemuDomainDetachWatchdog(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainWatchdogDefPtr dev) + virDomainWatchdogDefPtr dev, + bool async) { int ret = -1; virDomainWatchdogDefPtr watchdog = vm->def->watchdog; @@ -5336,7 +5375,8 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver, return -1; } - qemuDomainMarkDeviceForRemoval(vm, &watchdog->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, &watchdog->info); qemuDomainObjEnterMonitor(driver, vm); if (qemuMonitorDelDevice(priv->mon, watchdog->info.alias) < 0) { @@ -5358,7 +5398,8 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver, int qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainRedirdevDefPtr dev) + virDomainRedirdevDefPtr dev, + bool async) { int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -5379,7 +5420,8 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver, return -1; } - qemuDomainMarkDeviceForRemoval(vm, &tmpRedirdevDef->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, &tmpRedirdevDef->info); qemuDomainObjEnterMonitor(driver, vm); if (qemuMonitorDelDevice(priv->mon, tmpRedirdevDef->info.alias) < 0) { @@ -5389,11 +5431,16 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver, if (qemuDomainObjExitMonitor(driver, vm) < 0) goto cleanup; - if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) - ret = qemuDomainRemoveRedirdevDevice(driver, vm, tmpRedirdevDef); + if (async) { + ret = 0; + } else { + if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) + ret = qemuDomainRemoveRedirdevDevice(driver, vm, tmpRedirdevDef); + } cleanup: - qemuDomainResetDeviceRemoval(vm); + if (!async) + qemuDomainResetDeviceRemoval(vm); return ret; } @@ -5401,7 +5448,8 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver, int qemuDomainDetachNetDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev) + virDomainDeviceDefPtr dev, + bool async) { int detachidx, ret = -1; virDomainNetDefPtr detach = NULL; @@ -5414,7 +5462,8 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver, if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) { ret = qemuDomainDetachThisHostDevice(driver, vm, - virDomainNetGetActualHostdev(detach)); + virDomainNetGetActualHostdev(detach),\ + async); goto cleanup; } @@ -5442,7 +5491,8 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver, */ ignore_value(qemuInterfaceStopDevice(detach)); - qemuDomainMarkDeviceForRemoval(vm, &detach->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, &detach->info); qemuDomainObjEnterMonitor(driver, vm); if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { @@ -5454,11 +5504,16 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver, if (qemuDomainObjExitMonitor(driver, vm) < 0) goto cleanup; - if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) - ret = qemuDomainRemoveNetDevice(driver, vm, detach); + if (async) { + ret = 0; + } else { + if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) + ret = qemuDomainRemoveNetDevice(driver, vm, detach); + } cleanup: - qemuDomainResetDeviceRemoval(vm); + if (!async) + qemuDomainResetDeviceRemoval(vm); return ret; } @@ -5585,7 +5640,8 @@ int qemuDomainDetachLease(virQEMUDriverPtr driver, int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainChrDefPtr chr) + virDomainChrDefPtr chr, + bool async) { int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -5609,7 +5665,8 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, if (qemuBuildChrDeviceStr(&devstr, vmdef, chr, priv->qemuCaps) < 0) goto cleanup; - qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info); qemuDomainObjEnterMonitor(driver, vm); if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) { @@ -5619,11 +5676,16 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, if (qemuDomainObjExitMonitor(driver, vm) < 0) goto cleanup; - if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) - ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr); + if (async) { + ret = 0; + } else { + if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) + ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr); + } cleanup: - qemuDomainResetDeviceRemoval(vm); + if (!async) + qemuDomainResetDeviceRemoval(vm); VIR_FREE(devstr); return ret; } @@ -5632,7 +5694,8 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, int qemuDomainDetachRNGDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainRNGDefPtr rng) + virDomainRNGDefPtr rng, + bool async) { qemuDomainObjPrivatePtr priv = vm->privateData; ssize_t idx; @@ -5656,18 +5719,24 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver, return -1; } - qemuDomainMarkDeviceForRemoval(vm, &tmpRNG->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, &tmpRNG->info); qemuDomainObjEnterMonitor(driver, vm); rc = qemuMonitorDelDevice(priv->mon, tmpRNG->info.alias); if (qemuDomainObjExitMonitor(driver, vm) || rc < 0) goto cleanup; - if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) - ret = qemuDomainRemoveRNGDevice(driver, vm, tmpRNG); + if (async) { + ret = 0; + } else { + if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) + ret = qemuDomainRemoveRNGDevice(driver, vm, tmpRNG); + } cleanup: - qemuDomainResetDeviceRemoval(vm); + if (!async) + qemuDomainResetDeviceRemoval(vm); return ret; } @@ -5675,7 +5744,8 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver, int qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainMemoryDefPtr memdef) + virDomainMemoryDefPtr memdef, + bool async) { qemuDomainObjPrivatePtr priv = vm->privateData; virDomainMemoryDefPtr mem; @@ -5701,18 +5771,24 @@ qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver, return -1; } - qemuDomainMarkDeviceForRemoval(vm, &mem->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, &mem->info); qemuDomainObjEnterMonitor(driver, vm); rc = qemuMonitorDelDevice(priv->mon, mem->info.alias); if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) goto cleanup; - if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) - ret = qemuDomainRemoveMemoryDevice(driver, vm, mem); + if (async) { + ret = 0; + } else { + if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) + ret = qemuDomainRemoveMemoryDevice(driver, vm, mem); + } cleanup: - qemuDomainResetDeviceRemoval(vm); + if (!async) + qemuDomainResetDeviceRemoval(vm); return ret; } @@ -6380,7 +6456,8 @@ qemuDomainSetVcpuInternal(virQEMUDriverPtr driver, int qemuDomainDetachInputDevice(virDomainObjPtr vm, - virDomainInputDefPtr def) + virDomainInputDefPtr def, + bool async) { qemuDomainObjPrivatePtr priv = vm->privateData; virQEMUDriverPtr driver = priv->driver; @@ -6410,7 +6487,8 @@ qemuDomainDetachInputDevice(virDomainObjPtr vm, break; } - qemuDomainMarkDeviceForRemoval(vm, &input->info); + if (!async) + qemuDomainMarkDeviceForRemoval(vm, &input->info); qemuDomainObjEnterMonitor(driver, vm); if (qemuMonitorDelDevice(priv->mon, input->info.alias)) { @@ -6420,10 +6498,15 @@ qemuDomainDetachInputDevice(virDomainObjPtr vm, if (qemuDomainObjExitMonitor(driver, vm) < 0) goto cleanup; - if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) - ret = qemuDomainRemoveInputDevice(vm, input); + if (async) { + ret = 0; + } else { + if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) + ret = qemuDomainRemoveInputDevice(vm, input); + } cleanup: - qemuDomainResetDeviceRemoval(vm); + if (!async) + qemuDomainResetDeviceRemoval(vm); return ret; } diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index b2f5fa688b..751cbf61d4 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -87,7 +87,8 @@ int qemuDomainAttachMemory(virQEMUDriverPtr driver, virDomainMemoryDefPtr mem); int qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainMemoryDefPtr memdef); + virDomainMemoryDefPtr memdef, + bool async); int qemuDomainChangeGraphics(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainGraphicsDefPtr dev); @@ -106,26 +107,33 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver, int linkstate); int qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev); + virDomainDeviceDefPtr dev, + bool async); int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev); + virDomainDeviceDefPtr dev, + bool async); int qemuDomainDetachNetDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev); + virDomainDeviceDefPtr dev, + bool async); int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev); + virDomainDeviceDefPtr dev, + bool async); int qemuDomainDetachShmemDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainShmemDefPtr dev); + virDomainShmemDefPtr dev, + bool async); int qemuDomainDetachWatchdog(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainWatchdogDefPtr watchdog); + virDomainWatchdogDefPtr watchdog, + bool async); int qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainRedirdevDefPtr dev); + virDomainRedirdevDefPtr dev, + bool async); int qemuDomainAttachInputDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -142,13 +150,15 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver, virDomainChrDefPtr chr); int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainChrDefPtr chr); + virDomainChrDefPtr chr, + bool async); int qemuDomainAttachRNGDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainRNGDefPtr rng); int qemuDomainDetachRNGDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainRNGDefPtr rng); + virDomainRNGDefPtr rng, + bool async); void qemuDomainRemoveVcpuAlias(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -184,6 +194,7 @@ int qemuDomainSetVcpuInternal(virQEMUDriverPtr driver, bool state); int qemuDomainDetachInputDevice(virDomainObjPtr vm, - virDomainInputDefPtr def); + virDomainInputDefPtr def, + bool async); #endif /* __QEMU_HOTPLUG_H__ */ diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index e93503812a..663e33ed00 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -142,22 +142,23 @@ testQemuHotplugAttach(virDomainObjPtr vm, static int testQemuHotplugDetach(virDomainObjPtr vm, - virDomainDeviceDefPtr dev) + virDomainDeviceDefPtr dev, + bool async) { int ret = -1; switch (dev->type) { case VIR_DOMAIN_DEVICE_DISK: - ret = qemuDomainDetachDeviceDiskLive(&driver, vm, dev); + ret = qemuDomainDetachDeviceDiskLive(&driver, vm, dev, async); break; case VIR_DOMAIN_DEVICE_CHR: - ret = qemuDomainDetachChrDevice(&driver, vm, dev->data.chr); + ret = qemuDomainDetachChrDevice(&driver, vm, dev->data.chr, async); break; case VIR_DOMAIN_DEVICE_SHMEM: - ret = qemuDomainDetachShmemDevice(&driver, vm, dev->data.shmem); + ret = qemuDomainDetachShmemDevice(&driver, vm, dev->data.shmem, async); break; case VIR_DOMAIN_DEVICE_WATCHDOG: - ret = qemuDomainDetachWatchdog(&driver, vm, dev->data.watchdog); + ret = qemuDomainDetachWatchdog(&driver, vm, dev->data.watchdog, async); break; default: VIR_TEST_VERBOSE("device type '%s' cannot be detached\n", @@ -322,7 +323,7 @@ testQemuHotplug(const void *data) break; case DETACH: - ret = testQemuHotplugDetach(vm, dev); + ret = testQemuHotplugDetach(vm, dev, false); if (ret == 0 || fail) ret = testQemuHotplugCheckResult(vm, domain_xml, domain_filename, fail); -- 2.16.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list