[PATCH 7/9] cpu: Introduce virCPUCompareUnusable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



As opposed to the existing virCPUCompare{,XML} this function does not
use CPU model definitions from CPU map. It relies on CPU model usability
info from a hypervisor with a list of blockers that make the selected
CPU model unusable. Explicitly requested features are checked against
the hypervisor's view of a host CPU.

Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx>
---
 src/cpu/cpu.c            | 73 ++++++++++++++++++++++++++++++++++++++++
 src/cpu/cpu.h            |  7 ++++
 src/libvirt_private.syms |  1 +
 3 files changed, 81 insertions(+)

diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 1734561215..2b0d641e78 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -167,6 +167,79 @@ virCPUCompare(virArch arch,
 }
 
 
+/** virCPUCompareUnusable:
+ * @arch: CPU architecture
+ * @host: host CPU reported by the hypervisor
+ * @cpu: CPU to be compared with @host
+ * @blockers: NULL terminated list of features blocking usability of the CPU model from @cpu
+ * @failIncompatible: return an error instead of VIR_CPU_COMPARE_INCOMPATIBLE
+ *
+ * Check if @cpu can be run on @host when we know model used by @cpu is
+ * considered unusable by the hypervisor because it requires some features
+ * that cannot be provided on the host (the list of them is passed as
+ * @blockers) and/or @cpu requests additional features. The @cpu definition
+ * can still be compatible with @host if all @blockers are explicitly disabled
+ * and all explicitly requested features are supported by @host.
+ *
+ * Returns VIR_CPU_COMPARE_ERROR on error, VIR_CPU_COMPARE_INCOMPATIBLE when
+ * the @cpu cannot be created on @host, or VIR_CPU_COMPARE_SUPERSET when the
+ * @cpu is compatible with @host CPU. If @failIncompatible is true, the
+ * function will return VIR_CPU_COMPARE_ERROR (and set VIR_ERR_CPU_INCOMPATIBLE
+ * error) when the two CPUs are incompatible.
+ */
+int
+virCPUCompareUnusable(virArch arch,
+                      const virCPUDef *host,
+                      const virCPUDef *cpu,
+                      char **blockers,
+                      bool failIncompatible)
+{
+    g_autoptr(virCPUDef) expanded = NULL;
+    g_auto(virBuffer) features = VIR_BUFFER_INITIALIZER;
+    g_autofree char *str = NULL;
+    virCPUFeatureDef *feat;
+    char **blocker;
+    size_t i;
+
+    for (blocker = blockers; *blocker; blocker++) {
+        if (!(feat = virCPUDefFindFeature(cpu, *blocker)) ||
+            feat->policy != VIR_CPU_FEATURE_DISABLE) {
+            virBufferAddStr(&features, *blocker);
+            virBufferAddLit(&features, ", ");
+        }
+    }
+
+    expanded = virCPUDefCopy(host);
+    if (virCPUExpandFeatures(arch, expanded) < 0)
+        return VIR_CPU_COMPARE_ERROR;
+
+    for (i = 0; i < cpu->nfeatures; i++) {
+        if (cpu->features[i].policy != VIR_CPU_FEATURE_REQUIRE)
+            continue;
+
+        if (!(feat = virCPUDefFindFeature(expanded, cpu->features[i].name)) ||
+            feat->policy != VIR_CPU_FEATURE_REQUIRE) {
+            virBufferAddStr(&features, cpu->features[i].name);
+            virBufferAddLit(&features, ", ");
+        }
+    }
+    virBufferTrim(&features, ", ");
+
+    if ((str = virBufferContentAndReset(&features))) {
+        if (failIncompatible) {
+            virReportError(VIR_ERR_CPU_INCOMPATIBLE,
+                           _("Host CPU does not provide required features: %1$s"),
+                           str);
+            return VIR_CPU_COMPARE_ERROR;
+        }
+
+        return VIR_CPU_COMPARE_INCOMPATIBLE;
+    }
+
+    return VIR_CPU_COMPARE_SUPERSET;
+}
+
+
 /**
  * cpuDecode:
  *
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index ceb6eb0944..ff68c5da2d 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -185,6 +185,13 @@ virCPUCompare(virArch arch,
               bool failIncompatible)
     ATTRIBUTE_NONNULL(3);
 
+int
+virCPUCompareUnusable(virArch arch,
+                      const virCPUDef *host,
+                      const virCPUDef *cpu,
+                      char **blockers,
+                      bool failIncompatible);
+
 int
 cpuDecode   (virCPUDef *cpu,
              const virCPUData *data,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 551cea989b..c1542847f4 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1524,6 +1524,7 @@ virCPUBaseline;
 virCPUCheckFeature;
 virCPUCheckForbiddenFeatures;
 virCPUCompare;
+virCPUCompareUnusable;
 virCPUCompareXML;
 virCPUConvertLegacy;
 virCPUCopyMigratable;
-- 
2.47.0




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux