Blob Blame History Raw
From ed1ef3fb4a2a5f3b710e2f4e215e8e5b45db6558 Mon Sep 17 00:00:00 2001
Message-Id: <ed1ef3fb4a2a5f3b710e2f4e215e8e5b45db6558.1383922565.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 8 Nov 2013 12:33:14 +0100
Subject: [PATCH] conf: Do better job when comparing features ABI compatibility

https://bugzilla.redhat.com/show_bug.cgi?id=1008989

The ABI compatibility check for domain features didn't check the
expanded HyperV and APIC EOI values, thus possibly allowing change in
guest ABI.

Add the check and use typecasted switch statement to warn developers
when adding a new HyperV feature.

(cherry picked from commit 5702c014b2b1feba7329e8b3dcc3a6be7cb4a88e)

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/conf/domain_conf.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 67 insertions(+), 5 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index dea8130..a1d7385 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -13315,6 +13315,72 @@ virDomainRedirFilterDefCheckABIStability(virDomainRedirFilterDefPtr src,
     return true;
 }
 
+
+static bool
+virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
+                                      virDomainDefPtr dst)
+{
+    size_t i;
+
+    /* basic check */
+    if (src->features != dst->features) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target domain features %d does not match source %d"),
+                       dst->features, src->features);
+        return false;
+    }
+
+    /* APIC EOI */
+    if (src->apic_eoi != dst->apic_eoi) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("State of APIC EOI differs: "
+                         "source: '%s', destination: '%s'"),
+                       virDomainFeatureStateTypeToString(src->apic_eoi),
+                       virDomainFeatureStateTypeToString(dst->apic_eoi));
+        return false;
+    }
+
+    /* hyperv */
+    if (src->features & (1 << VIR_DOMAIN_FEATURE_HYPERV)) {
+        for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
+            switch ((enum virDomainHyperv) i) {
+            case VIR_DOMAIN_HYPERV_RELAXED:
+            case VIR_DOMAIN_HYPERV_VAPIC:
+                if (src->hyperv_features[i] != dst->hyperv_features[i]) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                   _("State of HyperV enlightenment "
+                                     "feature '%s' differs: "
+                                     "source: '%s', destination: '%s'"),
+                                   virDomainHypervTypeToString(i),
+                                   virDomainFeatureStateTypeToString(src->hyperv_features[i]),
+                                   virDomainFeatureStateTypeToString(dst->hyperv_features[i]));
+                    return false;
+                }
+
+                break;
+
+            case VIR_DOMAIN_HYPERV_SPINLOCKS:
+                /* spinlock count matters! */
+                if (src->hyperv_spinlocks != dst->hyperv_spinlocks) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                   _("HyperV spinlock retry count differs: "
+                                     "source: '%u', destination: '%u'"),
+                                   src->hyperv_spinlocks,
+                                   dst->hyperv_spinlocks);
+                    return false;
+                }
+                break;
+
+            case VIR_DOMAIN_HYPERV_LAST:
+                break;
+            }
+        }
+    }
+
+    return true;
+}
+
+
 /* This compares two configurations and looks for any differences
  * which will affect the guest ABI. This is primarily to allow
  * validation of custom XML config passed in during migration
@@ -13416,12 +13482,8 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
         return false;
     }
 
-    if (src->features != dst->features) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("Target domain features %d does not match source %d"),
-                       dst->features, src->features);
+    if (!virDomainDefFeaturesCheckABIStability(src, dst))
         return false;
-    }
 
     if (src->clock.ntimers != dst->clock.ntimers) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-- 
1.8.4.2