43fe83
From 93617e955bbad37f73c800cbb962b30551f2ccad Mon Sep 17 00:00:00 2001
43fe83
Message-Id: <93617e955bbad37f73c800cbb962b30551f2ccad.1377873637.git.jdenemar@redhat.com>
43fe83
From: Laine Stump <laine@laine.org>
43fe83
Date: Tue, 6 Aug 2013 13:23:27 -0600
43fe83
Subject: [PATCH] qemu: improve error reporting during PCI address validation
43fe83
43fe83
This patch is part of the resolution to:
43fe83
43fe83
   https://bugzilla.redhat.com/show_bug.cgi?id=819968
43fe83
43fe83
This patch addresses two concerns with the error reporting when an
43fe83
incompatible PCI address is specified for a device:
43fe83
43fe83
1) It wasn't always apparent which device had the problem. With this
43fe83
patch applied, any error about an incompatible address will always
43fe83
contain the full address as given in the config, so it will be easier
43fe83
to determine which device's config aused the problem.
43fe83
43fe83
2) In some cases when the problem came from bad config, the error
43fe83
message was erroneously classified as VIR_ERR_INTERNAL_ERROR. With
43fe83
this patch applied, the same error message will be changed to indicate
43fe83
either "internal" or "xml" error depending on whether the address came
43fe83
from the config, or was automatically generated by libvirt.
43fe83
43fe83
Note that in the case of "internal" (due to bad auto-generation)
43fe83
errors, the PCI address won't be of much use in finding the location
43fe83
in config to change (because it was automatically generated). Of
43fe83
course that makes perfect sense, but still the address could provide a
43fe83
clue about a bug in libvirt attempting to use a type of pci bus that
43fe83
doesn't have its flags set correctly (or something similar). In other
43fe83
words, it's not perfect, but it is definitely better.
43fe83
(cherry picked from commit c033e210613b860bef4859a81e22088d0d2f0f29)
43fe83
---
43fe83
 src/qemu/qemu_command.c | 224 +++++++++++++++++++++++++++++-------------------
43fe83
 1 file changed, 138 insertions(+), 86 deletions(-)
43fe83
43fe83
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
43fe83
index a8fce22..b811e1d 100644
43fe83
--- a/src/qemu/qemu_command.c
43fe83
+++ b/src/qemu/qemu_command.c
43fe83
@@ -1445,10 +1445,15 @@ struct _qemuDomainPCIAddressSet {
43fe83
 
43fe83
 static bool
43fe83
 qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
43fe83
+                                    const char *addrStr,
43fe83
                                     qemuDomainPCIConnectFlags busFlags,
43fe83
                                     qemuDomainPCIConnectFlags devFlags,
43fe83
-                                    bool reportError)
43fe83
+                                    bool reportError,
43fe83
+                                    bool fromConfig)
43fe83
 {
43fe83
+    virErrorNumber errType = (fromConfig
43fe83
+                              ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
43fe83
+
43fe83
     /* If this bus doesn't allow the type of connection (PCI
43fe83
      * vs. PCIe) required by the device, or if the device requires
43fe83
      * hot-plug and this bus doesn't have it, return false.
43fe83
@@ -1456,24 +1461,24 @@ qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
43fe83
     if (!(devFlags & busFlags & QEMU_PCI_CONNECT_TYPES_MASK)) {
43fe83
         if (reportError) {
43fe83
             if (devFlags & QEMU_PCI_CONNECT_TYPE_PCI) {
43fe83
-                virReportError(VIR_ERR_INTERNAL_ERROR,
43fe83
-                               _("PCI bus %.4x:%.2x is not compatible with the "
43fe83
-                                 "device. Device requires a standard PCI slot, "
43fe83
-                                 "which is not provided by this bus"),
43fe83
-                               addr->domain, addr->bus);
43fe83
+                virReportError(errType,
43fe83
+                               _("PCI bus is not compatible with the device "
43fe83
+                                 "at %s. Device requires a standard PCI slot, "
43fe83
+                                 "which is not provided by bus %.4x:%.2x"),
43fe83
+                               addrStr, addr->domain, addr->bus);
43fe83
             } else if (devFlags & QEMU_PCI_CONNECT_TYPE_PCIE) {
43fe83
-                virReportError(VIR_ERR_INTERNAL_ERROR,
43fe83
-                               _("PCI bus %.4x:%.2x is not compatible with the "
43fe83
-                                 "device. Device requires a PCI Express slot, "
43fe83
-                                 "which is not provided by this bus"),
43fe83
-                               addr->domain, addr->bus);
43fe83
+                virReportError(errType,
43fe83
+                               _("PCI bus is not compatible with the device "
43fe83
+                                 "at %s. Device requires a PCI Express slot, "
43fe83
+                                 "which is not provided by bus %.4x:%.2x"),
43fe83
+                               addrStr, addr->domain, addr->bus);
43fe83
             } else {
43fe83
                 /* this should never happen. If it does, there is a
43fe83
                  * bug in the code that sets the flag bits for devices.
43fe83
                  */
43fe83
-                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
43fe83
-                           _("The device information has no PCI "
43fe83
-                             "connection types listed"));
43fe83
+                virReportError(errType,
43fe83
+                           _("The device information for %s has no PCI "
43fe83
+                             "connection types listed"), addrStr);
43fe83
             }
