[libvirt] [PATCH 03/22] pci: new utility functions

Laine Stump laine at laine.org
Mon Jun 24 09:54:52 UTC 2013


* 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 |   2 +
 src/util/virpci.c        | 113 ++++++++++++++++++++++++++++++++++++++++-------
 src/util/virpci.h        |   7 +++
 3 files changed, 105 insertions(+), 17 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 7ac6fdc..2fdb185 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1648,6 +1648,7 @@ virObjectUnref;
 
 # util/virpci.h
 virPCIDeviceAddressGetSysfsFile;
+virPCIDeviceCopy;
 virPCIDeviceDetach;
 virPCIDeviceFileIterate;
 virPCIDeviceFree;
@@ -1664,6 +1665,7 @@ virPCIDeviceListAdd;
 virPCIDeviceListCount;
 virPCIDeviceListDel;
 virPCIDeviceListFind;
+virPCIDeviceListFindByIDs;
 virPCIDeviceListFindIndex;
 virPCIDeviceListGet;
 virPCIDeviceListNew;
diff --git a/src/util/virpci.c b/src/util/virpci.c
index d00c3ee..10e95bd 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -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)
 {
diff --git a/src/util/virpci.h b/src/util/virpci.h
index 17b15fe..d069adb 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -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);
 
-- 
1.7.11.7




More information about the libvir-list mailing list