]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
cpuCompare*: Add support for reporting failure on incompatible CPUs
authorJiri Denemark <jdenemar@redhat.com>
Wed, 28 May 2014 13:11:57 +0000 (15:11 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Wed, 25 Jun 2014 22:43:54 +0000 (00:43 +0200)
When CPU comparison APIs return VIR_CPU_COMPARE_INCOMPATIBLE, the caller
has no clue why the CPU is considered incompatible with host CPU. And in
some cases, it would be nice to be able to get such info in a client
rather than having to look in logs.

To achieve this, the APIs can be told to return VIR_ERR_CPU_INCOMPATIBLE
error for incompatible CPUs and the reason will be described in the
associated error message.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
12 files changed:
include/libvirt/virterror.h
src/bhyve/bhyve_driver.c
src/cpu/cpu.c
src/cpu/cpu.h
src/cpu/cpu_aarch64.c
src/cpu/cpu_arm.c
src/cpu/cpu_generic.c
src/cpu/cpu_powerpc.c
src/cpu/cpu_x86.c
src/qemu/qemu_driver.c
src/util/virerror.c
tests/cputest.c

index be90797c436f9cbfbf54defd9fde8a4dc1ad1002..15ba4f17922cf0769b142fc568bef1485a7636ef 100644 (file)
@@ -300,6 +300,8 @@ typedef enum {
                                            was denied */
     VIR_ERR_DBUS_SERVICE = 89,          /* error from a dbus service */
     VIR_ERR_STORAGE_VOL_EXIST = 90,     /* the storage vol already exists */
+    VIR_ERR_CPU_INCOMPATIBLE = 91,      /* given CPU is incompatible with host
+                                           CPU*/
 } virErrorNumber;
 
 /**
index bb9bcb7916c614e6225cecfc35e83ff20d350256..9bece84c2c007aba91fb023f0f5b61dcd815f0b6 100644 (file)
@@ -1332,7 +1332,7 @@ bhyveConnectCompareCPU(virConnectPtr conn,
         VIR_WARN("cannot get host CPU capabilities");
         ret = VIR_CPU_COMPARE_INCOMPATIBLE;
     } else {
-        ret = cpuCompareXML(caps->host.cpu, xmlDesc);
+        ret = cpuCompareXML(caps->host.cpu, xmlDesc, false);
     }
 
  cleanup:
index c3d66dd374daf15fafb7e6af6d539b9673f4ba82..08bec5e56add00abc4edad96baf2ef94197cf1dc 100644 (file)
@@ -92,7 +92,8 @@ cpuGetSubDriver(virArch arch)
  */
 virCPUCompareResult
 cpuCompareXML(virCPUDefPtr host,
-              const char *xml)
+              const char *xml,
+              bool failIncompatible)
 {
     xmlDocPtr doc = NULL;
     xmlXPathContextPtr ctxt = NULL;
@@ -108,7 +109,7 @@ cpuCompareXML(virCPUDefPtr host,
     if (cpu == NULL)
         goto cleanup;
 
-    ret = cpuCompare(host, cpu);
+    ret = cpuCompare(host, cpu, failIncompatible);
 
  cleanup:
     virCPUDefFree(cpu);
@@ -134,7 +135,8 @@ cpuCompareXML(virCPUDefPtr host,
  */
 virCPUCompareResult
 cpuCompare(virCPUDefPtr host,
-           virCPUDefPtr cpu)
+           virCPUDefPtr cpu,
+           bool failIncompatible)
 {
     struct cpuArchDriver *driver;
 
@@ -156,7 +158,7 @@ cpuCompare(virCPUDefPtr host,
         return VIR_CPU_COMPARE_ERROR;
     }
 
-    return driver->compare(host, cpu);
+    return driver->compare(host, cpu, failIncompatible);
 }
 
 
index e9f271330b16f096c8c8684ac3bdb24484d29569..339964ce3ae4102996ec01cafb8c8f16cbf667a2 100644 (file)
@@ -46,7 +46,8 @@ struct _virCPUData {
 
 typedef virCPUCompareResult
 (*cpuArchCompare)   (virCPUDefPtr host,
-                     virCPUDefPtr cpu);
+                     virCPUDefPtr cpu,
+                     bool failIncompatible);
 
 typedef int
 (*cpuArchDecode)    (virCPUDefPtr cpu,
@@ -119,12 +120,14 @@ struct cpuArchDriver {
 
 extern virCPUCompareResult
 cpuCompareXML(virCPUDefPtr host,
-              const char *xml)
+              const char *xml,
+              bool failIncompatible)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
 extern virCPUCompareResult
 cpuCompare  (virCPUDefPtr host,
-             virCPUDefPtr cpu)
+             virCPUDefPtr cpu,
+             bool failIncompatible)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
 extern int
index 7255d9fdf638d516974dd429e44efa6e240ebf0e..6346f9bd5e5814fc258a237c31e2dc20c9ed71bf 100644 (file)
@@ -110,7 +110,8 @@ AArch64Baseline(virCPUDefPtr *cpus,
 
 static virCPUCompareResult
 AArch64Compare(virCPUDefPtr host ATTRIBUTE_UNUSED,
-               virCPUDefPtr cpu ATTRIBUTE_UNUSED)
+               virCPUDefPtr cpu ATTRIBUTE_UNUSED,
+               bool failIncompatible ATTRIBUTE_UNUSED)
 {
     return VIR_CPU_COMPARE_IDENTICAL;
 }
index 39e8f128938c0071f6b2e86ac304da8b515fe665..ec755bd157e56eaef6f9cf56da20d730a5319add 100644 (file)
@@ -113,7 +113,8 @@ ArmBaseline(virCPUDefPtr *cpus,
 
 static virCPUCompareResult
 ArmCompare(virCPUDefPtr host ATTRIBUTE_UNUSED,
-           virCPUDefPtr cpu ATTRIBUTE_UNUSED)
+           virCPUDefPtr cpu ATTRIBUTE_UNUSED,
+           bool failMessages ATTRIBUTE_UNUSED)
 {
     return VIR_CPU_COMPARE_IDENTICAL;
 }
index f115c40d3e981fdba5a72ada1171fad56ae02009..d6890c0be46a25144c1a22f33acdc2267099f09c 100644 (file)
@@ -57,17 +57,20 @@ genericHashFeatures(virCPUDefPtr cpu)
 
 static virCPUCompareResult
 genericCompare(virCPUDefPtr host,
-               virCPUDefPtr cpu)
+               virCPUDefPtr cpu,
+               bool failIncompatible)
 {
-    virHashTablePtr hash;
+    virHashTablePtr hash = NULL;
     virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;
     size_t i;
     unsigned int reqfeatures;
 
     if ((cpu->arch != VIR_ARCH_NONE &&
          host->arch != cpu->arch) ||
-        STRNEQ(host->model, cpu->model))
-        return VIR_CPU_COMPARE_INCOMPATIBLE;
+        STRNEQ(host->model, cpu->model)) {
+        ret = VIR_CPU_COMPARE_INCOMPATIBLE;
+        goto cleanup;
+    }
 
     if ((hash = genericHashFeatures(host)) == NULL)
         goto cleanup;
@@ -102,6 +105,10 @@ genericCompare(virCPUDefPtr host,
 
  cleanup:
     virHashFree(hash);
+    if (failIncompatible && ret == VIR_CPU_COMPARE_INCOMPATIBLE) {
+        ret = VIR_CPU_COMPARE_ERROR;
+        virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL);
+    }
     return ret;
 }
 