43fe83
         }
43fe83
         return false;
43fe83
@@ -1481,11 +1486,11 @@ qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
43fe83
     if ((devFlags & QEMU_PCI_CONNECT_HOTPLUGGABLE) &&
43fe83
         !(busFlags & QEMU_PCI_CONNECT_HOTPLUGGABLE)) {
43fe83
         if (reportError) {
43fe83
-            virReportError(VIR_ERR_INTERNAL_ERROR,
43fe83
-                           _("PCI bus %.4x:%.2x is not compatible with the "
43fe83
-                             "device. Device requires hot-plug capability, "
43fe83
-                             "which is not provided by the bus"),
43fe83
-                           addr->domain, addr->bus);
43fe83
+            virReportError(errType,
43fe83
+                           _("PCI bus is not compatible with the device "
43fe83
+                             "at %s. Device requires hot-plug capability, "
43fe83
+                             "which is not provided by bus %.4x:%.2x"),
43fe83
+                           addrStr, addr->domain, addr->bus);
43fe83
         }
43fe83
         return false;
43fe83
     }
43fe83
@@ -1500,23 +1505,30 @@ qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
43fe83
 static bool
43fe83
 qemuDomainPCIAddressValidate(qemuDomainPCIAddressSetPtr addrs,
43fe83
                              virDevicePCIAddressPtr addr,
43fe83
-                             qemuDomainPCIConnectFlags flags)
43fe83
+                             const char *addrStr,
43fe83
+                             qemuDomainPCIConnectFlags flags,
43fe83
+                             bool fromConfig)
43fe83
 {
43fe83
     qemuDomainPCIAddressBusPtr bus;
43fe83
+    virErrorNumber errType = (fromConfig
43fe83
+                              ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
43fe83
 
43fe83
     if (addrs->nbuses == 0) {
43fe83
-        virReportError(VIR_ERR_XML_ERROR, "%s", _("No PCI buses available"));
43fe83
+        virReportError(errType, "%s", _("No PCI buses available"));
43fe83
         return false;
43fe83
     }
43fe83
     if (addr->domain != 0) {
43fe83
-        virReportError(VIR_ERR_XML_ERROR, "%s",
43fe83
-                       _("Only PCI domain 0 is available"));
43fe83
+        virReportError(errType,
43fe83
+                       _("Invalid PCI address %s. "
43fe83
+                         "Only PCI domain 0 is available"),
43fe83
+                       addrStr);
43fe83
         return false;
43fe83
     }
43fe83
     if (addr->bus >= addrs->nbuses) {
43fe83
-        virReportError(VIR_ERR_XML_ERROR,
43fe83
-                       _("Only PCI buses up to %zu are available"),
43fe83
-                       addrs->nbuses - 1);
43fe83
+        virReportError(errType,
43fe83
+                       _("Invalid PCI address %s. "
43fe83
+                         "Only PCI buses up to %zu are available"),
43fe83
+                       addrStr, addrs->nbuses - 1);
43fe83
         return false;
43fe83
     }
43fe83
 
43fe83
@@ -1525,26 +1537,27 @@ qemuDomainPCIAddressValidate(qemuDomainPCIAddressSetPtr addrs,
43fe83
     /* assure that at least one of the requested connection types is
43fe83
      * provided by this bus
43fe83
      */
43fe83
-    if (!qemuDomainPCIAddressFlagsCompatible(addr, bus->flags, flags, true))
43fe83
+    if (!qemuDomainPCIAddressFlagsCompatible(addr, addrStr, bus->flags,
43fe83
+                                             flags, true, fromConfig))
43fe83
         return false;
43fe83
 
43fe83
     /* some "buses" are really just a single port */
43fe83
     if (bus->minSlot && addr->slot < bus->minSlot) {
43fe83
-        virReportError(VIR_ERR_XML_ERROR,
43fe83
-                       _("Invalid PCI address: slot must be >= %zu"),
43fe83
-                       bus->minSlot);
43fe83
+        virReportError(errType,
43fe83
+                       _("Invalid PCI address %s. slot must be >= %zu"),
43fe83
+                       addrStr, bus->minSlot);
43fe83
         return false;
43fe83
     }
43fe83
     if (addr->slot > bus->maxSlot) {
43fe83
-        virReportError(VIR_ERR_XML_ERROR,
43fe83
-                       _("Invalid PCI address: slot must be <= %zu"),
43fe83
-                       bus->maxSlot);
43fe83
+        virReportError(errType,
43fe83
+                       _("Invalid PCI address %s. slot must be <= %zu"),
43fe83
+                       addrStr, bus->maxSlot);
43fe83
         return false;
43fe83
     }
43fe83
     if (addr->function > QEMU_PCI_ADDRESS_FUNCTION_LAST) {
43fe83
-        virReportError(VIR_ERR_XML_ERROR,
43fe83
-                       _("Invalid PCI address: function must be <= %u"),
43fe83
-                       QEMU_PCI_ADDRESS_FUNCTION_LAST);
43fe83
+        virReportError(errType,
43fe83
+                       _("Invalid PCI address %s. function must be <= %u"),
43fe83
+                       addrStr, QEMU_PCI_ADDRESS_FUNCTION_LAST);
43fe83
         return false;
43fe83
     }
43fe83
     return true;
43fe83
@@ -1953,12 +1966,12 @@ qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
43fe83
                                 bool fromConfig)
43fe83
 {
43fe83
     int ret = -1;
43fe83
-    char *str = NULL;
43fe83
+    char *addrStr = NULL;
43fe83
     qemuDomainPCIAddressBusPtr bus;
43fe83
     virErrorNumber errType = (fromConfig
43fe83
                               ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
43fe83
 
43fe83
-    if (!(str = qemuDomainPCIAddressAsString(addr)))
43fe83
+    if (!(addrStr = qemuDomainPCIAddressAsString(addr)))
43fe83
         goto cleanup;
43fe83
 
43fe83
     /* Add an extra bus if necessary */
43fe83
@@ -1967,7 +1980,7 @@ qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
43fe83
     /* Check that the requested bus exists, is the correct type, and we
43fe83
      * are asking for a valid slot
43fe83
      */
43fe83
-    if (!qemuDomainPCIAddressValidate(addrs, addr, flags))
43fe83
+    if (!qemuDomainPCIAddressValidate(addrs, addr, addrStr, flags, fromConfig))
43fe83
         goto cleanup;
43fe83
 
43fe83
     bus = &addrs->buses[addr->bus];
43fe83
@@ -1977,31 +1990,32 @@ qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
43fe83
             virReportError(errType,
43fe83
                            _("Attempted double use of PCI slot %s "
43fe83
                              "(may need \"multifunction='on'\" for "
43fe83
-                             "device on function 0)"), str);
43fe83
+                             "device on function 0)"), addrStr);
43fe83
             goto cleanup;
43fe83
         }
43fe83
         bus->slots[addr->slot] = 0xFF; /* reserve all functions of slot */
43fe83
-        VIR_DEBUG("Reserving PCI slot %s (multifunction='off')", str);
43fe83
+        VIR_DEBUG("Reserving PCI slot %s (multifunction='off')", addrStr);
43fe83
     } else {
43fe83
         if (bus->slots[addr->slot] & (1 << addr->function)) {
43fe83
             if (addr->function == 0) {
43fe83
                 virReportError(errType,
43fe83
-                               _("Attempted double use of PCI Address %s"), str);
43fe83
+                               _("Attempted double use of PCI Address %s"),
43fe83
+                               addrStr);
43fe83
             } else {
43fe83
                 virReportError(errType,
43fe83
                                _("Attempted double use of PCI Address %s "
43fe83
                                  "(may need \"multifunction='on'\" "
43fe83
-                                 "for device on function 0)"), str);
43fe83
+                                 "for device on function 0)"), addrStr);
43fe83
             }
