Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > ebe084c140192657f9094e135a84202c > files > 112

libvirt-0.8.2-29.el5.src.rpm

From f249a35af3bfe8c58dbcf6f64d59fafd393366eb Mon Sep 17 00:00:00 2001
From: Michal Privoznik <mprivozn@redhat.com>
Date: Thu, 12 Jul 2012 00:35:11 +0800
Subject: [PATCH] qemu: Rollback on used USB devices
To: libvir-list@redhat.com

(cherry picked from commit 2f5fdc886ec7ed8b871ebd0576271f8ee5be1f71)
Resolve BZ:https://bugzilla.redhat.com/show_bug.cgi?id=816601

One of our latest USB device handling patches
05abd1507d66aabb6cad12eeafeb4c4d1911c585 introduced a regression.
That is, we first create a temporary list of all USB devices that
are to be used by domain just starting up. Then we iterate over and
check if a device from the list is in the global list of currently
assigned devices (activeUsbHostdevs). If not, we add it there and
continue with next iteration then. But if a device from temporary
list is either taken already or adding to the activeUsbHostdevs fails,
we remove all devices in temp list from the activeUsbHostdevs list.
Therefore, if a device is already taken we remove it from
activeUsbHostdevs even if we should not. Thus, next time we allow
the device to be assigned to another domain.

Conflicts:

	src/qemu/qemu_hostdev.c

Signed-off-by: Daniel Veillard <veillard@redhat.com>
---
 src/qemu/qemu_driver.c |   28 ++++++++++++----------------
 1 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 68f97ac..0889c7e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3012,7 +3012,7 @@ qemuPrepareHostdevUSBDevices(struct qemud_driver *driver,
                              const char *name,
                              usbDeviceList *list)
 {
-    int i;
+    int i, j;
     unsigned int count;
     usbDevice *tmp;
 
@@ -3031,7 +3031,7 @@ qemuPrepareHostdevUSBDevices(struct qemud_driver *driver,
                 qemuReportError(VIR_ERR_OPERATION_INVALID,
                                 _("USB device %s is already in use"),
                                 usbDeviceGetName(tmp));
-            return -1;
+            goto error;
         }
 
         usbDeviceSetUsedBy(usb, name);
@@ -3043,9 +3043,16 @@ qemuPrepareHostdevUSBDevices(struct qemud_driver *driver,
          * perform rollback on failure.
          */
         if (usbDeviceListAdd(driver->activeUsbHostdevs, usb) < 0)
-            return -1;
+            goto error;
     }
     return 0;
+
+error:
+    for (j = 0; j < i; j++) {
+        tmp = usbDeviceListGet(list, i);
+        usbDeviceListSteal(driver->activeUsbHostdevs, tmp);
+    }
+    return -1;
 }
 
 static int
@@ -3066,8 +3073,7 @@ qemuPrepareHostUSBDevices(struct qemud_driver *driver,
     if (!(list = usbDeviceListNew()))
         goto cleanup;
 
-    /* Loop 1: build temporary list and validate no usb device
-     * is already taken
+    /* Loop 1: build temporary list
      */
     for (i = 0 ; i < nhostdevs ; i++) {
         virDomainHostdevDefPtr hostdev = hostdevs[i];
@@ -3123,7 +3129,7 @@ qemuPrepareHostUSBDevices(struct qemud_driver *driver,
      * wrong, perform rollback.
      */
     if (qemuPrepareHostdevUSBDevices(driver, def->name, list) < 0)
-        goto inactivedevs;
+        goto cleanup;
 
     /* Loop 2: Temporary list was successfully merged with
      * driver list, so steal all items to avoid freeing them
@@ -3135,16 +3141,6 @@ qemuPrepareHostUSBDevices(struct qemud_driver *driver,
     }
 
     ret = 0;
-    goto cleanup;
-
-inactivedevs:
-    /* Steal devices from driver->activeUsbHostdevs.
-     * We will free them later.
-     */
-    for (i = 0; i < usbDeviceListCount(list); i++) {
-        tmp = usbDeviceListGet(list, i);
-        usbDeviceListSteal(driver->activeUsbHostdevs, tmp);
-    }
 
 cleanup:
     usbDeviceListFree(list);
-- 
1.7.7.6