qemu_hotplug: Allow asynchronous detach

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@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Michal Privoznik 2018-05-23 18:01:16 +02:00
parent a7837f92cc
commit 5c81c342a7
4 changed files with 211 additions and 109 deletions

View File

@ -7727,14 +7727,15 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
static int static int
qemuDomainDetachDeviceControllerLive(virQEMUDriverPtr driver, qemuDomainDetachDeviceControllerLive(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDeviceDefPtr dev) virDomainDeviceDefPtr dev,
bool async)
{ {
virDomainControllerDefPtr cont = dev->data.controller; virDomainControllerDefPtr cont = dev->data.controller;
int ret = -1; int ret = -1;
switch (cont->type) { switch (cont->type) {
case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
ret = qemuDomainDetachControllerDevice(driver, vm, dev); ret = qemuDomainDetachControllerDevice(driver, vm, dev, async);
break; break;
default : default :
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
@ -7747,46 +7748,47 @@ qemuDomainDetachDeviceControllerLive(virQEMUDriverPtr driver,
static int static int
qemuDomainDetachDeviceLive(virDomainObjPtr vm, qemuDomainDetachDeviceLive(virDomainObjPtr vm,
virDomainDeviceDefPtr dev, virDomainDeviceDefPtr dev,
virQEMUDriverPtr driver) virQEMUDriverPtr driver,
bool async)
{ {
int ret = -1; int ret = -1;
switch ((virDomainDeviceType)dev->type) { switch ((virDomainDeviceType)dev->type) {
case VIR_DOMAIN_DEVICE_DISK: case VIR_DOMAIN_DEVICE_DISK:
ret = qemuDomainDetachDeviceDiskLive(driver, vm, dev); ret = qemuDomainDetachDeviceDiskLive(driver, vm, dev, async);
break; break;
case VIR_DOMAIN_DEVICE_CONTROLLER: case VIR_DOMAIN_DEVICE_CONTROLLER:
ret = qemuDomainDetachDeviceControllerLive(driver, vm, dev); ret = qemuDomainDetachDeviceControllerLive(driver, vm, dev, async);
break; break;
case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_LEASE:
ret = qemuDomainDetachLease(driver, vm, dev->data.lease); ret = qemuDomainDetachLease(driver, vm, dev->data.lease);
break; break;
case VIR_DOMAIN_DEVICE_NET: case VIR_DOMAIN_DEVICE_NET:
ret = qemuDomainDetachNetDevice(driver, vm, dev); ret = qemuDomainDetachNetDevice(driver, vm, dev, async);
break; break;
case VIR_DOMAIN_DEVICE_HOSTDEV: case VIR_DOMAIN_DEVICE_HOSTDEV:
ret = qemuDomainDetachHostDevice(driver, vm, dev); ret = qemuDomainDetachHostDevice(driver, vm, dev, async);
break; break;
case VIR_DOMAIN_DEVICE_CHR: case VIR_DOMAIN_DEVICE_CHR:
ret = qemuDomainDetachChrDevice(driver, vm, dev->data.chr); ret = qemuDomainDetachChrDevice(driver, vm, dev->data.chr, async);
break; break;
case VIR_DOMAIN_DEVICE_RNG: case VIR_DOMAIN_DEVICE_RNG:
ret = qemuDomainDetachRNGDevice(driver, vm, dev->data.rng); ret = qemuDomainDetachRNGDevice(driver, vm, dev->data.rng, async);
break; break;
case VIR_DOMAIN_DEVICE_MEMORY: case VIR_DOMAIN_DEVICE_MEMORY:
ret = qemuDomainDetachMemoryDevice(driver, vm, dev->data.memory); ret = qemuDomainDetachMemoryDevice(driver, vm, dev->data.memory, async);
break; break;
case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_SHMEM:
ret = qemuDomainDetachShmemDevice(driver, vm, dev->data.shmem); ret = qemuDomainDetachShmemDevice(driver, vm, dev->data.shmem, async);
break; break;
case VIR_DOMAIN_DEVICE_WATCHDOG: case VIR_DOMAIN_DEVICE_WATCHDOG:
ret = qemuDomainDetachWatchdog(driver, vm, dev->data.watchdog); ret = qemuDomainDetachWatchdog(driver, vm, dev->data.watchdog, async);
break; break;
case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_INPUT:
ret = qemuDomainDetachInputDevice(vm, dev->data.input); ret = qemuDomainDetachInputDevice(vm, dev->data.input, async);
break; break;
case VIR_DOMAIN_DEVICE_REDIRDEV: case VIR_DOMAIN_DEVICE_REDIRDEV:
ret = qemuDomainDetachRedirdevDevice(driver, vm, dev->data.redirdev); ret = qemuDomainDetachRedirdevDevice(driver, vm, dev->data.redirdev, async);
break; break;
case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_FS:
@ -8717,7 +8719,7 @@ qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr driver,
} }
if (flags & VIR_DOMAIN_AFFECT_LIVE) { if (flags & VIR_DOMAIN_AFFECT_LIVE) {
if (qemuDomainDetachDeviceLive(vm, dev_copy, driver) < 0) if (qemuDomainDetachDeviceLive(vm, dev_copy, driver, false) < 0)
goto cleanup; goto cleanup;
/* /*
* update domain status forcibly because the domain status may be * update domain status forcibly because the domain status may be

View File

@ -4740,7 +4740,8 @@ qemuDomainSignalDeviceRemoval(virDomainObjPtr vm,
static int static int
qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver, qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDiskDefPtr detach) virDomainDiskDefPtr detach,
bool async)
{ {
int ret = -1; int ret = -1;
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
@ -4757,7 +4758,8 @@ qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
qemuDomainMarkDeviceForRemoval(vm, &detach->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, &detach->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
@ -4769,18 +4771,24 @@ qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
if (qemuDomainObjExitMonitor(driver, vm) < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup; goto cleanup;
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if (async) {
ret = qemuDomainRemoveDiskDevice(driver, vm, detach); ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveDiskDevice(driver, vm, detach);
}
cleanup: cleanup:
qemuDomainResetDeviceRemoval(vm); if (!async)
qemuDomainResetDeviceRemoval(vm);
return ret; return ret;
} }
static int static int
qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDiskDefPtr detach) virDomainDiskDefPtr detach,
bool async)
{ {
int ret = -1; int ret = -1;
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
@ -4788,7 +4796,8 @@ qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
if (qemuDomainDiskBlockJobIsActive(detach)) if (qemuDomainDiskBlockJobIsActive(detach))
goto cleanup; goto cleanup;
qemuDomainMarkDeviceForRemoval(vm, &detach->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, &detach->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
@ -4800,11 +4809,16 @@ qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
if (qemuDomainObjExitMonitor(driver, vm) < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup; goto cleanup;
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if (async) {
ret = qemuDomainRemoveDiskDevice(driver, vm, detach); ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveDiskDevice(driver, vm, detach);
}
cleanup: cleanup:
qemuDomainResetDeviceRemoval(vm); if (!async)
qemuDomainResetDeviceRemoval(vm);
return ret; return ret;
} }
@ -4824,7 +4838,8 @@ qemuFindDisk(virDomainDefPtr def, const char *dst)
int int
qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDeviceDefPtr dev) virDomainDeviceDefPtr dev,
bool async)
{ {
virDomainDiskDefPtr disk; virDomainDiskDefPtr disk;
int ret = -1; int ret = -1;
@ -4841,10 +4856,10 @@ qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver,
case VIR_DOMAIN_DISK_DEVICE_DISK: case VIR_DOMAIN_DISK_DEVICE_DISK:
case VIR_DOMAIN_DISK_DEVICE_LUN: case VIR_DOMAIN_DISK_DEVICE_LUN:
if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) 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 || else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
disk->bus == VIR_DOMAIN_DISK_BUS_USB) disk->bus == VIR_DOMAIN_DISK_BUS_USB)
ret = qemuDomainDetachDiskDevice(driver, vm, disk); ret = qemuDomainDetachDiskDevice(driver, vm, disk, async);
else else
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("This type of disk cannot be hot unplugged")); _("This type of disk cannot be hot unplugged"));
@ -4922,7 +4937,8 @@ static bool qemuDomainControllerIsBusy(virDomainObjPtr vm,
int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDeviceDefPtr dev) virDomainDeviceDefPtr dev,
bool async)
{ {
int idx, ret = -1; int idx, ret = -1;
virDomainControllerDefPtr detach = NULL; virDomainControllerDefPtr detach = NULL;
@ -4974,7 +4990,8 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
qemuDomainMarkDeviceForRemoval(vm, &detach->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, &detach->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) {
@ -4984,18 +5001,24 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
if (qemuDomainObjExitMonitor(driver, vm) < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup; goto cleanup;
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if (async) {
ret = qemuDomainRemoveControllerDevice(driver, vm, detach); ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveControllerDevice(driver, vm, detach);
}
cleanup: cleanup:
qemuDomainResetDeviceRemoval(vm); if (!async)
qemuDomainResetDeviceRemoval(vm);
return ret; return ret;
} }
static int static int
qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver, qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainHostdevDefPtr detach) virDomainHostdevDefPtr detach,
bool async)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
virDomainHostdevSubsysPCIPtr pcisrc = &detach->source.subsys.u.pci; virDomainHostdevSubsysPCIPtr pcisrc = &detach->source.subsys.u.pci;
@ -5009,7 +5032,8 @@ qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver,
return -1; return -1;
} }
qemuDomainMarkDeviceForRemoval(vm, detach->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, detach->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
@ -5022,7 +5046,8 @@ qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver,
static int static int
qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver, qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainHostdevDefPtr detach) virDomainHostdevDefPtr detach,
bool async)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
int ret; int ret;
@ -5033,7 +5058,8 @@ qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver,
return -1; return -1;
} }
qemuDomainMarkDeviceForRemoval(vm, detach->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, detach->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
@ -5046,7 +5072,8 @@ qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver,
static int static int
qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver, qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainHostdevDefPtr detach) virDomainHostdevDefPtr detach,
bool async)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1; int ret = -1;
@ -5057,7 +5084,8 @@ qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver,
return -1; return -1;
} }
qemuDomainMarkDeviceForRemoval(vm, detach->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, detach->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
@ -5071,7 +5099,8 @@ qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver,
static int static int
qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver, qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainHostdevDefPtr detach) virDomainHostdevDefPtr detach,
bool async)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1; int ret = -1;
@ -5082,7 +5111,8 @@ qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver,
return -1; return -1;
} }
qemuDomainMarkDeviceForRemoval(vm, detach->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, detach->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
@ -5097,7 +5127,8 @@ qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver,
static int static int
qemuDomainDetachMediatedDevice(virQEMUDriverPtr driver, qemuDomainDetachMediatedDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainHostdevDefPtr detach) virDomainHostdevDefPtr detach,
bool async)
{ {
int ret = -1; int ret = -1;
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
@ -5108,7 +5139,8 @@ qemuDomainDetachMediatedDevice(virQEMUDriverPtr driver,
return -1; return -1;
} }
qemuDomainMarkDeviceForRemoval(vm, detach->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, detach->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
@ -5122,7 +5154,8 @@ qemuDomainDetachMediatedDevice(virQEMUDriverPtr driver,
static int static int
qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver, qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainHostdevDefPtr detach) virDomainHostdevDefPtr detach,
bool async)
{ {
int ret = -1; int ret = -1;
@ -5131,19 +5164,19 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
switch (detach->source.subsys.type) { switch (detach->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
ret = qemuDomainDetachHostPCIDevice(driver, vm, detach); ret = qemuDomainDetachHostPCIDevice(driver, vm, detach, async);
break; break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
ret = qemuDomainDetachHostUSBDevice(driver, vm, detach); ret = qemuDomainDetachHostUSBDevice(driver, vm, detach, async);
break; break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
ret = qemuDomainDetachHostSCSIDevice(driver, vm, detach); ret = qemuDomainDetachHostSCSIDevice(driver, vm, detach, async);
break; break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
ret = qemuDomainDetachSCSIVHostDevice(driver, vm, detach); ret = qemuDomainDetachSCSIVHostDevice(driver, vm, detach, async);
break; break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
ret = qemuDomainDetachMediatedDevice(driver, vm, detach); ret = qemuDomainDetachMediatedDevice(driver, vm, detach, async);
break; break;
default: default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@ -5155,11 +5188,13 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
if (ret < 0) { if (ret < 0) {
if (virDomainObjIsActive(vm)) if (virDomainObjIsActive(vm))
virDomainAuditHostdev(vm, detach, "detach", false); virDomainAuditHostdev(vm, detach, "detach", false);
} else if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) { } else if (!async &&
(ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) {
ret = qemuDomainRemoveHostDevice(driver, vm, detach); ret = qemuDomainRemoveHostDevice(driver, vm, detach);
} }
qemuDomainResetDeviceRemoval(vm); if (!async)
qemuDomainResetDeviceRemoval(vm);
return ret; return ret;
} }
@ -5167,7 +5202,8 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
/* search for a hostdev matching dev and detach it */ /* search for a hostdev matching dev and detach it */
int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDeviceDefPtr dev) virDomainDeviceDefPtr dev,
bool async)
{ {
virDomainHostdevDefPtr hostdev = dev->data.hostdev; virDomainHostdevDefPtr hostdev = dev->data.hostdev;
virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys; virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
@ -5242,16 +5278,17 @@ int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
* function so that mac address / virtualport are reset * function so that mac address / virtualport are reset
*/ */
if (detach->parent.type == VIR_DOMAIN_DEVICE_NET) if (detach->parent.type == VIR_DOMAIN_DEVICE_NET)
return qemuDomainDetachNetDevice(driver, vm, &detach->parent); return qemuDomainDetachNetDevice(driver, vm, &detach->parent, async);
else else
return qemuDomainDetachThisHostDevice(driver, vm, detach); return qemuDomainDetachThisHostDevice(driver, vm, detach, async);
} }
int int
qemuDomainDetachShmemDevice(virQEMUDriverPtr driver, qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainShmemDefPtr dev) virDomainShmemDefPtr dev,
bool async)
{ {
int ret = -1; int ret = -1;
ssize_t idx = -1; ssize_t idx = -1;
@ -5282,7 +5319,8 @@ qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
return -1; return -1;
} }
qemuDomainMarkDeviceForRemoval(vm, &shmem->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, &shmem->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorDelDevice(priv->mon, shmem->info.alias) < 0) { if (qemuMonitorDelDevice(priv->mon, shmem->info.alias) < 0) {
@ -5304,7 +5342,8 @@ qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
int int
qemuDomainDetachWatchdog(virQEMUDriverPtr driver, qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainWatchdogDefPtr dev) virDomainWatchdogDefPtr dev,
bool async)
{ {
int ret = -1; int ret = -1;
virDomainWatchdogDefPtr watchdog = vm->def->watchdog; virDomainWatchdogDefPtr watchdog = vm->def->watchdog;
@ -5336,7 +5375,8 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
return -1; return -1;
} }
qemuDomainMarkDeviceForRemoval(vm, &watchdog->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, &watchdog->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorDelDevice(priv->mon, watchdog->info.alias) < 0) { if (qemuMonitorDelDevice(priv->mon, watchdog->info.alias) < 0) {
@ -5346,11 +5386,16 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
if (qemuDomainObjExitMonitor(driver, vm) < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup; goto cleanup;
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if (async) {
ret = qemuDomainRemoveWatchdog(driver, vm, watchdog); ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveWatchdog(driver, vm, watchdog);
}
cleanup: cleanup:
qemuDomainResetDeviceRemoval(vm); if (!async)
qemuDomainResetDeviceRemoval(vm);
return ret; return ret;
} }
@ -5358,7 +5403,8 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
int int
qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver, qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainRedirdevDefPtr dev) virDomainRedirdevDefPtr dev,
bool async)
{ {
int ret = -1; int ret = -1;
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
@ -5379,7 +5425,8 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
return -1; return -1;
} }
qemuDomainMarkDeviceForRemoval(vm, &tmpRedirdevDef->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, &tmpRedirdevDef->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorDelDevice(priv->mon, tmpRedirdevDef->info.alias) < 0) { if (qemuMonitorDelDevice(priv->mon, tmpRedirdevDef->info.alias) < 0) {
@ -5389,11 +5436,16 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
if (qemuDomainObjExitMonitor(driver, vm) < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup; goto cleanup;
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if (async) {
ret = qemuDomainRemoveRedirdevDevice(driver, vm, tmpRedirdevDef); ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveRedirdevDevice(driver, vm, tmpRedirdevDef);
}
cleanup: cleanup:
qemuDomainResetDeviceRemoval(vm); if (!async)
qemuDomainResetDeviceRemoval(vm);
return ret; return ret;
} }
@ -5401,7 +5453,8 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
int int
qemuDomainDetachNetDevice(virQEMUDriverPtr driver, qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDeviceDefPtr dev) virDomainDeviceDefPtr dev,
bool async)
{ {
int detachidx, ret = -1; int detachidx, ret = -1;
virDomainNetDefPtr detach = NULL; virDomainNetDefPtr detach = NULL;
@ -5414,7 +5467,8 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) { if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
ret = qemuDomainDetachThisHostDevice(driver, vm, ret = qemuDomainDetachThisHostDevice(driver, vm,
virDomainNetGetActualHostdev(detach)); virDomainNetGetActualHostdev(detach),
async);
goto cleanup; goto cleanup;
} }
@ -5442,7 +5496,8 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
*/ */
ignore_value(qemuInterfaceStopDevice(detach)); ignore_value(qemuInterfaceStopDevice(detach));
qemuDomainMarkDeviceForRemoval(vm, &detach->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, &detach->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
@ -5454,11 +5509,16 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
if (qemuDomainObjExitMonitor(driver, vm) < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup; goto cleanup;
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if (async) {
ret = qemuDomainRemoveNetDevice(driver, vm, detach); ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveNetDevice(driver, vm, detach);
}
cleanup: cleanup:
qemuDomainResetDeviceRemoval(vm); if (!async)
qemuDomainResetDeviceRemoval(vm);
return ret; return ret;
} }
@ -5585,7 +5645,8 @@ int qemuDomainDetachLease(virQEMUDriverPtr driver,
int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainChrDefPtr chr) virDomainChrDefPtr chr,
bool async)
{ {
int ret = -1; int ret = -1;
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
@ -5609,7 +5670,8 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
if (qemuBuildChrDeviceStr(&devstr, vmdef, chr, priv->qemuCaps) < 0) if (qemuBuildChrDeviceStr(&devstr, vmdef, chr, priv->qemuCaps) < 0)
goto cleanup; goto cleanup;
qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) { if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) {
@ -5619,11 +5681,16 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
if (qemuDomainObjExitMonitor(driver, vm) < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup; goto cleanup;
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if (async) {
ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr); ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr);
}
cleanup: cleanup:
qemuDomainResetDeviceRemoval(vm); if (!async)
qemuDomainResetDeviceRemoval(vm);
VIR_FREE(devstr); VIR_FREE(devstr);
return ret; return ret;
} }
@ -5632,7 +5699,8 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
int int
qemuDomainDetachRNGDevice(virQEMUDriverPtr driver, qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainRNGDefPtr rng) virDomainRNGDefPtr rng,
bool async)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
ssize_t idx; ssize_t idx;
@ -5656,18 +5724,24 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
return -1; return -1;
} }
qemuDomainMarkDeviceForRemoval(vm, &tmpRNG->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, &tmpRNG->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
rc = qemuMonitorDelDevice(priv->mon, tmpRNG->info.alias); rc = qemuMonitorDelDevice(priv->mon, tmpRNG->info.alias);
if (qemuDomainObjExitMonitor(driver, vm) || rc < 0) if (qemuDomainObjExitMonitor(driver, vm) || rc < 0)
goto cleanup; goto cleanup;
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if (async) {
ret = qemuDomainRemoveRNGDevice(driver, vm, tmpRNG); ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveRNGDevice(driver, vm, tmpRNG);
}
cleanup: cleanup:
qemuDomainResetDeviceRemoval(vm); if (!async)
qemuDomainResetDeviceRemoval(vm);
return ret; return ret;
} }
@ -5675,7 +5749,8 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
int int
qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver, qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainMemoryDefPtr memdef) virDomainMemoryDefPtr memdef,
bool async)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
virDomainMemoryDefPtr mem; virDomainMemoryDefPtr mem;
@ -5701,18 +5776,24 @@ qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
return -1; return -1;
} }
qemuDomainMarkDeviceForRemoval(vm, &mem->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, &mem->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
rc = qemuMonitorDelDevice(priv->mon, mem->info.alias); rc = qemuMonitorDelDevice(priv->mon, mem->info.alias);
if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
goto cleanup; goto cleanup;
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if (async) {
ret = qemuDomainRemoveMemoryDevice(driver, vm, mem); ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveMemoryDevice(driver, vm, mem);
}
cleanup: cleanup:
qemuDomainResetDeviceRemoval(vm); if (!async)
qemuDomainResetDeviceRemoval(vm);
return ret; return ret;
} }
@ -6380,7 +6461,8 @@ qemuDomainSetVcpuInternal(virQEMUDriverPtr driver,
int int
qemuDomainDetachInputDevice(virDomainObjPtr vm, qemuDomainDetachInputDevice(virDomainObjPtr vm,
virDomainInputDefPtr def) virDomainInputDefPtr def,
bool async)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
virQEMUDriverPtr driver = priv->driver; virQEMUDriverPtr driver = priv->driver;
@ -6410,7 +6492,8 @@ qemuDomainDetachInputDevice(virDomainObjPtr vm,
break; break;
} }
qemuDomainMarkDeviceForRemoval(vm, &input->info); if (!async)
qemuDomainMarkDeviceForRemoval(vm, &input->info);
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorDelDevice(priv->mon, input->info.alias)) { if (qemuMonitorDelDevice(priv->mon, input->info.alias)) {
@ -6420,10 +6503,15 @@ qemuDomainDetachInputDevice(virDomainObjPtr vm,
if (qemuDomainObjExitMonitor(driver, vm) < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup; goto cleanup;
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if (async) {
ret = qemuDomainRemoveInputDevice(vm, input); ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveInputDevice(vm, input);
}
cleanup: cleanup:
qemuDomainResetDeviceRemoval(vm); if (!async)
qemuDomainResetDeviceRemoval(vm);
return ret; return ret;
} }

View File

@ -87,7 +87,8 @@ int qemuDomainAttachMemory(virQEMUDriverPtr driver,
virDomainMemoryDefPtr mem); virDomainMemoryDefPtr mem);
int qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver, int qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainMemoryDefPtr memdef); virDomainMemoryDefPtr memdef,
bool async);
int qemuDomainChangeGraphics(virQEMUDriverPtr driver, int qemuDomainChangeGraphics(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainGraphicsDefPtr dev); virDomainGraphicsDefPtr dev);
@ -106,26 +107,33 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver,
int linkstate); int linkstate);
int qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, int qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDeviceDefPtr dev); virDomainDeviceDefPtr dev,
bool async);
int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDeviceDefPtr dev); virDomainDeviceDefPtr dev,
bool async);
int qemuDomainDetachNetDevice(virQEMUDriverPtr driver, int qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDeviceDefPtr dev); virDomainDeviceDefPtr dev,
bool async);
int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDeviceDefPtr dev); virDomainDeviceDefPtr dev,
bool async);
int qemuDomainDetachShmemDevice(virQEMUDriverPtr driver, int qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainShmemDefPtr dev); virDomainShmemDefPtr dev,
bool async);
int qemuDomainDetachWatchdog(virQEMUDriverPtr driver, int qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainWatchdogDefPtr watchdog); virDomainWatchdogDefPtr watchdog,
bool async);
int qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver, int qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainRedirdevDefPtr dev); virDomainRedirdevDefPtr dev,
bool async);
int qemuDomainAttachInputDevice(virQEMUDriverPtr driver, int qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
@ -142,13 +150,15 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
virDomainChrDefPtr chr); virDomainChrDefPtr chr);
int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainChrDefPtr chr); virDomainChrDefPtr chr,
bool async);
int qemuDomainAttachRNGDevice(virQEMUDriverPtr driver, int qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainRNGDefPtr rng); virDomainRNGDefPtr rng);
int qemuDomainDetachRNGDevice(virQEMUDriverPtr driver, int qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainRNGDefPtr rng); virDomainRNGDefPtr rng,
bool async);
void qemuDomainRemoveVcpuAlias(virQEMUDriverPtr driver, void qemuDomainRemoveVcpuAlias(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
@ -184,6 +194,7 @@ int qemuDomainSetVcpuInternal(virQEMUDriverPtr driver,
bool state); bool state);
int qemuDomainDetachInputDevice(virDomainObjPtr vm, int qemuDomainDetachInputDevice(virDomainObjPtr vm,
virDomainInputDefPtr def); virDomainInputDefPtr def,
bool async);
#endif /* __QEMU_HOTPLUG_H__ */ #endif /* __QEMU_HOTPLUG_H__ */

View File

@ -142,22 +142,23 @@ testQemuHotplugAttach(virDomainObjPtr vm,
static int static int
testQemuHotplugDetach(virDomainObjPtr vm, testQemuHotplugDetach(virDomainObjPtr vm,
virDomainDeviceDefPtr dev) virDomainDeviceDefPtr dev,
bool async)
{ {
int ret = -1; int ret = -1;
switch (dev->type) { switch (dev->type) {
case VIR_DOMAIN_DEVICE_DISK: case VIR_DOMAIN_DEVICE_DISK:
ret = qemuDomainDetachDeviceDiskLive(&driver, vm, dev); ret = qemuDomainDetachDeviceDiskLive(&driver, vm, dev, async);
break; break;
case VIR_DOMAIN_DEVICE_CHR: case VIR_DOMAIN_DEVICE_CHR:
ret = qemuDomainDetachChrDevice(&driver, vm, dev->data.chr); ret = qemuDomainDetachChrDevice(&driver, vm, dev->data.chr, async);
break; break;
case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_SHMEM:
ret = qemuDomainDetachShmemDevice(&driver, vm, dev->data.shmem); ret = qemuDomainDetachShmemDevice(&driver, vm, dev->data.shmem, async);
break; break;
case VIR_DOMAIN_DEVICE_WATCHDOG: case VIR_DOMAIN_DEVICE_WATCHDOG:
ret = qemuDomainDetachWatchdog(&driver, vm, dev->data.watchdog); ret = qemuDomainDetachWatchdog(&driver, vm, dev->data.watchdog, async);
break; break;
default: default:
VIR_TEST_VERBOSE("device type '%s' cannot be detached\n", VIR_TEST_VERBOSE("device type '%s' cannot be detached\n",
@ -322,7 +323,7 @@ testQemuHotplug(const void *data)
break; break;
case DETACH: case DETACH:
ret = testQemuHotplugDetach(vm, dev); ret = testQemuHotplugDetach(vm, dev, false);
if (ret == 0 || fail) if (ret == 0 || fail)
ret = testQemuHotplugCheckResult(vm, domain_xml, ret = testQemuHotplugCheckResult(vm, domain_xml,
domain_filename, fail); domain_filename, fail);