[libvirt] [PATCH v2 08/11] qemu: handle host usb device plug/unplug when libvirtd is down

Nikolay Shirokovskiy posted 11 patches 6 years, 5 months ago
There is a newer version of this series
[libvirt] [PATCH v2 08/11] qemu: handle host usb device plug/unplug when libvirtd is down
Posted by Nikolay Shirokovskiy 6 years, 5 months ago
Somebody can easily unplug usb device from host while libvirtd is being
stopped. Also usb device can be plugged or unplugged/plugged back and so
forth. Let's handle such cases.

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
---
 src/qemu/qemu_process.c | 55 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index c9921646e9..8bec36fe2c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3749,6 +3749,58 @@ qemuProcessUpdateDevices(virQEMUDriverPtr driver,
     return ret;
 }
 
+
+static int
+qemuProcessReattachUSBDevices(virQEMUDriverPtr driver,
+                              virDomainObjPtr vm)
+{
+    size_t i;
+
+    for (i = 0; i < vm->def->nhostdevs; i++) {
+        virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
+        virDomainHostdevSubsysUSBPtr usbsrc = &hostdev->source.subsys.u.usb;
+
+        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
+            continue;
+
+        /* don't mess with devices that don't use stable host addressing
+         * with respect to unplug/plug to host
+         */
+        if (!usbsrc->vendor || !usbsrc->product)
+            continue;
+
+        if (!usbsrc->bus && !usbsrc->device) {
+            int num;
+
+            if ((num = virUSBDeviceFindByVendor(usbsrc->vendor, usbsrc->product,
+                                                NULL, false, NULL)) < 0)
+                return -1;
+
+            if (num > 0 &&
+                qemuDomainAttachHostDevice(driver, vm, hostdev) < 0)
+                return -1;
+        } else {
+            virUSBDevicePtr usb;
+
+            if (virUSBDeviceFindByBus(usbsrc->bus, usbsrc->device,
+                                      NULL, false, &usb) < 0)
+                return -1;
+
+            if (!usb) {
+                virDomainDeviceDef dev = { .type = VIR_DOMAIN_DEVICE_HOSTDEV };
+
+                dev.data.hostdev = hostdev;
+                if (qemuDomainDetachDeviceLive(vm, &dev, driver, true, true) < 0)
+                    return -1;
+            }
+            virUSBDeviceFree(usb);
+        }
+    }
+
+    return 0;
+}
+
+
 static int
 qemuDomainPerfRestart(virDomainObjPtr vm)
 {
@@ -8206,6 +8258,9 @@ qemuProcessReconnect(void *opaque)
     if (qemuProcessUpdateDevices(driver, obj) < 0)
         goto error;
 
+    if (qemuProcessReattachUSBDevices(driver, obj) < 0)
+        goto error;
+
     if (qemuRefreshPRManagerState(driver, obj) < 0)
         goto error;
 
-- 
2.23.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 08/11] qemu: handle host usb device plug/unplug when libvirtd is down
Posted by Daniel Henrique Barboza 6 years, 4 months ago

On 9/9/19 8:33 AM, Nikolay Shirokovskiy wrote:
> Somebody can easily unplug usb device from host while libvirtd is being
> stopped. Also usb device can be plugged or unplugged/plugged back and so
> forth. Let's handle such cases.
>
> Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
> ---

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>

>   src/qemu/qemu_process.c | 55 +++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 55 insertions(+)
>
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index c9921646e9..8bec36fe2c 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -3749,6 +3749,58 @@ qemuProcessUpdateDevices(virQEMUDriverPtr driver,
>       return ret;
>   }
>   
> +
> +static int
> +qemuProcessReattachUSBDevices(virQEMUDriverPtr driver,
> +                              virDomainObjPtr vm)
> +{
> +    size_t i;
> +
> +    for (i = 0; i < vm->def->nhostdevs; i++) {
> +        virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
> +        virDomainHostdevSubsysUSBPtr usbsrc = &hostdev->source.subsys.u.usb;
> +
> +        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
> +            continue;
> +
> +        /* don't mess with devices that don't use stable host addressing
> +         * with respect to unplug/plug to host
> +         */
> +        if (!usbsrc->vendor || !usbsrc->product)
> +            continue;
> +
> +        if (!usbsrc->bus && !usbsrc->device) {
> +            int num;
> +
> +            if ((num = virUSBDeviceFindByVendor(usbsrc->vendor, usbsrc->product,
> +                                                NULL, false, NULL)) < 0)
> +                return -1;
> +
> +            if (num > 0 &&
> +                qemuDomainAttachHostDevice(driver, vm, hostdev) < 0)
> +                return -1;
> +        } else {
> +            virUSBDevicePtr usb;
> +
> +            if (virUSBDeviceFindByBus(usbsrc->bus, usbsrc->device,
> +                                      NULL, false, &usb) < 0)
> +                return -1;
> +
> +            if (!usb) {
> +                virDomainDeviceDef dev = { .type = VIR_DOMAIN_DEVICE_HOSTDEV };
> +
> +                dev.data.hostdev = hostdev;
> +                if (qemuDomainDetachDeviceLive(vm, &dev, driver, true, true) < 0)
> +                    return -1;
> +            }
> +            virUSBDeviceFree(usb);
> +        }
> +    }
> +
> +    return 0;
> +}
> +
> +
>   static int
>   qemuDomainPerfRestart(virDomainObjPtr vm)
>   {
> @@ -8206,6 +8258,9 @@ qemuProcessReconnect(void *opaque)
>       if (qemuProcessUpdateDevices(driver, obj) < 0)
>           goto error;
>   
> +    if (qemuProcessReattachUSBDevices(driver, obj) < 0)
> +        goto error;
> +
>       if (qemuRefreshPRManagerState(driver, obj) < 0)
>           goto error;
>   

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