[libvirt] [PATCH v14 27/49] move virHostdevPrepareHostUSBDevices to virhostdev.c

Chunyan Liu cyliu at suse.com
Fri Mar 7 10:52:54 UTC 2014


Signed-off-by: Chunyan Liu <cyliu at suse.com>
---
 src/libvirt_private.syms |   1 +
 src/qemu/qemu_hostdev.c  | 217 -----------------------------------------------
 src/util/virhostdev.c    | 216 ++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virhostdev.h    |   7 ++
 4 files changed, 224 insertions(+), 217 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 8aba3cf..04694d8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1295,6 +1295,7 @@ virHookPresent;
 #util/virhostdev.h
 virHostdevManagerGetDefault;
 virHostdevPreparePCIDevices;
+virHostdevPrepareUSBDevices;
 virHostdevReAttachPCIDevices;
 virHostdevUpdateActivePciHostdevs;
 virHostdevUpdateActiveScsiHostdevs;
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 0eb78ac..35494d8 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -232,223 +232,6 @@ out:
     return ret;
 }
 
-
-static int
-virHostdevMarkUsbHostdevs(virHostdevManagerPtr mgr,
-                          const char *drv_name,
-                          const char *name,
-                          virUSBDeviceListPtr list)
-{
-    size_t i, j;
-    unsigned int count;
-    virUSBDevicePtr tmp;
-
-    virObjectLock(mgr->activeUsbHostdevs);
-    count = virUSBDeviceListCount(list);
-
-    for (i = 0; i < count; i++) {
-        virUSBDevicePtr usb = virUSBDeviceListGet(list, i);
-        if ((tmp = virUSBDeviceListFind(mgr->activeUsbHostdevs, usb))) {
-            const char *other_drvname;
-            const char *other_domname;
-
-            virUSBDeviceGetUsedBy(tmp, &other_drvname, &other_domname);
-            if (other_drvname && other_domname)
-                virReportError(VIR_ERR_OPERATION_INVALID,
-                               _("USB device %s is in use by "
-                                 "driver %s, domain %s"),
-                               virUSBDeviceGetName(tmp),
-                               other_drvname, other_domname);
-            else
-                virReportError(VIR_ERR_OPERATION_INVALID,
-                               _("USB device %s is already in use"),
-                               virUSBDeviceGetName(tmp));
-            goto error;
-        }
-
-        virUSBDeviceSetUsedBy(usb, drv_name, name);
-        VIR_DEBUG("Adding %03d.%03d dom=%s to activeUsbHostdevs",
-                  virUSBDeviceGetBus(usb), virUSBDeviceGetDevno(usb), name);
-        /*
-         * The caller is responsible to steal these usb devices
-         * from the virUSBDeviceList that passed in on success,
-         * perform rollback on failure.
-         */
-        if (virUSBDeviceListAdd(mgr->activeUsbHostdevs, usb) < 0)
-            goto error;
-    }
-
-    virObjectUnlock(mgr->activeUsbHostdevs);
-    return 0;
-
-error:
-    for (j = 0; j < i; j++) {
-        tmp = virUSBDeviceListGet(list, i);
-        virUSBDeviceListSteal(mgr->activeUsbHostdevs, tmp);
-    }
-    virObjectUnlock(mgr->activeUsbHostdevs);
-    return -1;
-}
-
-
-static int
-virHostdevFindUSBDevice(virDomainHostdevDefPtr hostdev,
-                        bool mandatory,
-                        virUSBDevicePtr *usb)
-{
-    unsigned vendor = hostdev->source.subsys.u.usb.vendor;
-    unsigned product = hostdev->source.subsys.u.usb.product;
-    unsigned bus = hostdev->source.subsys.u.usb.bus;
-    unsigned device = hostdev->source.subsys.u.usb.device;
-    bool autoAddress = hostdev->source.subsys.u.usb.autoAddress;
-    int rc;
-
-    *usb = NULL;
-
-    if (vendor && bus) {
-        rc = virUSBDeviceFind(vendor, product, bus, device,
-                              NULL,
-                              autoAddress ? false : mandatory,
-                              usb);
-        if (rc < 0) {
-            return -1;
-        } else if (!autoAddress) {
-            goto out;
-        } else {
-            VIR_INFO("USB device %x:%x could not be found at previous"
-                     " address (bus:%u device:%u)",
-                     vendor, product, bus, device);
-        }
-    }
-
-    /* When vendor is specified, its USB address is either unspecified or the
-     * device could not be found at the USB device where it had been
-     * automatically found before.
-     */
-    if (vendor) {
-        virUSBDeviceListPtr devs;
-
-        rc = virUSBDeviceFindByVendor(vendor, product, NULL, mandatory, &devs);
-        if (rc < 0)
-            return -1;
-
-        if (rc == 1) {
-            *usb = virUSBDeviceListGet(devs, 0);
-            virUSBDeviceListSteal(devs, *usb);
-        }
-        virObjectUnref(devs);
-
-        if (rc == 0) {
-            goto out;
-        } else if (rc > 1) {
-            if (autoAddress) {
-                virReportError(VIR_ERR_OPERATION_FAILED,
-                               _("Multiple USB devices for %x:%x were found,"
-                                 " but none of them is at bus:%u device:%u"),
-                               vendor, product, bus, device);
-            } else {
-                virReportError(VIR_ERR_OPERATION_FAILED,
-                               _("Multiple USB devices for %x:%x, "
-                                 "use <address> to specify one"),
-                               vendor, product);
-            }
-            return -1;
-        }
-
-        hostdev->source.subsys.u.usb.bus = virUSBDeviceGetBus(*usb);
-        hostdev->source.subsys.u.usb.device = virUSBDeviceGetDevno(*usb);
-        hostdev->source.subsys.u.usb.autoAddress = true;
-
-        if (autoAddress) {
-            VIR_INFO("USB device %x:%x found at bus:%u device:%u (moved"
-                     " from bus:%u device:%u)",
-                     vendor, product,
-                     hostdev->source.subsys.u.usb.bus,
-                     hostdev->source.subsys.u.usb.device,
-                     bus, device);
-        }
-    } else if (!vendor && bus) {
-        if (virUSBDeviceFindByBus(bus, device, NULL, mandatory, usb) < 0)
-            return -1;
-    }
-
-out:
-    if (!*usb)
-        hostdev->missing = true;
-    return 0;
-}
-
-static int
-virHostdevPrepareUSBDevices(virHostdevManagerPtr hostdev_mgr,
-                            const char *drv_name,
-                            const char *name,
-                            virDomainHostdevDefPtr *hostdevs,
-                            int nhostdevs,
-                            unsigned int flags)
-{
-    size_t i;
-    int ret = -1;
-    virUSBDeviceListPtr list;
-    virUSBDevicePtr tmp;
-    bool coldBoot = !!(flags & VIR_HOSTDEV_COLD_BOOT);
-
-    /* To prevent situation where USB device is assigned to two domains
-     * we need to keep a list of currently assigned USB devices.
-     * This is done in several loops which cannot be joined into one big
-     * loop. See virHostdevPreparePCIDevices()
-     */
-    if (!(list = virUSBDeviceListNew()))
-        goto cleanup;
-
-    /* Loop 1: build temporary list
-     */
-    for (i = 0; i < nhostdevs; i++) {
-        virDomainHostdevDefPtr hostdev = hostdevs[i];
-        bool required = true;
-        virUSBDevicePtr usb;
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-            continue;
-        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
-            continue;
-
-        if (hostdev->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_OPTIONAL ||
-            (hostdev->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_REQUISITE &&
-             !coldBoot))
-            required = false;
-
-        if (virHostdevFindUSBDevice(hostdev, required, &usb) < 0)
-            goto cleanup;
-
-        if (usb && virUSBDeviceListAdd(list, usb) < 0) {
-            virUSBDeviceFree(usb);
-            goto cleanup;
-        }
-    }
-
-    /* Mark devices in temporary list as used by @name
-     * and add them do driver list. However, if something goes
-     * wrong, perform rollback.
-     */
-    if (virHostdevMarkUsbHostdevs(hostdev_mgr, drv_name, name, list) < 0)
-        goto cleanup;
-
-    /* Loop 2: Temporary list was successfully merged with
-     * driver list, so steal all items to avoid freeing them
-     * in cleanup label.
-     */
-    while (virUSBDeviceListCount(list) > 0) {
-        tmp = virUSBDeviceListGet(list, 0);
-        virUSBDeviceListSteal(list, tmp);
-    }
-
-    ret = 0;
-
-cleanup:
-    virObjectUnref(list);
-    return ret;
-}
-
 int
 qemuPrepareHostUSBDevices(virQEMUDriverPtr driver,
                           const char *name,
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 47447fa..a55480c 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -927,3 +927,219 @@ cleanup:
     virObjectUnlock(mgr->activeScsiHostdevs);
     return ret;
 }
