From 2c396c9f38179ca8a2428d30bc26be1bb05789c1 Mon Sep 17 00:00:00 2001 Message-Id: <2c396c9f38179ca8a2428d30bc26be1bb05789c1@dist-git> From: Michal Privoznik Date: Thu, 11 Apr 2019 15:14:25 -0400 Subject: [PATCH] qemu_hotplug: Introduce and use qemuDomainDeleteDevice The aim of this function will be to fix return value of qemuMonitorDelDevice() in one specific case. But that is yet to come. Right now this is nothing but a plain substitution. Signed-off-by: Michal Privoznik ACKed-by: Peter Krempa (cherry picked from commit 4cd13478ac331f5e42c926d4f2111dd89d2970a6) Partially-Resolves: https://bugzilla.redhat.com/1658198 Signed-off-by: Laine Stump Conflicts: src/qemu/qemu_hotplug.c: - qemuDomainDetachExtensionDevice() (erroneously) added to qemuDomainDetachControllerDevice upstream, doesn't exist downstream. Signed-off-by: Laine Stump Message-Id: <20190411191453.24055-14-laine@redhat.com> Acked-by: Michal Privoznik --- src/qemu/qemu_hotplug.c | 239 ++++++++++++++-------------------------- 1 file changed, 82 insertions(+), 157 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 963b87f798..1f41efa180 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -68,6 +68,45 @@ VIR_LOG_INIT("qemu.qemu_hotplug"); unsigned long long qemuDomainRemoveDeviceWaitTime = 1000ull * 5; +/** + * qemuDomainDeleteDevice: + * @vm: domain object + * @alias: device to remove + * + * This is a wrapper over qemuMonitorDelDevice() plus enter/exit + * monitor calls. This function MUST be used instead of plain + * qemuMonitorDelDevice() in all places where @alias represents a + * device from domain XML, i.e. caller marks the device for + * removal and then calls qemuDomainWaitForDeviceRemoval() + * followed by qemuDomainRemove*Device(). + * + * For collateral devices (e.g. extension devices like zPCI) it + * is safe to use plain qemuMonitorDelDevice(). + * + * Upon entry, @vm must be locked. + * + * Returns: 0 on success, + * -1 otherwise. + */ +static int +qemuDomainDeleteDevice(virDomainObjPtr vm, + const char *alias) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + virQEMUDriverPtr driver = priv->driver; + int rc; + + qemuDomainObjEnterMonitor(driver, vm); + + rc = qemuMonitorDelDevice(priv->mon, alias); + + if (qemuDomainObjExitMonitor(driver, vm) < 0) + rc = -1; + + return rc; +} + + /** * qemuHotplugPrepareDiskAccess: * @driver: qemu driver struct @@ -4689,7 +4728,6 @@ qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver, bool async) { int ret = -1; - qemuDomainObjPrivatePtr priv = vm->privateData; if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) { virReportError(VIR_ERR_OPERATION_FAILED, @@ -4701,15 +4739,11 @@ qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver, if (!async) qemuDomainMarkDeviceForRemoval(vm, &detach->info); - qemuDomainObjEnterMonitor(driver, vm); - if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { - if (qemuDomainObjExitMonitor(driver, vm) < 0) - goto cleanup; - virDomainAuditDisk(vm, detach->src, NULL, "detach", false); + if (qemuDomainDeleteDevice(vm, detach->info.alias) < 0) { + if (virDomainObjIsActive(vm)) + virDomainAuditDisk(vm, detach->src, NULL, "detach", false); goto cleanup; } - if (qemuDomainObjExitMonitor(driver, vm) < 0) - goto cleanup; if (async) { ret = 0; @@ -4731,7 +4765,6 @@ qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, bool async) { int ret = -1; - qemuDomainObjPrivatePtr priv = vm->privateData; if (qemuDomainDiskBlockJobIsActive(detach)) goto cleanup; @@ -4739,15 +4772,11 @@ qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, if (!async) qemuDomainMarkDeviceForRemoval(vm, &detach->info); - qemuDomainObjEnterMonitor(driver, vm); - if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { - if (qemuDomainObjExitMonitor(driver, vm) < 0) - goto cleanup; - virDomainAuditDisk(vm, detach->src, NULL, "detach", false); + if (qemuDomainDeleteDevice(vm, detach->info.alias) < 0) { + if (virDomainObjIsActive(vm)) + virDomainAuditDisk(vm, detach->src, NULL, "detach", false); goto cleanup; } - if (qemuDomainObjExitMonitor(driver, vm) < 0) - goto cleanup; if (async) { ret = 0; @@ -4882,7 +4911,6 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, { int idx, ret = -1; virDomainControllerDefPtr detach = NULL; - qemuDomainObjPrivatePtr priv = vm->privateData; if ((idx = virDomainControllerFind(vm->def, dev->data.controller->type, @@ -4928,12 +4956,7 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, if (!async) qemuDomainMarkDeviceForRemoval(vm, &detach->info); - qemuDomainObjEnterMonitor(driver, vm); - if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { - ignore_value(qemuDomainObjExitMonitor(driver, vm)); - goto cleanup; - } - if (qemuDomainObjExitMonitor(driver, vm) < 0) + if (qemuDomainDeleteDevice(vm, detach->info.alias) < 0) goto cleanup; if (async) { @@ -4950,14 +4973,11 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, } static int -qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver, - virDomainObjPtr vm, +qemuDomainDetachHostPCIDevice(virDomainObjPtr vm, virDomainHostdevDefPtr detach, bool async) { - qemuDomainObjPrivatePtr priv = vm->privateData; virDomainHostdevSubsysPCIPtr pcisrc = &detach->source.subsys.u.pci; - int ret; if (qemuIsMultiFunctionDevice(vm->def, detach->info)) { virReportError(VIR_ERR_OPERATION_FAILED, @@ -4970,23 +4990,14 @@ qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver, if (!async) qemuDomainMarkDeviceForRemoval(vm, detach->info); - qemuDomainObjEnterMonitor(driver, vm); - ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); - if (qemuDomainObjExitMonitor(driver, vm) < 0) - ret = -1; - - return ret; + return qemuDomainDeleteDevice(vm, detach->info->alias); } static int -qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver, - virDomainObjPtr vm, +qemuDomainDetachHostUSBDevice(virDomainObjPtr vm, virDomainHostdevDefPtr detach, bool async) { - qemuDomainObjPrivatePtr priv = vm->privateData; - int ret; - if (!detach->info->alias) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("device cannot be detached without a device alias")); @@ -4996,23 +5007,14 @@ qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver, if (!async) qemuDomainMarkDeviceForRemoval(vm, detach->info); - qemuDomainObjEnterMonitor(driver, vm); - ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); - if (qemuDomainObjExitMonitor(driver, vm) < 0) - ret = -1; - - return ret; + return qemuDomainDeleteDevice(vm, detach->info->alias); } static int -qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver, - virDomainObjPtr vm, +qemuDomainDetachHostSCSIDevice(virDomainObjPtr vm, virDomainHostdevDefPtr detach, bool async) { - qemuDomainObjPrivatePtr priv = vm->privateData; - int ret = -1; - if (!detach->info->alias) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("device cannot be detached without a device alias")); @@ -5022,24 +5024,14 @@ qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver, if (!async) qemuDomainMarkDeviceForRemoval(vm, detach->info); - qemuDomainObjEnterMonitor(driver, vm); - ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); - - if (qemuDomainObjExitMonitor(driver, vm) < 0) - return -1; - - return ret; + return qemuDomainDeleteDevice(vm, detach->info->alias); } static int -qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver, - virDomainObjPtr vm, +qemuDomainDetachSCSIVHostDevice(virDomainObjPtr vm, virDomainHostdevDefPtr detach, bool async) { - qemuDomainObjPrivatePtr priv = vm->privateData; - int ret = -1; - if (!detach->info->alias) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("device cannot be detached without a device alias")); @@ -5049,25 +5041,15 @@ qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver, if (!async) qemuDomainMarkDeviceForRemoval(vm, detach->info); - qemuDomainObjEnterMonitor(driver, vm); - ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); - - if (qemuDomainObjExitMonitor(driver, vm) < 0) - return -1; - - return ret; + return qemuDomainDeleteDevice(vm, detach->info->alias); } static int -qemuDomainDetachMediatedDevice(virQEMUDriverPtr driver, - virDomainObjPtr vm, +qemuDomainDetachMediatedDevice(virDomainObjPtr vm, virDomainHostdevDefPtr detach, bool async) { - int ret = -1; - qemuDomainObjPrivatePtr priv = vm->privateData; - if (!detach->info->alias) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("device cannot be detached without a device alias")); @@ -5077,12 +5059,7 @@ qemuDomainDetachMediatedDevice(virQEMUDriverPtr driver, if (!async) qemuDomainMarkDeviceForRemoval(vm, detach->info); - qemuDomainObjEnterMonitor(driver, vm); - ret = qemuMonitorDelDevice(priv->mon, detach->info->alias); - if (qemuDomainObjExitMonitor(driver, vm) < 0) - ret = -1; - - return ret; + return qemuDomainDeleteDevice(vm, detach->info->alias); } @@ -5099,19 +5076,19 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver, switch (detach->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: - ret = qemuDomainDetachHostPCIDevice(driver, vm, detach, async); + ret = qemuDomainDetachHostPCIDevice(vm, detach, async); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: - ret = qemuDomainDetachHostUSBDevice(driver, vm, detach, async); + ret = qemuDomainDetachHostUSBDevice(vm, detach, async); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: - ret = qemuDomainDetachHostSCSIDevice(driver, vm, detach, async); + ret = qemuDomainDetachHostSCSIDevice(vm, detach, async); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: - ret = qemuDomainDetachSCSIVHostDevice(driver, vm, detach, async); + ret = qemuDomainDetachSCSIVHostDevice(vm, detach, async); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: - ret = qemuDomainDetachMediatedDevice(driver, vm, detach, async); + ret = qemuDomainDetachMediatedDevice(vm, detach, async); break; default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -5228,7 +5205,6 @@ qemuDomainDetachShmemDevice(virQEMUDriverPtr driver, int ret = -1; ssize_t idx = -1; virDomainShmemDefPtr shmem = NULL; - qemuDomainObjPrivatePtr priv = vm->privateData; if ((idx = virDomainShmemDefFind(vm->def, dev)) < 0) { virReportError(VIR_ERR_DEVICE_MISSING, @@ -5257,12 +5233,7 @@ qemuDomainDetachShmemDevice(virQEMUDriverPtr driver, if (!async) qemuDomainMarkDeviceForRemoval(vm, &shmem->info); - qemuDomainObjEnterMonitor(driver, vm); - if (qemuMonitorDelDevice(priv->mon, shmem->info.alias) < 0) { - ignore_value(qemuDomainObjExitMonitor(driver, vm)); - goto cleanup; - } - if (qemuDomainObjExitMonitor(driver, vm) < 0) + if (qemuDomainDeleteDevice(vm, shmem->info.alias) < 0) goto cleanup; if (async) { @@ -5287,7 +5258,6 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver, { int ret = -1; virDomainWatchdogDefPtr watchdog = vm->def->watchdog; - qemuDomainObjPrivatePtr priv = vm->privateData; if (!watchdog) { virReportError(VIR_ERR_DEVICE_MISSING, "%s", @@ -5318,12 +5288,7 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver, if (!async) qemuDomainMarkDeviceForRemoval(vm, &watchdog->info); - qemuDomainObjEnterMonitor(driver, vm); - if (qemuMonitorDelDevice(priv->mon, watchdog->info.alias) < 0) { - ignore_value(qemuDomainObjExitMonitor(driver, vm)); - goto cleanup; - } - if (qemuDomainObjExitMonitor(driver, vm) < 0) + if (qemuDomainDeleteDevice(vm, watchdog->info.alias) < 0) goto cleanup; if (async) { @@ -5347,7 +5312,6 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver, bool async) { int ret = -1; - qemuDomainObjPrivatePtr priv = vm->privateData; virDomainRedirdevDefPtr tmpRedirdevDef; ssize_t idx; @@ -5368,12 +5332,7 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver, if (!async) qemuDomainMarkDeviceForRemoval(vm, &tmpRedirdevDef->info); - qemuDomainObjEnterMonitor(driver, vm); - if (qemuMonitorDelDevice(priv->mon, tmpRedirdevDef->info.alias) < 0) { - ignore_value(qemuDomainObjExitMonitor(driver, vm)); - goto cleanup; - } - if (qemuDomainObjExitMonitor(driver, vm) < 0) + if (qemuDomainDeleteDevice(vm, tmpRedirdevDef->info.alias) < 0) goto cleanup; if (async) { @@ -5398,7 +5357,6 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver, { int detachidx, ret = -1; virDomainNetDefPtr detach = NULL; - qemuDomainObjPrivatePtr priv = vm->privateData; if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net)) < 0) goto cleanup; @@ -5439,15 +5397,11 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver, if (!async) qemuDomainMarkDeviceForRemoval(vm, &detach->info); - qemuDomainObjEnterMonitor(driver, vm); - if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { - if (qemuDomainObjExitMonitor(driver, vm) < 0) - goto cleanup; - virDomainAuditNet(vm, detach, NULL, "detach", false); + if (qemuDomainDeleteDevice(vm, detach->info.alias) < 0) { + if (virDomainObjIsActive(vm)) + virDomainAuditNet(vm, detach, NULL, "detach", false); goto cleanup; } - if (qemuDomainObjExitMonitor(driver, vm) < 0) - goto cleanup; if (async) { ret = 0; @@ -5610,20 +5564,19 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, if (!async && !guestfwd) qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info); - qemuDomainObjEnterMonitor(driver, vm); if (guestfwd) { - if (qemuMonitorRemoveNetdev(priv->mon, tmpChr->info.alias) < 0) { - ignore_value(qemuDomainObjExitMonitor(driver, vm)); + int rc; + qemuDomainObjEnterMonitor(driver, vm); + rc = qemuMonitorRemoveNetdev(priv->mon, tmpChr->info.alias); + if (qemuDomainObjExitMonitor(driver, vm) < 0) + rc = -1; + + if (rc < 0) goto cleanup; - } } else { - if (qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) { - ignore_value(qemuDomainObjExitMonitor(driver, vm)); + if (qemuDomainDeleteDevice(vm, tmpChr->info.alias) < 0) goto cleanup; - } } - if (qemuDomainObjExitMonitor(driver, vm) < 0) - goto cleanup; if (guestfwd) { ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr, false); @@ -5647,10 +5600,8 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver, virDomainRNGDefPtr rng, bool async) { - qemuDomainObjPrivatePtr priv = vm->privateData; ssize_t idx; virDomainRNGDefPtr tmpRNG; - int rc; int ret = -1; if ((idx = virDomainRNGFind(vm->def, rng)) < 0) { @@ -5672,9 +5623,7 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver, if (!async) qemuDomainMarkDeviceForRemoval(vm, &tmpRNG->info); - qemuDomainObjEnterMonitor(driver, vm); - rc = qemuMonitorDelDevice(priv->mon, tmpRNG->info.alias); - if (qemuDomainObjExitMonitor(driver, vm) || rc < 0) + if (qemuDomainDeleteDevice(vm, tmpRNG->info.alias) < 0) goto cleanup; if (async) { @@ -5697,10 +5646,8 @@ qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver, virDomainMemoryDefPtr memdef, bool async) { - qemuDomainObjPrivatePtr priv = vm->privateData; virDomainMemoryDefPtr mem; int idx; - int rc; int ret = -1; qemuDomainMemoryDeviceAlignSize(vm->def, memdef); @@ -5724,9 +5671,7 @@ qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver, if (!async) qemuDomainMarkDeviceForRemoval(vm, &mem->info); - qemuDomainObjEnterMonitor(driver, vm); - rc = qemuMonitorDelDevice(priv->mon, mem->info.alias); - if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) + if (qemuDomainDeleteDevice(vm, mem->info.alias) < 0) goto cleanup; if (async) { @@ -5831,15 +5776,9 @@ qemuDomainHotplugDelVcpu(virQEMUDriverPtr driver, qemuDomainMarkDeviceAliasForRemoval(vm, vcpupriv->alias); - qemuDomainObjEnterMonitor(driver, vm); - - rc = qemuMonitorDelDevice(qemuDomainGetMonitor(vm), vcpupriv->alias); - - if (qemuDomainObjExitMonitor(driver, vm) < 0) - goto cleanup; - - if (rc < 0) { - virDomainAuditVcpu(vm, oldvcpus, oldvcpus - nvcpus, "update", false); + if (qemuDomainDeleteDevice(vm, vcpupriv->alias) < 0) { + if (virDomainObjIsActive(vm)) + virDomainAuditVcpu(vm, oldvcpus, oldvcpus - nvcpus, "update", false); goto cleanup; } @@ -6409,8 +6348,6 @@ qemuDomainDetachInputDevice(virDomainObjPtr vm, virDomainInputDefPtr def, bool async) { - qemuDomainObjPrivatePtr priv = vm->privateData; - virQEMUDriverPtr driver = priv->driver; virDomainInputDefPtr input; int ret = -1; int idx; @@ -6440,12 +6377,7 @@ qemuDomainDetachInputDevice(virDomainObjPtr vm, if (!async) qemuDomainMarkDeviceForRemoval(vm, &input->info); - qemuDomainObjEnterMonitor(driver, vm); - if (qemuMonitorDelDevice(priv->mon, input->info.alias) < 0) { - ignore_value(qemuDomainObjExitMonitor(driver, vm)); - goto cleanup; - } - if (qemuDomainObjExitMonitor(driver, vm) < 0) + if (qemuDomainDeleteDevice(vm, input->info.alias) < 0) goto cleanup; if (async) { @@ -6467,8 +6399,6 @@ qemuDomainDetachVsockDevice(virDomainObjPtr vm, virDomainVsockDefPtr dev, bool async) { - qemuDomainObjPrivatePtr priv = vm->privateData; - virQEMUDriverPtr driver = priv->driver; virDomainVsockDefPtr vsock = vm->def->vsock; int ret = -1; @@ -6483,12 +6413,7 @@ qemuDomainDetachVsockDevice(virDomainObjPtr vm, if (!async) qemuDomainMarkDeviceForRemoval(vm, &vsock->info); - qemuDomainObjEnterMonitor(driver, vm); - if (qemuMonitorDelDevice(priv->mon, vsock->info.alias) < 0) { - ignore_value(qemuDomainObjExitMonitor(driver, vm)); - goto cleanup; - } - if (qemuDomainObjExitMonitor(driver, vm) < 0) + if (qemuDomainDeleteDevice(vm, vsock->info.alias) < 0) goto cleanup; if (async) { -- 2.21.0