43fe83
             goto cleanup;
43fe83
         }
43fe83
         bus->slots[addr->slot] |= (1 << addr->function);
43fe83
-        VIR_DEBUG("Reserving PCI address %s", str);
43fe83
+        VIR_DEBUG("Reserving PCI address %s", addrStr);
43fe83
     }
43fe83
 
43fe83
     ret = 0;
43fe83
 cleanup:
43fe83
-    VIR_FREE(str);
43fe83
+    VIR_FREE(addrStr);
43fe83
     return ret;
43fe83
 }
43fe83
 
43fe83
@@ -2017,7 +2031,8 @@ qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
43fe83
 int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
43fe83
                                    virDomainDeviceInfoPtr dev)
43fe83
 {
43fe83
-    int ret = 0;
43fe83
+    int ret = -1;
43fe83
+    char *addrStr = NULL;
43fe83
     /* Flags should be set according to the particular device,
43fe83
      * but only the caller knows the type of device. Currently this
43fe83
      * function is only used for hot-plug, though, and hot-plug is
43fe83
@@ -2026,6 +2041,9 @@ int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
43fe83
     qemuDomainPCIConnectFlags flags = (QEMU_PCI_CONNECT_HOTPLUGGABLE |
43fe83
                                        QEMU_PCI_CONNECT_TYPE_PCI);
43fe83
 
43fe83
+    if (!(addrStr = qemuDomainPCIAddressAsString(&dev->addr.pci)))
43fe83
+        goto cleanup;
43fe83
+
43fe83
     if (dev->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
43fe83
         /* We do not support hotplug multi-function PCI device now, so we should
43fe83
          * reserve the whole slot. The function of the PCI device must be 0.
43fe83
@@ -2034,16 +2052,20 @@ int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
43fe83
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
43fe83
                            _("Only PCI device addresses with function=0"
43fe83
                              " are supported"));
43fe83
-            return -1;
43fe83
+            goto cleanup;
43fe83
         }
43fe83
 
43fe83
-        if (!qemuDomainPCIAddressValidate(addrs, &dev->addr.pci, flags))
43fe83
-            return -1;
43fe83
+        if (!qemuDomainPCIAddressValidate(addrs, &dev->addr.pci,
43fe83
+                                          addrStr, flags, true))
43fe83
+            goto cleanup;
43fe83
 
43fe83
         ret = qemuDomainPCIAddressReserveSlot(addrs, &dev->addr.pci, flags);
43fe83
     } else {
43fe83
         ret = qemuDomainPCIAddressReserveNextSlot(addrs, dev, flags);
43fe83
     }
43fe83
+
43fe83
+cleanup:
43fe83
+    VIR_FREE(addrStr);
43fe83
     return ret;
43fe83
 }
43fe83
 
43fe83
@@ -2063,12 +2085,20 @@ qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs,
43fe83
      * already had it, and are giving it back.
43fe83
      */
43fe83
     qemuDomainPCIConnectFlags flags = QEMU_PCI_CONNECT_TYPES_MASK;
43fe83
+    int ret = -1;
43fe83
+    char *addrStr = NULL;
43fe83
 
43fe83
-    if (!qemuDomainPCIAddressValidate(addrs, addr, flags))
43fe83
-        return -1;
43fe83
+    if (!(addrStr = qemuDomainPCIAddressAsString(addr)))
43fe83
+        goto cleanup;
43fe83
+
43fe83
+    if (!qemuDomainPCIAddressValidate(addrs, addr, addrStr, flags, false))
43fe83
+        goto cleanup;
43fe83
 
43fe83
     addrs->buses[addr->bus].slots[addr->slot] = 0;
43fe83
-    return 0;
43fe83
+    ret = 0;
43fe83
+cleanup:
43fe83
+    VIR_FREE(addrStr);
43fe83
+    return ret;
43fe83
 }
