* 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