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 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list