index 05fa55b88fbec39469386522bc505c452988316f..67cb9ff61ad5bc88a89fc525cb4784f3c742af30 100644 (file)
@@ -440,13 +440,19 @@ ppcCompute(virCPUDefPtr host,
 
 static virCPUCompareResult
 ppcCompare(virCPUDefPtr host,
-           virCPUDefPtr cpu)
+           virCPUDefPtr cpu,
+           bool failIncompatible)
 {
     if ((cpu->arch == VIR_ARCH_NONE || host->arch == cpu->arch) &&
         STREQ(host->model, cpu->model))
         return VIR_CPU_COMPARE_IDENTICAL;
 
-    return VIR_CPU_COMPARE_INCOMPATIBLE;
+    if (failIncompatible) {
+        virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL);
+        return VIR_CPU_COMPARE_ERROR;
+    } else {
+        return VIR_CPU_COMPARE_INCOMPATIBLE;
+    }
 }
 
 static int
index 72c5216f012dac09edbefdf5b194f1247ed3aff5..235fa49483bf80b25cf9e1e564c5b6457190d94d 100644 (file)
@@ -1463,9 +1463,25 @@ x86Compute(virCPUDefPtr host,
 
 static virCPUCompareResult
 x86Compare(virCPUDefPtr host,
-           virCPUDefPtr cpu)
+           virCPUDefPtr cpu,
+           bool failIncomaptible)
 {
-    return x86Compute(host, cpu, NULL, NULL);
+    virCPUCompareResult ret;
+    char *message = NULL;
+
+    ret = x86Compute(host, cpu, NULL, &message);
+
+    if (failIncomaptible && ret == VIR_CPU_COMPARE_INCOMPATIBLE) {
+        ret = VIR_CPU_COMPARE_ERROR;
+        if (message) {
+            virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s", message);
+        } else {
+            virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL);
+        }
+    }
+    VIR_FREE(message);
+
+    return ret;
 }
 
 