43fe83
 
43fe83
 void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs)
43fe83
@@ -2090,6 +2120,7 @@ qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs,
43fe83
      * 0000:00:00.0
43fe83
      */
43fe83
     virDevicePCIAddress a = { 0, 0, 0, 0, false };
43fe83
+    char *addrStr = NULL;
43fe83
 
43fe83
     /* except if this search is for the exact same type of device as
43fe83
      * last time, continue the search from the previous match
43fe83
@@ -2099,13 +2130,17 @@ qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs,
43fe83
 
43fe83
     if (addrs->nbuses == 0) {
43fe83
         virReportError(VIR_ERR_XML_ERROR, "%s", _("No PCI buses available"));
43fe83
-        return -1;
43fe83
+        goto error;
43fe83
     }
43fe83
 
43fe83
     /* Start the search at the last used bus and slot */
43fe83
     for (a.slot++; a.bus < addrs->nbuses; a.bus++) {
43fe83
-        if (!qemuDomainPCIAddressFlagsCompatible(&a, addrs->buses[a.bus].flags,
43fe83
-                                                 flags, false)) {
43fe83
+        addrStr = NULL;
43fe83
+        if (!(addrStr = qemuDomainPCIAddressAsString(&a)))
43fe83
+            goto error;
43fe83
+        if (!qemuDomainPCIAddressFlagsCompatible(&a, addrStr,
43fe83
+                                                 addrs->buses[a.bus].flags,
43fe83
+                                                 flags, false, false)) {
43fe83
             VIR_DEBUG("PCI bus %.4x:%.2x is not compatible with the device",
43fe83
                       a.domain, a.bus);
43fe83
             continue;
43fe83
@@ -2124,13 +2159,17 @@ qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs,
43fe83
     if (addrs->dryRun) {
43fe83
         /* a is already set to the first new bus and slot 1 */
43fe83
         if (qemuDomainPCIAddressSetGrow(addrs, &a, flags) < 0)
43fe83
-            return -1;
43fe83
+            goto error;
43fe83
         goto success;
43fe83
     } else if (flags == addrs->lastFlags) {
43fe83
         /* Check the buses from 0 up to the last used one */
43fe83
         for (a.bus = 0; a.bus <= addrs->lastaddr.bus; a.bus++) {
43fe83
-            if (!qemuDomainPCIAddressFlagsCompatible(&a, addrs->buses[a.bus].flags,
43fe83
-                                                     flags, false)) {
43fe83
+            addrStr = NULL;
43fe83
+            if (!(addrStr = qemuDomainPCIAddressAsString(&a)))
43fe83
+                goto error;
43fe83
+            if (!qemuDomainPCIAddressFlagsCompatible(&a, addrStr,
43fe83
+                                                     addrs->buses[a.bus].flags,
43fe83
+                                                     flags, false, false)) {
43fe83
                 VIR_DEBUG("PCI bus %.4x:%.2x is not compatible with the device",
43fe83
                           a.domain, a.bus);
43fe83
                 continue;
43fe83
@@ -2147,12 +2186,15 @@ qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs,
43fe83
 
43fe83
     virReportError(VIR_ERR_INTERNAL_ERROR,
43fe83
                    "%s", _("No more available PCI slots"));
43fe83
+error:
43fe83
+    VIR_FREE(addrStr);
43fe83
     return -1;
43fe83
 
43fe83
 success:
43fe83
     VIR_DEBUG("Found free PCI slot %.4x:%.2x:%.2x",
43fe83
               a.domain, a.bus, a.slot);
43fe83
     *next_addr = a;
43fe83
+    VIR_FREE(addrStr);
43fe83
     return 0;
43fe83
 }
43fe83
 
43fe83
@@ -2217,10 +2259,12 @@ qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
43fe83
                                 virQEMUCapsPtr qemuCaps,
43fe83
                                 qemuDomainPCIAddressSetPtr addrs)
43fe83
 {
43fe83
+    int ret = -1;
43fe83
     size_t i;
43fe83
     virDevicePCIAddress tmp_addr;
43fe83
     bool qemuDeviceVideoUsable = virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
43fe83
     virDevicePCIAddressPtr addrptr;
43fe83
+    char *addrStr = NULL;
43fe83
     qemuDomainPCIConnectFlags flags = QEMU_PCI_CONNECT_HOTPLUGGABLE | QEMU_PCI_CONNECT_TYPE_PCI;
43fe83
 
43fe83
     /* Verify that first IDE and USB controllers (if any) is on the PIIX3, fn 1 */
43fe83
@@ -2235,7 +2279,7 @@ qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
43fe83
                     def->controllers[i]->info.addr.pci.function != 1) {
43fe83
                     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
43fe83
                                    _("Primary IDE controller must have PCI address 0:0:1.1"));
43fe83
-                    goto error;
43fe83
+                    goto cleanup;
43fe83
                 }
43fe83
             } else {
43fe83
                 def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
43fe83
@@ -2255,7 +2299,7 @@ qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
43fe83
                     def->controllers[i]->info.addr.pci.function != 2) {
43fe83
                     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
43fe83
                                    _("PIIX3 USB controller must have PCI address 0:0:1.2"));
43fe83
-                    goto error;
43fe83
+                    goto cleanup;
43fe83
                 }
43fe83
             } else {
43fe83
                 def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
43fe83
@@ -2274,7 +2318,7 @@ qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
43fe83
         memset(&tmp_addr, 0, sizeof(tmp_addr));
43fe83
         tmp_addr.slot = 1;
43fe83
         if (qemuDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
43fe83
-            goto error;
43fe83
+            goto cleanup;
43fe83
     }
43fe83
 
43fe83
     if (def->nvideos > 0) {
43fe83
@@ -2293,8 +2337,11 @@ qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
43fe83
             primaryVideo->info.addr.pci.function = 0;
43fe83
             addrptr = &primaryVideo->info.addr.pci;
43fe83
 
43fe83
-            if (!qemuDomainPCIAddressValidate(addrs, addrptr, flags))
43fe83
-                goto error;
43fe83
+            if (!(addrStr = qemuDomainPCIAddressAsString(addrptr)))
43fe83
+                goto cleanup;
43fe83
+            if (!qemuDomainPCIAddressValidate(addrs, addrptr,
43fe83
+                                              addrStr, flags, false))
43fe83
+                goto cleanup;
43fe83
 
43fe83
             if (qemuDomainPCIAddressSlotInUse(addrs, addrptr)) {
43fe83
                 if (qemuDeviceVideoUsable) {
43fe83
@@ -2302,15 +2349,15 @@ qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
43fe83
                     if (qemuDomainPCIAddressReserveNextSlot(addrs,
43fe83
                                                             &primaryVideo->info,
43fe83
                                                             flags) < 0)
43fe83
-                        goto error;
43fe83
+                        goto cleanup;
43fe83
                 } else {
43fe83
                     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
43fe83
                                    _("PCI address 0:0:2.0 is in use, "
43fe83
                                      "QEMU needs it for primary video"));
43fe83
-                    goto error;
43fe83
+                    goto cleanup;
43fe83
                 }
43fe83
             } else if (qemuDomainPCIAddressReserveSlot(addrs, addrptr, flags) < 0) {
43fe83
-                goto error;
43fe83
+                goto cleanup;
43fe83
             }
43fe83
         } else if (!qemuDeviceVideoUsable) {
43fe83
             if (primaryVideo->info.addr.pci.domain != 0 ||
43fe83
@@ -2319,7 +2366,7 @@ qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
43fe83
                 primaryVideo->info.addr.pci.function != 0) {
43fe83
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
43fe83
                                _("Primary video card must have PCI address 0:0:2.0"));
43fe83
-                goto error;
43fe83
+                goto cleanup;
43fe83
             }
43fe83
             /* If TYPE==PCI, then qemuCollectPCIAddress() function
43fe83
              * has already reserved the address, so we must skip */
43fe83
@@ -2334,13 +2381,13 @@ qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
43fe83
                       " intervention");
