[libvirt] [PATCH v3 REBASE 03/12] qemu: support host usb device unplug

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Tue Oct 15 14:29:47 UTC 2019


Handle host usb device unplug in DEVICE_DELETED handle execution
path.

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy at virtuozzo.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413 at gmail.com>
---
 src/qemu/qemu_hotplug.c | 38 +++++++++++++++++++++++++++++++-------
 1 file changed, 31 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 4f7858da71..0e161bfd5a 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4400,7 +4400,8 @@ qemuDomainRemoveUSBHostDevice(virQEMUDriverPtr driver,
                               virDomainHostdevDefPtr hostdev)
 {
     qemuHostdevReAttachUSBDevices(driver, vm->def->name, &hostdev, 1);
-    qemuDomainReleaseDeviceAddress(vm, hostdev->info);
+    if (hostdev->deleteAction != VIR_DOMAIN_HOSTDEV_DELETE_ACTION_UNPLUG)
+        qemuDomainReleaseDeviceAddress(vm, hostdev->info);
 }
 
 static void
@@ -4441,6 +4442,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
     VIR_AUTOFREE(char *) drivealias = NULL;
     VIR_AUTOFREE(char *) objAlias = NULL;
     bool is_vfio = false;
+    bool unplug = hostdev->deleteAction == VIR_DOMAIN_HOSTDEV_DELETE_ACTION_UNPLUG;
 
     VIR_DEBUG("Removing host device %s from domain %p %s",
               hostdev->info->alias, vm, vm->def->name);
@@ -4488,16 +4490,24 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
         }
     }
 
-    for (i = 0; i < vm->def->nhostdevs; i++) {
-        if (vm->def->hostdevs[i] == hostdev) {
-            virDomainHostdevRemove(vm->def, i);
-            break;
+    if (!unplug) {
+        for (i = 0; i < vm->def->nhostdevs; i++) {
+            if (vm->def->hostdevs[i] == hostdev) {
+                virDomainHostdevRemove(vm->def, i);
+                break;
+            }
         }
     }
 
     virDomainAuditHostdev(vm, hostdev, "detach", true);
 
-    if (!is_vfio &&
+    /*
+     * In case of unplug the attempt to restore label will fail. But we don't
+     * need to restore the label! In case of separate mount namespace for the
+     * domain we remove device file later in this function. In case of global
+     * mount namespace the device file is deleted or being deleted by systemd.
+     */
+    if (!is_vfio && !unplug &&
         qemuSecurityRestoreHostdevLabel(driver, vm, hostdev) < 0)
         VIR_WARN("Failed to restore host device labelling");
 
@@ -4531,7 +4541,13 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
         break;
     }
 
-    virDomainHostdevDefFree(hostdev);
+    if (unplug) {
+        virDomainHostdevSubsysUSBPtr usbsrc = &hostdev->source.subsys.u.usb;
+        usbsrc->bus = 0;
+        usbsrc->device = 0;
+    } else {
+        virDomainHostdevDefFree(hostdev);
+    }
 
     if (net) {
         if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
@@ -4546,6 +4562,8 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
         virDomainNetDefFree(net);
     }
 
+    hostdev->deleteAction = VIR_DOMAIN_HOSTDEV_DELETE_ACTION_NONE;
+
     return 0;
 }
 
@@ -4984,6 +5002,7 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
     virDomainDeviceInfoPtr info;
     virObjectEventPtr event;
     VIR_AUTOFREE(char *) alias = NULL;
+    bool unplug;
 
     /*
      * save the alias to use when sending a DEVICE_REMOVED event after
@@ -5024,8 +5043,13 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
             return -1;
         break;
     case VIR_DOMAIN_DEVICE_HOSTDEV:
+        unplug = dev->data.hostdev->deleteAction == VIR_DOMAIN_HOSTDEV_DELETE_ACTION_UNPLUG;
+
         if (qemuDomainRemoveHostDevice(driver, vm, dev->data.hostdev) < 0)
             return -1;
+
+        if (unplug)
+            return 0;
         break;
     case VIR_DOMAIN_DEVICE_RNG:
         if (qemuDomainRemoveRNGDevice(driver, vm, dev->data.rng) < 0)
-- 
2.23.0




More information about the libvir-list mailing list