]> xenbits.xensource.com Git - people/dariof/libvirt.git/commitdiff
pci: new utility functions
authorLaine Stump <laine@laine.org>
Fri, 31 May 2013 15:06:32 +0000 (11:06 -0400)
committerLaine Stump <laine@laine.org>
Mon, 24 Jun 2013 21:33:38 +0000 (17:33 -0400)
* virPCIDeviceFindByIDs - find a device on a list w/o creating an object
    This makes searching for an existing device on a list lighter weight.

* virPCIDeviceCopy - make a copy of an existing virPCIDevice object.

* virPCIDeviceGetDriverPathAndName - construct new strings containing
    1) the name of the driver bound to this device.
    2) the full path to the sysfs config for that driver.
    (This code was lifted from virPCIDeviceUnbindFromStub, and replaced
    there with a call to this new function).

src/libvirt_private.syms
src/util/virpci.c
src/util/virpci.h

index 9401d93c66b5509f7c988e3d83f31b489312bb86..7c38c58077fbd80db6d95a4f05a210e44e5477c6 100644 (file)
@@ -1688,6 +1688,7 @@ virObjectUnref;
 
 # util/virpci.h
 virPCIDeviceAddressGetSysfsFile;
+virPCIDeviceCopy;
 virPCIDeviceDetach;
 virPCIDeviceFileIterate;
 virPCIDeviceFree;
@@ -1704,6 +1705,7 @@ virPCIDeviceListAdd;
 virPCIDeviceListCount;
 virPCIDeviceListDel;
 virPCIDeviceListFind;
+virPCIDeviceListFindByIDs;
 virPCIDeviceListFindIndex;
 virPCIDeviceListGet;
 virPCIDeviceListNew;
index d00c3ee8222ae41cf60c277a6810d3febf4b9366..10e95bd8b0022d265308b7f03c29e7732da3e827 100644 (file)
@@ -880,6 +880,54 @@ virPCIFile(char **buffer, const char *device, const char *file)
     return 0;
 }
 
+
+/* virPCIDeviceGetDriverPathAndName - put the path to the driver
+ * directory of the driver in use for this device in @path and the
+ * name of the driver in @name. Both could be NULL if it's not bound
+ * to any driver.
+ *
+ * Return 0 for success, -1 for error.
+ */
+static int
+virPCIDeviceGetDriverPathAndName(virPCIDevicePtr dev, char **path, char **name)
+{
+    int ret = -1;
+    char *drvlink = NULL;
+
+    *path = *name = NULL;
+    /* drvlink = "/sys/bus/pci/dddd:bb:ss.ff/driver" */
+    if (virPCIFile(&drvlink, dev->name, "driver") < 0)
+        goto cleanup;
+
+    if (virFileIsLink(drvlink) != 1) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Invalid device %s driver file %s is not a symlink"),
+                       dev->name, drvlink);
+        goto cleanup;
+    }
+    if (virFileResolveLink(drvlink, path) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Unable to resolve device %s driver symlink %s"),
+                       dev->name, drvlink);
+        goto cleanup;
+    }
+    /* path = "/sys/bus/pci/drivers/${drivername}" */
+
+    if (VIR_STRDUP(*name, last_component(*path)) < 0)
+        goto cleanup;
+    /* name = "${drivername}" */
+
+    ret = 0;
+cleanup:
+    VIR_FREE(drvlink);
+    if (ret < 0) {
+        VIR_FREE(*path);
+        VIR_FREE(*name);
+    }
+    return ret;
+}
+
+
 static int
 virPCIProbeStubDriver(const char *driver)
 {
@@ -931,23 +979,7 @@ virPCIDeviceUnbindFromStub(virPCIDevicePtr dev)
     /* If the device is currently bound to one of the "well known"
      * stub drivers, then unbind it, otherwise ignore it.
      */
-    if (virPCIFile(&path, dev->name, "driver") < 0)
-        goto cleanup;
-    /* path = "/sys/bus/pci/dddd:bb:ss.ff/driver" */
-    if (virFileIsLink(path) != 1) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Invalid device %s driver file %s is not a symlink"),
-                       dev->name, path);
-        goto cleanup;
-    }
-    if (virFileResolveLink(path, &drvdir) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Unable to resolve device %s driver symlink %s"),
-                       dev->name, path);
-        goto cleanup;
-    }
-    /* drvdir = "/sys/bus/pci/drivers/${drivername}" */
-    if (VIR_STRDUP(driver, last_component(drvdir)) < 0)
+    if (virPCIDeviceGetDriverPathAndName(dev, &drvdir, &driver) < 0)
         goto cleanup;
 
     if (!dev->unbind_from_stub)
@@ -1473,6 +1505,32 @@ error:
     goto cleanup;
 }
 
+
+virPCIDevicePtr
+virPCIDeviceCopy(virPCIDevicePtr dev)
+{
+    virPCIDevicePtr copy;
+
+    if (VIR_ALLOC(copy) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    /* shallow copy to take care of most attributes */
+    *copy = *dev;
+    copy->path = copy->stubDriver = NULL;
+    if (VIR_STRDUP(copy->path, dev->path) < 0 ||
+        VIR_STRDUP(copy->stubDriver, dev->stubDriver) < 0) {
+        goto error;
+    }
+    return copy;
+
+error:
+    virPCIDeviceFree(copy);
+    return NULL;
+}
+
+
 void
 virPCIDeviceFree(virPCIDevicePtr dev)
 {
@@ -1690,6 +1748,27 @@ virPCIDeviceListFindIndex(virPCIDeviceListPtr list, virPCIDevicePtr dev)
     return -1;
 }
 
+
+virPCIDevicePtr
+virPCIDeviceListFindByIDs(virPCIDeviceListPtr list,
+                          unsigned int domain,
+                          unsigned int bus,
+                          unsigned int slot,
+                          unsigned int function)
+{
+    int i;
+
+    for (i = 0; i < list->count; i++) {
+        if (list->devs[i]->domain == domain &&
+            list->devs[i]->bus == bus &&
+            list->devs[i]->slot == slot &&
+            list->devs[i]->function == function)
+            return list->devs[i];
+    }
+    return NULL;
+}
+
+
 virPCIDevicePtr
 virPCIDeviceListFind(virPCIDeviceListPtr list, virPCIDevicePtr dev)
 {
index 17b15fef06482dab2ade1f267c7907b772b08e62..d069adba0da06ff45abca38c5c430f1990066785 100644 (file)
@@ -45,6 +45,7 @@ virPCIDevicePtr virPCIDeviceNew(unsigned int domain,
                                 unsigned int bus,
                                 unsigned int slot,
                                 unsigned int function);
+virPCIDevicePtr virPCIDeviceCopy(virPCIDevicePtr dev);
 void virPCIDeviceFree(virPCIDevicePtr dev);
 const char *virPCIDeviceGetName(virPCIDevicePtr dev);
 
@@ -94,6 +95,12 @@ void virPCIDeviceListDel(virPCIDeviceListPtr list,
                          virPCIDevicePtr dev);
 virPCIDevicePtr virPCIDeviceListFind(virPCIDeviceListPtr list,
                                      virPCIDevicePtr dev);
+virPCIDevicePtr
+virPCIDeviceListFindByIDs(virPCIDeviceListPtr list,
+                          unsigned int domain,
+                          unsigned int bus,
+                          unsigned int slot,
+                          unsigned int function);
 int virPCIDeviceListFindIndex(virPCIDeviceListPtr list,
                               virPCIDevicePtr dev);