43fe83
             virResetLastError();
43fe83
         } else if (qemuDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) {
43fe83
-            goto error;
43fe83
+            goto cleanup;
43fe83
         }
43fe83
     }
43fe83
-    return 0;
43fe83
-
43fe83
-error:
43fe83
-    return -1;
43fe83
+    ret = 0;
43fe83
+cleanup:
43fe83
+    VIR_FREE(addrStr);
43fe83
+    return ret;
43fe83
 }
43fe83
 
43fe83
 
43fe83
@@ -2357,10 +2404,12 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
43fe83
                                     virQEMUCapsPtr qemuCaps,
43fe83
                                     qemuDomainPCIAddressSetPtr addrs)
43fe83
 {
43fe83
+    int ret = -1;
43fe83
     size_t i;
43fe83
     virDevicePCIAddress tmp_addr;
43fe83
     bool qemuDeviceVideoUsable = virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
43fe83
     virDevicePCIAddressPtr addrptr;
43fe83
+    char *addrStr = NULL;
43fe83
     qemuDomainPCIConnectFlags flags = QEMU_PCI_CONNECT_TYPE_PCIE;
43fe83
 
43fe83
     /* Verify that the first SATA controller is at 00:1F.2 */
43fe83
@@ -2375,7 +2424,7 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
43fe83
                     def->controllers[i]->info.addr.pci.function != 2) {
43fe83
                     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
43fe83
                                    _("Primary SATA controller must have PCI address 0:0:1f.2"));
