USB controller gets put on the first place in XML, but the default one
is added at the end of the controllers array. Sorting them before
checking ABI compatibility solves this.

The default USB controller also doesn't get a PCI address assigned,
making virDomainDeviceInfoCheckABIStability fail.
---
 src/conf/domain_conf.c |   55 +++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 58603a3..c98802a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9765,8 +9765,10 @@ static bool 
virDomainControllerDefCheckABIStability(virDomainControllerDefPtr sr
         }
     }
 
-    if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info))
-        goto cleanup;
+    /* don't check device info for the default USB controller */
+    if (!(src->type == VIR_DOMAIN_CONTROLLER_TYPE_USB && src->idx == 0 && 
src->model == -1))
+        if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info))
+            goto cleanup;
 
     identical = true;
 
@@ -10180,6 +10182,27 @@ cleanup:
     return identical;
 }
 
+static int virDomainControllerCmp(const void *ctrl1,
+                                  const void *ctrl2)
+{
+    virDomainControllerDefPtr c1 = *(virDomainControllerDefPtr*) ctrl1;
+    virDomainControllerDefPtr c2 = *(virDomainControllerDefPtr*) ctrl2;
+
+    if (c1->type < c2->type)
+        return -1;
+    if (c1->type > c2->type)
+        return 1;
+    if (c1->idx < c2->idx)
+        return -1;
+    if (c1->idx > c2->idx)
+        return 1;
+    if (c1->model < c1->model)
+        return -1;
+    if (c1->model > c2->model)
+        return 1;
+    return 0;
+}
+
 
 /* This compares two configurations and looks for any differences
  * which will affect the guest ABI. This is primarily to allow
@@ -10191,6 +10214,9 @@ bool virDomainDefCheckABIStability(virDomainDefPtr src,
     bool identical = false;
     int i;
 
+    virDomainControllerDefPtr *scontrollers = NULL;
+    virDomainControllerDefPtr *dcontrollers = NULL;
+
     if (src->virtType != dst->virtType) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("Target domain virt type %s does not match source 
%s"),
@@ -10312,10 +10338,33 @@ bool virDomainDefCheckABIStability(virDomainDefPtr 
src,
         goto cleanup;
     }
 
+    /* sort the controllers before comparison */
+    if (VIR_ALLOC_N(scontrollers, src->ncontrollers) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    memcpy(scontrollers, src->controllers, 
src->ncontrollers*sizeof(src->controllers[0]));
+    qsort(scontrollers, src->ncontrollers, sizeof(virDomainControllerDefPtr),
+          virDomainControllerCmp);
+
+
+    if (VIR_ALLOC_N(dcontrollers, dst->ncontrollers) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    memcpy(dcontrollers, dst->controllers, 
dst->ncontrollers*sizeof(dst->controllers[0]));
+    qsort(dcontrollers, dst->ncontrollers, sizeof(virDomainControllerDefPtr),
+          virDomainControllerCmp);
+
     for (i = 0 ; i < src->ncontrollers ; i++)
-        if (!virDomainControllerDefCheckABIStability(src->controllers[i], 
dst->controllers[i]))
+        if (!virDomainControllerDefCheckABIStability(scontrollers[i], 
dcontrollers[i]))
             goto cleanup;
 
+    VIR_FREE(scontrollers);
+    VIR_FREE(dcontrollers);
+
     if (src->nfss != dst->nfss) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("Target domain filesystem count %d does not match 
source %d"),
-- 
1.7.8.6

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to