[libvirt] [PATCH] Fix save/restore with USB controller in XML.

Ján Tomko jtomko at redhat.com
Fri Aug 3 14:54:17 UTC 2012


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




More information about the libvir-list mailing list