+
+static int
+virHostdevMarkUsbHostdevs(virHostdevManagerPtr mgr,
+                          const char *drv_name,
+                          const char *name,
+                          virUSBDeviceListPtr list)
+{
+    size_t i, j;
+    unsigned int count;
+    virUSBDevicePtr tmp;
+
+    virObjectLock(mgr->activeUsbHostdevs);
+    count = virUSBDeviceListCount(list);
+
+    for (i = 0; i < count; i++) {
+        virUSBDevicePtr usb = virUSBDeviceListGet(list, i);
+        if ((tmp = virUSBDeviceListFind(mgr->activeUsbHostdevs, usb))) {
+            const char *other_drvname;
+            const char *other_domname;
+
+            virUSBDeviceGetUsedBy(tmp, &other_drvname, &other_domname);
+            if (other_drvname && other_domname)
+                virReportError(VIR_ERR_OPERATION_INVALID,
+                               _("USB device %s is in use by "
+                                 "driver %s, domain %s"),
+                               virUSBDeviceGetName(tmp),
+                               other_drvname, other_domname);
+            else
+                virReportError(VIR_ERR_OPERATION_INVALID,
+                               _("USB device %s is already in use"),
+                               virUSBDeviceGetName(tmp));
+            goto error;
+        }
+
+        virUSBDeviceSetUsedBy(usb, drv_name, name);
+        VIR_DEBUG("Adding %03d.%03d dom=%s to activeUsbHostdevs",
+                  virUSBDeviceGetBus(usb), virUSBDeviceGetDevno(usb), name);
+        /*
+         * The caller is responsible to steal these usb devices
+         * from the virUSBDeviceList that passed in on success,
+         * perform rollback on failure.
+         */
+        if (virUSBDeviceListAdd(mgr->activeUsbHostdevs, usb) < 0)
+            goto error;
+    }
+
+    virObjectUnlock(mgr->activeUsbHostdevs);
+    return 0;
+
+error:
+    for (j = 0; j < i; j++) {
+        tmp = virUSBDeviceListGet(list, i);
+        virUSBDeviceListSteal(mgr->activeUsbHostdevs, tmp);
+    }
+    virObjectUnlock(mgr->activeUsbHostdevs);
+    return -1;
+}
+
+
+static int
+virHostdevFindUSBDevice(virDomainHostdevDefPtr hostdev,
+                        bool mandatory,
+                        virUSBDevicePtr *usb)
+{
+    unsigned vendor = hostdev->source.subsys.u.usb.vendor;
+    unsigned product = hostdev->source.subsys.u.usb.product;
+    unsigned bus = hostdev->source.subsys.u.usb.bus;
+    unsigned device = hostdev->source.subsys.u.usb.device;
+    bool autoAddress = hostdev->source.subsys.u.usb.autoAddress;
+    int rc;
+
+    *usb = NULL;
+
+    if (vendor && bus) {
+        rc = virUSBDeviceFind(vendor, product, bus, device,
+                              NULL,
+                              autoAddress ? false : mandatory,
+                              usb);
+        if (rc < 0) {
+            return -1;
+        } else if (!autoAddress) {
+            goto out;
+        } else {
+            VIR_INFO("USB device %x:%x could not be found at previous"
+                     " address (bus:%u device:%u)",
+                     vendor, product, bus, device);
+        }
+    }
+
+    /* When vendor is specified, its USB address is either unspecified or the
+     * device could not be found at the USB device where it had been
+     * automatically found before.
+     */
+    if (vendor) {
+        virUSBDeviceListPtr devs;
+
+        rc = virUSBDeviceFindByVendor(vendor, product, NULL, mandatory, &devs);
+        if (rc < 0)
+            return -1;
+
+        if (rc == 1) {
+            *usb = virUSBDeviceListGet(devs, 0);
+            virUSBDeviceListSteal(devs, *usb);
+        }
+        virObjectUnref(devs);
+
+        if (rc == 0) {
+            goto out;
+        } else if (rc > 1) {
+            if (autoAddress) {
+                virReportError(VIR_ERR_OPERATION_FAILED,
+                               _("Multiple USB devices for %x:%x were found,"
+                                 " but none of them is at bus:%u device:%u"),
+                               vendor, product, bus, device);
+            } else {
+                virReportError(VIR_ERR_OPERATION_FAILED,
+                               _("Multiple USB devices for %x:%x, "
+                                 "use <address> to specify one"),
+                               vendor, product);
+            }
+            return -1;
+        }
+
+        hostdev->source.subsys.u.usb.bus = virUSBDeviceGetBus(*usb);
+        hostdev->source.subsys.u.usb.device = virUSBDeviceGetDevno(*usb);
+        hostdev->source.subsys.u.usb.autoAddress = true;
+
+        if (autoAddress) {
+            VIR_INFO("USB device %x:%x found at bus:%u device:%u (moved"
+                     " from bus:%u device:%u)",
+                     vendor, product,
+                     hostdev->source.subsys.u.usb.bus,
+                     hostdev->source.subsys.u.usb.device,
+                     bus, device);
+        }
+    } else if (!vendor && bus) {
+        if (virUSBDeviceFindByBus(bus, device, NULL, mandatory, usb) < 0)
+            return -1;
+    }
+
+out:
+    if (!*usb)
+        hostdev->missing = true;
+    return 0;
+}
+
+int
+virHostdevPrepareUSBDevices(virHostdevManagerPtr hostdev_mgr,
+                            const char *drv_name,
+                            const char *name,
+                            virDomainHostdevDefPtr *hostdevs,
+                            int nhostdevs,
+                            unsigned int flags)
+{
+    size_t i;
+    int ret = -1;
+    virUSBDeviceListPtr list;
+    virUSBDevicePtr tmp;
+    bool coldBoot = !!(flags & VIR_HOSTDEV_COLD_BOOT);
+
+    /* To prevent situation where USB device is assigned to two domains
+     * we need to keep a list of currently assigned USB devices.
+     * This is done in several loops which cannot be joined into one big
+     * loop. See virHostdevPreparePCIDevices()
+     */
+    if (!(list = virUSBDeviceListNew()))
+        goto cleanup;
+
+    /* Loop 1: build temporary list
+     */
+    for (i = 0; i < nhostdevs; i++) {
+        virDomainHostdevDefPtr hostdev = hostdevs[i];
+        bool required = true;
+        virUSBDevicePtr usb;
+
+        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+            continue;
+        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
+            continue;
+
+        if (hostdev->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_OPTIONAL ||
+            (hostdev->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_REQUISITE &&
+             !coldBoot))
+            required = false;
+
+        if (virHostdevFindUSBDevice(hostdev, required, &usb) < 0)
+            goto cleanup;
+
+        if (usb && virUSBDeviceListAdd(list, usb) < 0) {
+            virUSBDeviceFree(usb);
+            goto cleanup;
+        }
+    }
+
+    /* Mark devices in temporary list as used by @name
+     * and add them do driver list. However, if something goes
+     * wrong, perform rollback.
+     */
+    if (virHostdevMarkUsbHostdevs(hostdev_mgr, drv_name, name, list) < 0)
+        goto cleanup;
+
+    /* Loop 2: Temporary list was successfully merged with
+     * driver list, so steal all items to avoid freeing them
+     * in cleanup label.
+     */
+    while (virUSBDeviceListCount(list) > 0) {
+        tmp = virUSBDeviceListGet(list, 0);
+        virUSBDeviceListSteal(list, tmp);
+    }
+
+    ret = 0;
+
+cleanup:
+    virObjectUnref(list);
+    return ret;
+}
diff --git a/src/util/virhostdev.h b/src/util/virhostdev.h
index e6b5e31..83ebefc 100644
--- a/src/util/virhostdev.h
+++ b/src/util/virhostdev.h
@@ -58,6 +58,13 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
                             virDomainHostdevDefPtr *hostdevs,
                             int nhostdevs,
                             unsigned int flags);
+int
+virHostdevPrepareUSBDevices(virHostdevManagerPtr hostdev_mgr,
+                            const char *drv_name,
+                            const char *name,
+                            virDomainHostdevDefPtr *hostdevs,
+                            int nhostdevs,
+                            unsigned int flags);
 void
 virHostdevReAttachPCIDevices(virHostdevManagerPtr hostdev_mgr,
                              const char *drv_name,
-- 
1.9.0




More information about the libvir-list mailing list