index 22699c10e8e3d497f8d276dbe62439832e5c4881..3c23fc7cf7763494e9ba378b0a59fef6342dbee5 100644 (file)
@@ -11528,7 +11528,7 @@ qemuConnectCompareCPU(virConnectPtr conn,
         VIR_WARN("cannot get host CPU capabilities");
         ret = VIR_CPU_COMPARE_INCOMPATIBLE;
     } else {
-        ret = cpuCompareXML(caps->host.cpu, xmlDesc);
+        ret = cpuCompareXML(caps->host.cpu, xmlDesc, false);
     }
 
  cleanup:
index e0bc970e3217d14d9c526d3a98003cccb38cf83b..6bd3d09cfdeb884ccb5a0c72b1f5f4cb9eb4c880 100644 (file)
@@ -1277,6 +1277,12 @@ virErrorMsg(virErrorNumber error, const char *info)
             else
                 errmsg = _("error from service: %s");
             break;
+        case VIR_ERR_CPU_INCOMPATIBLE:
+            if (info == NULL)
+                errmsg = _("the CPU is incompatible with host CPU");
+            else
+                errmsg = _("the CPU is incompatible with host CPU: %s");
+            break;
     }
     return errmsg;
 }
index 3766c2f2df43d9b554bf28ace241cd2c623e2f2f..38cd71e82154e723cfb1e4361e3c41412ef4e98a 100644 (file)
@@ -228,7 +228,7 @@ cpuTestCompare(const void *arg)
         !(cpu = cpuTestLoadXML(data->arch, data->name)))
         goto cleanup;
 
-    result = cpuCompare(host, cpu);
+    result = cpuCompare(host, cpu, false);
     if (data->result == VIR_CPU_COMPARE_ERROR)
         virResetLastError();
 
@@ -357,7 +357,7 @@ cpuTestBaseline(const void *arg)
     for (i = 0; i < ncpus; i++) {
         virCPUCompareResult cmp;
 
-        cmp = cpuCompare(cpus[i], baseline);
+        cmp = cpuCompare(cpus[i], baseline, false);
         if (cmp != VIR_CPU_COMPARE_SUPERSET &&
             cmp != VIR_CPU_COMPARE_IDENTICAL) {
             if (virTestGetVerbose()) {