[libvirt] [PATCH v14 47/49] change lxc_hostdev.c to use virhostdev common library APIs

Chunyan Liu cyliu at suse.com
Fri Mar 7 10:53:14 UTC 2014


Signed-off-by: Chunyan Liu <cyliu at suse.com>
---
 src/lxc/lxc_hostdev.c | 305 ++------------------------------------------------
 1 file changed, 10 insertions(+), 295 deletions(-)

diff --git a/src/lxc/lxc_hostdev.c b/src/lxc/lxc_hostdev.c
index 635f2e5..07480dc 100644
--- a/src/lxc/lxc_hostdev.c
+++ b/src/lxc/lxc_hostdev.c
@@ -35,259 +35,28 @@ int
 virLXCUpdateActiveUsbHostdevs(virLXCDriverPtr driver,
                               virDomainDefPtr def)
 {
-    virDomainHostdevDefPtr hostdev = NULL;
-    size_t i;
     virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
 
     if (!def->nhostdevs)
         return 0;
 
-    for (i = 0; i < def->nhostdevs; i++) {
-        virUSBDevicePtr usb = NULL;
-        hostdev = def->hostdevs[i];
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-            continue;
-        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
-            continue;
-
-        usb = virUSBDeviceNew(hostdev->source.subsys.u.usb.bus,
-                              hostdev->source.subsys.u.usb.device,
-                              NULL);
-        if (!usb) {
-            VIR_WARN("Unable to reattach USB device %03d.%03d on domain %s",
-                     hostdev->source.subsys.u.usb.bus,
-                     hostdev->source.subsys.u.usb.device,
-                     def->name);
-            continue;
-        }
-
-        virUSBDeviceSetUsedBy(usb, LXC_DRIVER_NAME, def->name);
-
-        virObjectLock(hostdev_mgr->activeUsbHostdevs);
-        if (virUSBDeviceListAdd(hostdev_mgr->activeUsbHostdevs, usb) < 0) {
-            virObjectUnlock(hostdev_mgr->activeUsbHostdevs);
-            virUSBDeviceFree(usb);
-            return -1;
-        }
-        virObjectUnlock(hostdev_mgr->activeUsbHostdevs);
-    }
-
-    return 0;
-}
-
-
-int
-virLXCPrepareHostdevUSBDevices(virLXCDriverPtr driver,
-                               const char *name,
-                               virUSBDeviceList *list)
-{
-    size_t i, j;
-    unsigned int count;
-    virUSBDevicePtr tmp;
-    virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
-
-    count = virUSBDeviceListCount(list);
-
-    virObjectLock(hostdev_mgr->activeUsbHostdevs);
-    for (i = 0; i < count; i++) {
-        virUSBDevicePtr usb = virUSBDeviceListGet(list, i);
-        if ((tmp = virUSBDeviceListFind(hostdev_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, LXC_DRIVER_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(hostdev_mgr->activeUsbHostdevs, usb) < 0)
-            goto error;
-    }
-    virObjectUnlock(hostdev_mgr->activeUsbHostdevs);
-    return 0;
-
-error:
-    for (j = 0; j < i; j++) {
-        tmp = virUSBDeviceListGet(list, i);
-        virUSBDeviceListSteal(hostdev_mgr->activeUsbHostdevs, tmp);
-    }
-    virObjectUnlock(hostdev_mgr->activeUsbHostdevs);
-    return -1;
-}
-
-int
-virLXCFindHostdevUSBDevice(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) {
-        virUSBDeviceList *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;
+    return virHostdevUpdateActiveUsbHostdevs(hostdev_mgr,
+                                             def->hostdevs, def->nhostdevs,
+                                             LXC_DRIVER_NAME, def->name);
 }
 
 static int
 virLXCPrepareHostUSBDevices(virLXCDriverPtr driver,
                             virDomainDefPtr def)
 {
-    size_t i;
-    int ret = -1;
-    virUSBDeviceList *list;
-    virUSBDevicePtr tmp;
     virDomainHostdevDefPtr *hostdevs = def->hostdevs;
     int nhostdevs = def->nhostdevs;
+    const char *dom_name = def->name;
+    unsigned int flags = 0;
+    virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
 
-    /* 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 virLXCPrepareHostdevPCIDevices()
-     */
-    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)
-            required = false;
-
-        if (virLXCFindHostdevUSBDevice(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 (virLXCPrepareHostdevUSBDevices(driver, def->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;
+    return virHostdevPrepareUsbHostdevs(hostdev_mgr, LXC_DRIVER_NAME, dom_name,
+                                        hostdevs, nhostdevs, flags);
 }
 
 
@@ -352,64 +121,10 @@ virLXCDomainReAttachHostUsbDevices(virLXCDriverPtr driver,
                                    virDomainHostdevDefPtr *hostdevs,
                                    int nhostdevs)
 {
-    size_t i;
     virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
 
-    virObjectLock(hostdev_mgr->activeUsbHostdevs);
-    for (i = 0; i < nhostdevs; i++) {
-        virDomainHostdevDefPtr hostdev = hostdevs[i];
-        virUSBDevicePtr usb, tmp;
-        const char *usedby_domname = NULL;
-        const char *usedby_drvname = NULL;
-
-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-            continue;
-        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
-            continue;
-        if (hostdev->missing)
-            continue;
-
-        usb = virUSBDeviceNew(hostdev->source.subsys.u.usb.bus,
-                              hostdev->source.subsys.u.usb.device,
-                              NULL);
-
-        if (!usb) {
-            VIR_WARN("Unable to reattach USB device %03d.%03d on domain %s",
-                     hostdev->source.subsys.u.usb.bus,
-                     hostdev->source.subsys.u.usb.device,
-                     name);
-            continue;
-        }
-
-        /* Delete only those USB devices which belongs
-         * to domain @name because virLXCProcessStart() might
-         * have failed because USB device is already taken.
-         * Therefore we want to steal only those devices from
-         * the list which were taken by @name */
-
-        tmp = virUSBDeviceListFind(hostdev_mgr->activeUsbHostdevs, usb);
-        virUSBDeviceFree(usb);
-
-        if (!tmp) {
-            VIR_WARN("Unable to find device %03d.%03d "
-                     "in list of active USB devices",
-                     hostdev->source.subsys.u.usb.bus,
-                     hostdev->source.subsys.u.usb.device);
-            continue;
-        }
-
-        virUSBDeviceGetUsedBy(tmp, &usedby_drvname, &usedby_domname);
-        if (STREQ_NULLABLE(LXC_DRIVER_NAME, usedby_drvname) &&
-            STREQ_NULLABLE(name, usedby_domname)) {
-            VIR_DEBUG("Removing %03d.%03d dom=%s from activeUsbHostdevs",
-                      hostdev->source.subsys.u.usb.bus,
-                      hostdev->source.subsys.u.usb.device,
-                      name);
-
-            virUSBDeviceListDel(hostdev_mgr->activeUsbHostdevs, tmp);
-        }
-    }
-    virObjectUnlock(hostdev_mgr->activeUsbHostdevs);
+    virHostdevReAttachUsbHostdevs(hostdev_mgr, LXC_DRIVER_NAME,
+                                  name, hostdevs, nhostdevs);
 }
 
 void virLXCDomainReAttachHostDevices(virLXCDriverPtr driver,
-- 
1.9.0




More information about the libvir-list mailing list