43fe83
-                    goto error;
43fe83
+                    goto cleanup;
43fe83
                 }
43fe83
             } else {
43fe83
                 def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
43fe83
@@ -2399,12 +2448,12 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
43fe83
         tmp_addr.multi = 1;
43fe83
         if (qemuDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
43fe83
                                             false, false) < 0)
43fe83
-           goto error;
43fe83
+           goto cleanup;
43fe83
         tmp_addr.function = 3;
43fe83
         tmp_addr.multi = 0;
43fe83
         if (qemuDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
43fe83
                                             false, false) < 0)
43fe83
-           goto error;
43fe83
+           goto cleanup;
43fe83
     }
43fe83
 
43fe83
     if (def->nvideos > 0) {
43fe83
@@ -2423,8 +2472,11 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
43fe83
             primaryVideo->info.addr.pci.function = 0;
43fe83
             addrptr = &primaryVideo->info.addr.pci;
43fe83
 
43fe83
-            if (!qemuDomainPCIAddressValidate(addrs, addrptr, flags))
43fe83
-                goto error;
43fe83
+            if (!(addrStr = qemuDomainPCIAddressAsString(addrptr)))
43fe83
+                goto cleanup;
43fe83
+            if (!qemuDomainPCIAddressValidate(addrs, addrptr,
43fe83
+                                              addrStr, flags, false))
43fe83
+                goto cleanup;
43fe83
 
43fe83
             if (qemuDomainPCIAddressSlotInUse(addrs, addrptr)) {
43fe83
                 if (qemuDeviceVideoUsable) {
43fe83
@@ -2432,15 +2484,15 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
43fe83
                     if (qemuDomainPCIAddressReserveNextSlot(addrs,
43fe83
                                                             &primaryVideo->info,
43fe83
                                                             flags) < 0)
43fe83
-                        goto error;
43fe83
+                        goto cleanup;
43fe83
                 } else {
43fe83
                     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
43fe83
                                    _("PCI address 0:0:1.0 is in use, "
43fe83
                                      "QEMU needs it for primary video"));
43fe83
-                    goto error;
43fe83
+                    goto cleanup;
43fe83
                 }
43fe83
             } else if (qemuDomainPCIAddressReserveSlot(addrs, addrptr, flags) < 0) {
43fe83
-                goto error;
43fe83
+                goto cleanup;
43fe83
             }
43fe83
         } else if (!qemuDeviceVideoUsable) {
43fe83
             if (primaryVideo->info.addr.pci.domain != 0 ||
43fe83
@@ -2449,7 +2501,7 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
43fe83
                 primaryVideo->info.addr.pci.function != 0) {
43fe83
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
43fe83
                                _("Primary video card must have PCI address 0:0:1.0"));
43fe83
-                goto error;
43fe83
+                goto cleanup;
43fe83
             }
43fe83
             /* If TYPE==PCI, then qemuCollectPCIAddress() function
43fe83
              * has already reserved the address, so we must skip */
43fe83
@@ -2464,13 +2516,13 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
43fe83
                       " intervention");
43fe83
             virResetLastError();
43fe83
         } else if (qemuDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) {
43fe83
-            goto error;
43fe83
+            goto cleanup;
43fe83
         }
43fe83
     }
43fe83
-    return 0;
43fe83
-
43fe83
-error:
43fe83
-    return -1;
43fe83
+    ret = 0;
43fe83
+cleanup:
43fe83
+    VIR_FREE(addrStr);
43fe83
+    return ret;
43fe83
 }
43fe83
 
43fe83
 
43fe83
-- 
43fe83
1.8.3.2
43fe83