Qemu driver stores a per-domain hash of used PCI addresses. Currently,
payload of each hash entry is exactly the same as its key, i.e., string
representation of a PCI address. This patch changes payload to be
virDomainDevicePCIAddressPtr. Along the road, return values of all
qemuPCIAddressAsString() calls are properly checked and error returned
if required.
---
src/qemu/qemu_conf.c | 78 ++++++++++++++++++++++++++++++++++++--------------
1 files changed, 56 insertions(+), 22 deletions(-)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index fb85220..38d28bf 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -2093,19 +2093,33 @@ static int qemuCollectPCIAddress(virDomainDefPtr def
ATTRIBUTE_UNUSED,
void *opaque)
{
qemuDomainPCIAddressSetPtr addrs = opaque;
+ virDomainDevicePCIAddressPtr pci = NULL;
+ char *addr = NULL;
if (dev->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
- char *addr = qemuPCIAddressAsString(dev);
+ if (!(addr = qemuPCIAddressAsString(dev)))
+ goto error;
+
+ if (VIR_ALLOC(pci) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ *pci = dev->addr.pci;
VIR_DEBUG("Remembering PCI addr %s", addr);
- if (virHashAddEntry(addrs->used, addr, addr) < 0) {
- VIR_FREE(addr);
- return -1;
- }
+ if (virHashAddEntry(addrs->used, addr, pci) < 0)
+ goto error;
+
+ VIR_FREE(addr);
}
return 0;
+
+error:
+ VIR_FREE(addr);
+ VIR_FREE(pci);
+ return -1;
}
@@ -2134,25 +2148,31 @@ error:
int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
virDomainDeviceInfoPtr dev)
{
- char *addr;
+ char *addr = NULL;
+ virDomainDevicePCIAddressPtr pci = NULL;
addr = qemuPCIAddressAsString(dev);
if (!addr)
- return -1;
+ goto error;
+
+ if (VIR_ALLOC(pci) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ *pci = dev->addr.pci;
VIR_DEBUG("Reserving PCI addr %s", addr);
if (virHashLookup(addrs->used, addr)) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("unable to reserve PCI address %s"), addr);
- VIR_FREE(addr);
- return -1;
+ goto error;
}
- if (virHashAddEntry(addrs->used, addr, addr)) {
- VIR_FREE(addr);
- return -1;
- }
+ if (virHashAddEntry(addrs->used, addr, pci))
+ goto error;
+
+ VIR_FREE(addr);
if (dev->addr.pci.slot > addrs->nextslot) {
addrs->nextslot = dev->addr.pci.slot + 1;
@@ -2161,6 +2181,11 @@ int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr
addrs,
}
return 0;
+
+error:
+ VIR_FREE(addr);
+ VIR_FREE(pci);
+ return -1;
}
int qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
@@ -2226,11 +2251,12 @@ int qemuDomainPCIAddressSetNextAddr(qemuDomainPCIAddressSetPtr
addrs,
{
int i;
int iteration;
+ char *addr = NULL;
+ virDomainDevicePCIAddressPtr pci = NULL;
for (i = addrs->nextslot, iteration = 0;
iteration <= QEMU_PCI_ADDRESS_LAST_SLOT; i++, iteration++) {
virDomainDeviceInfo maybe;
- char *addr;
if (QEMU_PCI_ADDRESS_LAST_SLOT < i)
i = 0;
@@ -2239,7 +2265,8 @@ int qemuDomainPCIAddressSetNextAddr(qemuDomainPCIAddressSetPtr
addrs,
maybe.addr.pci.bus = 0;
maybe.addr.pci.slot = i;
- addr = qemuPCIAddressAsString(&maybe);
+ if (!(addr = qemuPCIAddressAsString(&maybe)))
+ goto error;
if (virHashLookup(addrs->used, addr)) {
VIR_DEBUG("PCI addr %s already in use", addr);
@@ -2247,17 +2274,20 @@ int qemuDomainPCIAddressSetNextAddr(qemuDomainPCIAddressSetPtr
addrs,
continue;
}
+ if (VIR_ALLOC(pci) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ *pci = maybe.addr.pci;
+
VIR_DEBUG("Allocating PCI addr %s", addr);
- if (virHashAddEntry(addrs->used, addr, addr) < 0) {
- VIR_FREE(addr);
- return -1;
- }
+ if (virHashAddEntry(addrs->used, addr, pci) < 0)
+ goto error;
+ VIR_FREE(addr);
dev->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
- dev->addr.pci.domain = 0;
- dev->addr.pci.bus = 0;
- dev->addr.pci.slot = i;
+ dev->addr.pci = maybe.addr.pci;
addrs->nextslot = i + 1;
if (QEMU_PCI_ADDRESS_LAST_SLOT < addrs->nextslot)
@@ -2268,6 +2298,10 @@ int qemuDomainPCIAddressSetNextAddr(qemuDomainPCIAddressSetPtr
addrs,
qemuReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("No more available PCI addresses"));
+
+error:
+ VIR_FREE(addr);
+ VIR_FREE(pci);
return -1;
}
--
1.7.2