[libvirt] [PATCH 01/15] Make pciDeviceList struct opaque

Daniel P. Berrange berrange at redhat.com
Tue Nov 3 19:49:55 UTC 2009


* src/util/pci.c, src/util/pci.h: Make the pciDeviceList struct
  opaque to callers of the API. Add accessor methods for managing
  devices in the list
* src/qemu/qemu_driver.c: Update to use APIs instead of directly
  accessing pciDeviceList fields
---
 src/libvirt_private.syms |    5 +++
 src/qemu/qemu_driver.c   |   74 +++++++++++++++++++++++++++------------------
 src/util/pci.c           |   46 +++++++++++++++++++++++++---
 src/util/pci.h           |   12 ++++---
 4 files changed, 97 insertions(+), 40 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 15d75fd..1e4a3dd 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -356,6 +356,11 @@ pciDeviceListFree;
 pciDeviceListAdd;
 pciDeviceListDel;
 pciDeviceFileIterate;
+pciDeviceListCount;
+pciDeviceListGet;
+pciDeviceListLock;
+pciDeviceListUnlock;
+pciDeviceListSteal;
 
 
 # qparams.h
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2b8b550..3bbbb6d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1367,7 +1367,7 @@ qemuUpdateActivePciHostdevs(struct qemud_driver *driver,
                             virDomainDefPtr def)
 {
     pciDeviceList *pcidevs;
-    int i, ret;
+    int ret = -1;
 
     if (!def->nhostdevs)
         return 0;
@@ -1375,18 +1375,19 @@ qemuUpdateActivePciHostdevs(struct qemud_driver *driver,
     if (!(pcidevs = qemuGetPciHostDeviceList(NULL, def)))
         return -1;
 
-    ret = 0;
-
-    for (i = 0; i < pcidevs->count; i++) {
+    while (pciDeviceListCount(pcidevs) > 0) {
+        pciDevice *dev = pciDeviceListSteal(NULL, pcidevs, 0);
         if (pciDeviceListAdd(NULL,
                              driver->activePciHostdevs,
-                             pcidevs->devs[i]) < 0) {
-            ret = -1;
-            break;
+                             dev) < 0) {
+            pciFreeDevice(NULL, dev);
+            goto cleanup;
         }
-        pcidevs->devs[i] = NULL;
     }
 
+    ret = 0;
+
+cleanup:
     pciDeviceListFree(NULL, pcidevs);
     return ret;
 }
@@ -1398,6 +1399,7 @@ qemuPrepareHostDevices(virConnectPtr conn,
 {
     pciDeviceList *pcidevs;
     int i;
+    int ret = -1;
 
     if (!def->nhostdevs)
         return 0;
@@ -1417,33 +1419,39 @@ qemuPrepareHostDevices(virConnectPtr conn,
      * to pci-stub.ko
      */
 
-    for (i = 0; i < pcidevs->count; i++)
-        if (pciDeviceGetManaged(pcidevs->devs[i]) &&
-            pciDettachDevice(conn, pcidevs->devs[i]) < 0)
-            goto error;
+    for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+        pciDevice *dev = pciDeviceListGet(pcidevs, i);
+        if (pciDeviceGetManaged(dev) &&
+            pciDettachDevice(conn, dev) < 0)
+            goto cleanup;
+    }
 
     /* Now that all the PCI hostdevs have be dettached, we can safely
      * reset them */
-    for (i = 0; i < pcidevs->count; i++)
-        if (pciResetDevice(conn, pcidevs->devs[i],
+    for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+        pciDevice *dev = pciDeviceListGet(pcidevs, i);
+        if (pciResetDevice(conn, dev,
                            driver->activePciHostdevs) < 0)
-            goto error;
+            goto cleanup;
+    }
 
     /* Now mark all the devices as active */
-    for (i = 0; i < pcidevs->count; i++) {
+    for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+        pciDevice *dev = pciDeviceListGet(pcidevs, i);
+        pciDeviceListSteal(NULL, pcidevs, dev);
         if (pciDeviceListAdd(conn,
                              driver->activePciHostdevs,
-                             pcidevs->devs[i]) < 0)
-            goto error;
-        pcidevs->devs[i] = NULL;
+                             dev) < 0) {
+            pciFreeDevice(NULL, dev);
+            goto cleanup;
+        }
     }
 
-    pciDeviceListFree(conn, pcidevs);
-    return 0;
+    ret = 0;
 
-error:
+cleanup:
     pciDeviceListFree(conn, pcidevs);
-    return -1;
+    return ret;
 }
 
 static void
@@ -1468,26 +1476,32 @@ qemuDomainReAttachHostDevices(virConnectPtr conn,
     /* Again 3 loops; mark all devices as inactive before reset
      * them and reset all the devices before re-attach */
 
-    for (i = 0; i < pcidevs->count; i++)
-        pciDeviceListDel(conn, driver->activePciHostdevs, pcidevs->devs[i]);
+    for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+        pciDevice *dev = pciDeviceListGet(pcidevs, i);
+        pciDeviceListDel(conn, driver->activePciHostdevs, dev);
+    }
 
-    for (i = 0; i < pcidevs->count; i++)
-        if (pciResetDevice(conn, pcidevs->devs[i],
+    for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+        pciDevice *dev = pciDeviceListGet(pcidevs, i);
+        if (pciResetDevice(conn, dev,
                            driver->activePciHostdevs) < 0) {
             virErrorPtr err = virGetLastError();
             VIR_ERROR(_("Failed to reset PCI device: %s\n"),
                       err ? err->message : "");
             virResetError(err);
         }
+    }
 
-    for (i = 0; i < pcidevs->count; i++)
-        if (pciDeviceGetManaged(pcidevs->devs[i]) &&
-            pciReAttachDevice(conn, pcidevs->devs[i]) < 0) {
+    for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
+        pciDevice *dev = pciDeviceListGet(pcidevs, i);
+        if (pciDeviceGetManaged(dev) &&
+            pciReAttachDevice(NULL, dev) < 0) {
             virErrorPtr err = virGetLastError();
             VIR_ERROR(_("Failed to re-attach PCI device: %s\n"),
                       err ? err->message : "");
             virResetError(err);
         }
+    }
 
     pciDeviceListFree(conn, pcidevs);
 }
diff --git a/src/util/pci.c b/src/util/pci.c
index feaa6e8..1e003c2 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -66,6 +66,12 @@ struct _pciDevice {
     unsigned      managed : 1;
 };
 
+struct _pciDeviceList {
+    unsigned count;
+    pciDevice **devs;
+};
+
+
 /* For virReportOOMError()  and virReportSystemError() */
 #define VIR_FROM_THIS VIR_FROM_NONE
 
@@ -980,11 +986,30 @@ pciDeviceListAdd(virConnectPtr conn,
     return 0;
 }
 
-void
-pciDeviceListDel(virConnectPtr conn ATTRIBUTE_UNUSED,
-                 pciDeviceList *list,
-                 pciDevice *dev)
+pciDevice *
+pciDeviceListGet(pciDeviceList *list,
+                 int idx)
+{
+    if (idx >= list->count)
+        return NULL;
+    if (idx < 0)
+        return NULL;
+
+    return list->devs[idx];
+}
+
+int
+pciDeviceListCount(pciDeviceList *list)
 {
+    return list->count;
+}
+
+pciDevice *
+pciDeviceListSteal(virConnectPtr conn ATTRIBUTE_UNUSED,
+                   pciDeviceList *list,
+                   pciDevice *dev)
+{
+    pciDevice *ret = NULL;
     int i;
 
     for (i = 0; i < list->count; i++) {
@@ -994,7 +1019,7 @@ pciDeviceListDel(virConnectPtr conn ATTRIBUTE_UNUSED,
             list->devs[i]->function != dev->function)
             continue;
 
-        pciFreeDevice(conn, list->devs[i]);
+        ret = list->devs[i];
 
         if (i != --list->count)
             memmove(&list->devs[i],
@@ -1007,6 +1032,17 @@ pciDeviceListDel(virConnectPtr conn ATTRIBUTE_UNUSED,
 
         break;
     }
+    return ret;
+}
+
+void
+pciDeviceListDel(virConnectPtr conn,
+                 pciDeviceList *list,
+                 pciDevice *dev)
+{
+    pciDevice *ret = pciDeviceListSteal(conn, list, dev);
+    if (ret)
+        pciFreeDevice(conn, ret);
 }
 
 pciDevice *
diff --git a/src/util/pci.h b/src/util/pci.h
index 047955f..1f0b9d2 100644
--- a/src/util/pci.h
+++ b/src/util/pci.h
@@ -25,11 +25,7 @@
 #include "internal.h"
 
 typedef struct _pciDevice pciDevice;
-
-typedef struct {
-    unsigned count;
-    pciDevice **devs;
-} pciDeviceList;
+typedef struct _pciDeviceList pciDeviceList;
 
 pciDevice *pciGetDevice      (virConnectPtr  conn,
                               unsigned       domain,
@@ -55,6 +51,12 @@ void           pciDeviceListFree (virConnectPtr conn,
 int            pciDeviceListAdd  (virConnectPtr conn,
                                   pciDeviceList *list,
                                   pciDevice *dev);
+pciDevice *    pciDeviceListGet (pciDeviceList *list,
+                                 int idx);
+int            pciDeviceListCount (pciDeviceList *list);
+pciDevice *    pciDeviceListSteal (virConnectPtr conn,
+                                   pciDeviceList *list,
+                                   pciDevice *dev);
 void           pciDeviceListDel  (virConnectPtr conn,
                                   pciDeviceList *list,
                                   pciDevice *dev);
-- 
1.6.2.5




More information about the libvir-list mailing list