[PATCH v3 07/12] qemu: handle race on device deletion and usb host device plugging

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Imagine host usb device is unplugged from host and as a result we send
command to qemu to delete appropriate device. Then before qemu device is
deleted host usb device is plugged back. Currently code supposes there is
no remnant device in qemu and will try to add new device and the attempt
will fail.

Instead let's check the device is not yet deleted and postpone adding
qemu device to device_deleted event handler.

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@xxxxxxxxxxxxx>
Reviewed-by: Daniel Henrique Barboza <danielhb413@xxxxxxxxx>
---
 src/qemu/qemu_driver.c | 49 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b12b39d61d..e5594835c4 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4655,6 +4655,44 @@ processGuestPanicEvent(virQEMUDriverPtr driver,
 }
 
 
+static int
+qemuCheckHostdevPlugged(virQEMUDriverPtr driver,
+                        virDomainObjPtr vm,
+                        const char *devAlias)
+{
+    virDomainHostdevDefPtr hostdev;
+    virDomainHostdevSubsysUSBPtr usbsrc;
+    virDomainDeviceDef dev;
+    int num;
+
+    if (virDomainDefFindDevice(vm->def, devAlias, &dev, false) < 0)
+        return 0;
+
+    if (dev.type != VIR_DOMAIN_DEVICE_HOSTDEV)
+        return 0;
+
+    hostdev = dev.data.hostdev;
+    if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
+        return 0;
+
+    usbsrc = &hostdev->source.subsys.u.usb;
+    if (!usbsrc->vendor || !usbsrc->product)
+        return 0;
+
+    if ((num = virUSBDeviceFindByVendor(usbsrc->vendor, usbsrc->product,
+                                        NULL, false, NULL)) < 0)
+        return -1;
+
+    if (num == 0)
+        return 0;
+
+    if (qemuDomainAttachHostDevice(driver, vm, hostdev) < 0)
+        return -1;
+
+    return 0;
+}
+
+
 static void
 processDeviceDeletedEvent(virQEMUDriverPtr driver,
                           virDomainObjPtr vm,
@@ -4682,6 +4720,11 @@ processDeviceDeletedEvent(virQEMUDriverPtr driver,
 
         if (qemuDomainRemoveDevice(driver, vm, &dev) < 0)
             goto endjob;
+
+        /* Fall thru and save status file even on error condition because
+         * device is removed successfully and changed configuration need
+         * to be saved in status file. */
+        qemuCheckHostdevPlugged(driver, vm, devAlias);
     }
 
     if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
@@ -5287,6 +5330,12 @@ processUSBAddedEvent(virQEMUDriverPtr driver,
     if (i == vm->def->nhostdevs)
         goto cleanup;
 
+    /* if device is not yet even deleted from qemu then handle plugging later.
+     * Or we failed handling host usb device unplugging, then another attempt of
+     * unplug/plug could help. */
+    if (usbsrc->bus || usbsrc->device)
+        goto cleanup;
+
     if (qemuDomainAttachHostDevice(driver, vm, hostdev) < 0)
         goto cleanup;
 
-- 
2.23.0

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux