]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Add helper APIs for iterating over PCI device resource files
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 14 Aug 2009 13:20:40 +0000 (14:20 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 10 Sep 2009 13:34:07 +0000 (14:34 +0100)
* src/pci.h, src/pci.c: Helper for iterating over PCI device
  resource files
* src/libvirt_private.syms: Export pciDeviceFileIterate

src/libvirt_private.syms
src/pci.c
src/pci.h

index 998b8433bc2eb19264fb349e21c6814eeb88e45c..16bdc3f89c472c25b416de6e506fdddc5c2e5036 100644 (file)
@@ -294,6 +294,8 @@ pciDeviceListNew;
 pciDeviceListFree;
 pciDeviceListAdd;
 pciDeviceListDel;
+pciDeviceFileIterate;
+
 
 # qparams.h
 qparam_get_query;
index 96e5d6dcc8889dee642a20e069aa3e163b849cd4..feaa6e8033dba87afde38c8b111ce8c7d8d53c70 100644 (file)
--- a/src/pci.c
+++ b/src/pci.c
@@ -1022,3 +1022,55 @@ pciDeviceListFind(pciDeviceList *list, pciDevice *dev)
             return list->devs[i];
     return NULL;
 }
+
+
+int pciDeviceFileIterate(virConnectPtr conn,
+                         pciDevice *dev,
+                         pciDeviceFileActor actor,
+                         void *opaque)
+{
+    char *pcidir = NULL;
+    char *file = NULL;
+    DIR *dir = NULL;
+    int ret = -1;
+    struct dirent *ent;
+
+    if (virAsprintf(&pcidir, "/sys/bus/pci/devices/%04x:%02x:%02x.%x",
+                    dev->domain, dev->bus, dev->slot, dev->function) < 0) {
+        virReportOOMError(conn);
+        goto cleanup;
+    }
+
+    if (!(dir = opendir(pcidir))) {
+        virReportSystemError(conn, errno,
+                             _("cannot open %s"), pcidir);
+        goto cleanup;
+    }
+
+    while ((ent = readdir(dir)) != NULL) {
+        /* Device assignment requires:
+         *   $PCIDIR/config, $PCIDIR/resource, $PCIDIR/resourceNNN, $PCIDIR/rom
+         */
+        if (STREQ(ent->d_name, "config") ||
+            STRPREFIX(ent->d_name, "resource") ||
+            STREQ(ent->d_name, "rom")) {
+            if (virAsprintf(&file, "%s/%s", pcidir, ent->d_name) < 0) {
+                virReportOOMError(conn);
+                goto cleanup;
+            }
+            if ((actor)(conn, dev, file, opaque) < 0)
+                goto cleanup;
+
+            VIR_FREE(file);
+        }
+    }
+
+    ret = 0;
+
+cleanup:
+    if (dir)
+        closedir(dir);
+    VIR_FREE(file);
+    VIR_FREE(pcidir);
+    return ret;
+}
index 685b0afc9d2ccb676a3b306c24940940d7b7042e..047955f007738a703772bbcda862b52564805cc1 100644 (file)
--- a/src/pci.h
+++ b/src/pci.h
@@ -22,7 +22,6 @@
 #ifndef __VIR_PCI_H__
 #define __VIR_PCI_H__
 
-#include <config.h>
 #include "internal.h"
 
 typedef struct _pciDevice pciDevice;
@@ -62,4 +61,19 @@ void           pciDeviceListDel  (virConnectPtr conn,
 pciDevice *    pciDeviceListFind (pciDeviceList *list,
                                   pciDevice *dev);
 
+/*
+ * Callback that will be invoked once for each file
+ * associated with / used for PCI host device access.
+ *
+ * Should return 0 if successfully processed, or
+ * -1 to indicate error and abort iteration
+ */
+typedef int (*pciDeviceFileActor)(virConnectPtr conn, pciDevice *dev,
+                                  const char *path, void *opaque);
+
+int pciDeviceFileIterate(virConnectPtr conn,
+                         pciDevice *dev,
+                         pciDeviceFileActor actor,
+                         void *opaque);
+
 #endif /* __VIR_PCI_H__ */