From f30843142aa0836423f5e3ff7a45707eb13ce553 Mon Sep 17 00:00:00 2001 From: Pierre LIBEAU Date: Wed, 31 Aug 2022 14:22:51 +0200 Subject: [PATCH] qemu: Fix race condition when detaching a device If QEMU replies to device_del command with "DeviceNotFound" error, then libvirt doesn't clean the device from the live configuration. This is because qemuMonitorDelDevice() returns -2 to qemuDomainDeleteDevice() and instead of calling qemuDomainRemoveDevice() the qemuDomainDetachDeviceLive() jumps right onto cleanup label. Resolves: https://gitlab.com/libvirt/libvirt/-/issues/359 Signed-off-by: Pierre LIBEAU Signed-off-by: Michal Privoznik Reviewed-by: Michal Privoznik --- src/qemu/qemu_hotplug.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 00727f6ddc..f5d12b4fb3 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -93,6 +93,8 @@ qemuDomainResetDeviceRemoval(virDomainObj *vm); * * Returns: 0 on success, * -1 otherwise. + * -2 device does not exist in qemu, but it still + * exists in libvirt */ static int qemuDomainDeleteDevice(virDomainObj *vm, @@ -124,7 +126,6 @@ qemuDomainDeleteDevice(virDomainObj *vm, * domain XML is queried right after detach API the * device would still be there. */ VIR_DEBUG("Detaching of device %s failed and no event arrived", alias); - rc = 0; } } @@ -5864,6 +5865,7 @@ qemuDomainDetachDeviceLive(virDomainObj *vm, virDomainDeviceDef detach = { .type = match->type }; virDomainDeviceInfo *info = NULL; int ret = -1; + int rc; switch ((virDomainDeviceType)match->type) { /* @@ -6053,7 +6055,10 @@ qemuDomainDetachDeviceLive(virDomainObj *vm, if (!async) qemuDomainMarkDeviceForRemoval(vm, info); - if (qemuDomainDeleteDevice(vm, info->alias) < 0) { + rc = qemuDomainDeleteDevice(vm, info->alias); + if (rc < 0) { + if (rc == -2) + ret = qemuDomainRemoveDevice(driver, vm, &detach); if (virDomainObjIsActive(vm)) qemuDomainRemoveAuditDevice(vm, &detach, false); goto cleanup; -- 2.47.2