提交 dd9e9c3b 编写于 作者: D Daniel P. Berrange

Make pciDeviceList struct opaque

* 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
上级 790f0b30
...@@ -365,6 +365,11 @@ pciDeviceListFree; ...@@ -365,6 +365,11 @@ pciDeviceListFree;
pciDeviceListAdd; pciDeviceListAdd;
pciDeviceListDel; pciDeviceListDel;
pciDeviceFileIterate; pciDeviceFileIterate;
pciDeviceListCount;
pciDeviceListGet;
pciDeviceListLock;
pciDeviceListUnlock;
pciDeviceListSteal;
# qparams.h # qparams.h
......
...@@ -1365,7 +1365,7 @@ qemuUpdateActivePciHostdevs(struct qemud_driver *driver, ...@@ -1365,7 +1365,7 @@ qemuUpdateActivePciHostdevs(struct qemud_driver *driver,
virDomainDefPtr def) virDomainDefPtr def)
{ {
pciDeviceList *pcidevs; pciDeviceList *pcidevs;
int i, ret; int ret = -1;
if (!def->nhostdevs) if (!def->nhostdevs)
return 0; return 0;
...@@ -1373,18 +1373,19 @@ qemuUpdateActivePciHostdevs(struct qemud_driver *driver, ...@@ -1373,18 +1373,19 @@ qemuUpdateActivePciHostdevs(struct qemud_driver *driver,
if (!(pcidevs = qemuGetPciHostDeviceList(NULL, def))) if (!(pcidevs = qemuGetPciHostDeviceList(NULL, def)))
return -1; return -1;
ret = 0; while (pciDeviceListCount(pcidevs) > 0) {
pciDevice *dev = pciDeviceListSteal(NULL, pcidevs, 0);
for (i = 0; i < pcidevs->count; i++) {
if (pciDeviceListAdd(NULL, if (pciDeviceListAdd(NULL,
driver->activePciHostdevs, driver->activePciHostdevs,
pcidevs->devs[i]) < 0) { dev) < 0) {
ret = -1; pciFreeDevice(NULL, dev);
break; goto cleanup;
} }
pcidevs->devs[i] = NULL;
} }
ret = 0;
cleanup:
pciDeviceListFree(NULL, pcidevs); pciDeviceListFree(NULL, pcidevs);
return ret; return ret;
} }
...@@ -1396,6 +1397,7 @@ qemuPrepareHostDevices(virConnectPtr conn, ...@@ -1396,6 +1397,7 @@ qemuPrepareHostDevices(virConnectPtr conn,
{ {
pciDeviceList *pcidevs; pciDeviceList *pcidevs;
int i; int i;
int ret = -1;
if (!def->nhostdevs) if (!def->nhostdevs)
return 0; return 0;
...@@ -1415,33 +1417,39 @@ qemuPrepareHostDevices(virConnectPtr conn, ...@@ -1415,33 +1417,39 @@ qemuPrepareHostDevices(virConnectPtr conn,
* to pci-stub.ko * to pci-stub.ko
*/ */
for (i = 0; i < pcidevs->count; i++) for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
if (pciDeviceGetManaged(pcidevs->devs[i]) && pciDevice *dev = pciDeviceListGet(pcidevs, i);
pciDettachDevice(conn, pcidevs->devs[i]) < 0) if (pciDeviceGetManaged(dev) &&
goto error; pciDettachDevice(conn, dev) < 0)
goto cleanup;
}
/* Now that all the PCI hostdevs have be dettached, we can safely /* Now that all the PCI hostdevs have be dettached, we can safely
* reset them */ * reset them */
for (i = 0; i < pcidevs->count; i++) for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
if (pciResetDevice(conn, pcidevs->devs[i], pciDevice *dev = pciDeviceListGet(pcidevs, i);
if (pciResetDevice(conn, dev,
driver->activePciHostdevs) < 0) driver->activePciHostdevs) < 0)
goto error; goto cleanup;
}
/* Now mark all the devices as active */ /* 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, if (pciDeviceListAdd(conn,
driver->activePciHostdevs, driver->activePciHostdevs,
pcidevs->devs[i]) < 0) dev) < 0) {
goto error; pciFreeDevice(NULL, dev);
pcidevs->devs[i] = NULL; goto cleanup;
}
} }
pciDeviceListFree(conn, pcidevs); ret = 0;
return 0;
error: cleanup:
pciDeviceListFree(conn, pcidevs); pciDeviceListFree(conn, pcidevs);
return -1; return ret;
} }
static void static void
...@@ -1466,26 +1474,32 @@ qemuDomainReAttachHostDevices(virConnectPtr conn, ...@@ -1466,26 +1474,32 @@ qemuDomainReAttachHostDevices(virConnectPtr conn,
/* Again 3 loops; mark all devices as inactive before reset /* Again 3 loops; mark all devices as inactive before reset
* them and reset all the devices before re-attach */ * them and reset all the devices before re-attach */
for (i = 0; i < pcidevs->count; i++) for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
pciDeviceListDel(conn, driver->activePciHostdevs, pcidevs->devs[i]); pciDevice *dev = pciDeviceListGet(pcidevs, i);
pciDeviceListDel(conn, driver->activePciHostdevs, dev);
}
for (i = 0; i < pcidevs->count; i++) for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
if (pciResetDevice(conn, pcidevs->devs[i], pciDevice *dev = pciDeviceListGet(pcidevs, i);
if (pciResetDevice(conn, dev,
driver->activePciHostdevs) < 0) { driver->activePciHostdevs) < 0) {
virErrorPtr err = virGetLastError(); virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to reset PCI device: %s\n"), VIR_ERROR(_("Failed to reset PCI device: %s\n"),
err ? err->message : ""); err ? err->message : "");
virResetError(err); virResetError(err);
} }
}
for (i = 0; i < pcidevs->count; i++) for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
if (pciDeviceGetManaged(pcidevs->devs[i]) && pciDevice *dev = pciDeviceListGet(pcidevs, i);
pciReAttachDevice(conn, pcidevs->devs[i]) < 0) { if (pciDeviceGetManaged(dev) &&
pciReAttachDevice(NULL, dev) < 0) {
virErrorPtr err = virGetLastError(); virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to re-attach PCI device: %s\n"), VIR_ERROR(_("Failed to re-attach PCI device: %s\n"),
err ? err->message : ""); err ? err->message : "");
virResetError(err); virResetError(err);
} }
}
pciDeviceListFree(conn, pcidevs); pciDeviceListFree(conn, pcidevs);
} }
......
...@@ -66,6 +66,12 @@ struct _pciDevice { ...@@ -66,6 +66,12 @@ struct _pciDevice {
unsigned managed : 1; unsigned managed : 1;
}; };
struct _pciDeviceList {
unsigned count;
pciDevice **devs;
};
/* For virReportOOMError() and virReportSystemError() */ /* For virReportOOMError() and virReportSystemError() */
#define VIR_FROM_THIS VIR_FROM_NONE #define VIR_FROM_THIS VIR_FROM_NONE
...@@ -980,11 +986,30 @@ pciDeviceListAdd(virConnectPtr conn, ...@@ -980,11 +986,30 @@ pciDeviceListAdd(virConnectPtr conn,
return 0; return 0;
} }
void pciDevice *
pciDeviceListDel(virConnectPtr conn ATTRIBUTE_UNUSED, pciDeviceListGet(pciDeviceList *list,
pciDeviceList *list, int idx)
pciDevice *dev) {
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; int i;
for (i = 0; i < list->count; i++) { for (i = 0; i < list->count; i++) {
...@@ -994,7 +1019,7 @@ pciDeviceListDel(virConnectPtr conn ATTRIBUTE_UNUSED, ...@@ -994,7 +1019,7 @@ pciDeviceListDel(virConnectPtr conn ATTRIBUTE_UNUSED,
list->devs[i]->function != dev->function) list->devs[i]->function != dev->function)
continue; continue;
pciFreeDevice(conn, list->devs[i]); ret = list->devs[i];
if (i != --list->count) if (i != --list->count)
memmove(&list->devs[i], memmove(&list->devs[i],
...@@ -1007,6 +1032,17 @@ pciDeviceListDel(virConnectPtr conn ATTRIBUTE_UNUSED, ...@@ -1007,6 +1032,17 @@ pciDeviceListDel(virConnectPtr conn ATTRIBUTE_UNUSED,
break; break;
} }
return ret;
}
void
pciDeviceListDel(virConnectPtr conn,
pciDeviceList *list,
pciDevice *dev)
{
pciDevice *ret = pciDeviceListSteal(conn, list, dev);
if (ret)
pciFreeDevice(conn, ret);
} }
pciDevice * pciDevice *
......
...@@ -25,11 +25,7 @@ ...@@ -25,11 +25,7 @@
#include "internal.h" #include "internal.h"
typedef struct _pciDevice pciDevice; typedef struct _pciDevice pciDevice;
typedef struct _pciDeviceList pciDeviceList;
typedef struct {
unsigned count;
pciDevice **devs;
} pciDeviceList;
pciDevice *pciGetDevice (virConnectPtr conn, pciDevice *pciGetDevice (virConnectPtr conn,
unsigned domain, unsigned domain,
...@@ -55,6 +51,12 @@ void pciDeviceListFree (virConnectPtr conn, ...@@ -55,6 +51,12 @@ void pciDeviceListFree (virConnectPtr conn,
int pciDeviceListAdd (virConnectPtr conn, int pciDeviceListAdd (virConnectPtr conn,
pciDeviceList *list, pciDeviceList *list,
pciDevice *dev); pciDevice *dev);
pciDevice * pciDeviceListGet (pciDeviceList *list,
int idx);
int pciDeviceListCount (pciDeviceList *list);
pciDevice * pciDeviceListSteal (virConnectPtr conn,
pciDeviceList *list,
pciDevice *dev);
void pciDeviceListDel (virConnectPtr conn, void pciDeviceListDel (virConnectPtr conn,
pciDeviceList *list, pciDeviceList *list,
pciDevice *dev); pciDevice *dev);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册