]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
cpu: Wire in XML validation
authorTim Wiederhake <twiederh@redhat.com>
Wed, 7 Oct 2020 08:54:55 +0000 (10:54 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Wed, 7 Oct 2020 09:26:27 +0000 (11:26 +0200)
This adds a new value to virConnectCompareCPUFlags,
"VIR_CONNECT_CPU_VALIDATE_XML", that governs XML document validation in
virCPUDefParseXML.

In src/conf/cpu_conf.c, include configmake.h for PKGDATADIR and
virfile.h for virFileFindResource.

Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
12 files changed:
include/libvirt/libvirt-host.h
src/bhyve/bhyve_driver.c
src/conf/cpu_conf.c
src/conf/cpu_conf.h
src/conf/domain_conf.c
src/cpu/cpu.c
src/cpu/cpu.h
src/libxl/libxl_driver.c
src/qemu/qemu_domain.c
src/qemu/qemu_driver.c
src/qemu/qemu_migration_cookie.c
tests/cputest.c

index 6972834175c2252280963c0bcc147097947542a8..4caed94a77d027c0044923fdc90548bfba723ad2 100644 (file)
@@ -754,6 +754,8 @@ typedef enum {
 typedef enum {
     VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE = (1 << 0), /* treat incompatible
                                                              CPUs as failure */
+    VIR_CONNECT_COMPARE_CPU_VALIDATE_XML = (1 << 1), /* validate the xml
+                                                        document */
 } virConnectCompareCPUFlags;
 
 int virConnectCompareCPU(virConnectPtr conn,
index 91f41aa238d045f5bca216c814f5c627b907a18c..78c3241293638b3ec5af2f3e00b3fb1d08121e37 100644 (file)
@@ -1441,14 +1441,17 @@ bhyveConnectCompareCPU(virConnectPtr conn,
     int ret = VIR_CPU_COMPARE_ERROR;
     virCapsPtr caps = NULL;
     bool failIncompatible;
+    bool validateXML;
 
-    virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE,
+    virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE |
+                  VIR_CONNECT_COMPARE_CPU_VALIDATE_XML,
                   VIR_CPU_COMPARE_ERROR);
 
     if (virConnectCompareCPUEnsureACL(conn) < 0)
         goto cleanup;
 
     failIncompatible = !!(flags & VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE);
+    validateXML = !!(flags & VIR_CONNECT_COMPARE_CPU_VALIDATE_XML);
 
     if (!(caps = bhyveDriverGetCapabilities(driver)))
         goto cleanup;
@@ -1464,7 +1467,7 @@ bhyveConnectCompareCPU(virConnectPtr conn,
         }
     } else {
         ret = virCPUCompareXML(caps->host.arch, caps->host.cpu,
-                               xmlDesc, failIncompatible);
+                               xmlDesc, failIncompatible, validateXML);
     }
 
  cleanup:
index dea950ce689380f93be5f29a561f84022287fc55..1910470836aa455a89264d66c063b0e30102da89 100644 (file)
 
 #include <config.h>
 
+#include "configmake.h"
 #include "virerror.h"
 #include "viralloc.h"
 #include "virbuffer.h"
+#include "virfile.h"
 #include "cpu_conf.h"
 #include "domain_conf.h"
 #include "virstring.h"
@@ -281,7 +283,8 @@ virCPUDefCopy(const virCPUDef *cpu)
 int
 virCPUDefParseXMLString(const char *xml,
                         virCPUType type,
-                        virCPUDefPtr *cpu)
+                        virCPUDefPtr *cpu,
+                        bool validateXML)
 {
     xmlDocPtr doc = NULL;
     xmlXPathContextPtr ctxt = NULL;
@@ -295,7 +298,7 @@ virCPUDefParseXMLString(const char *xml,
     if (!(doc = virXMLParseStringCtxt(xml, _("(CPU_definition)"), &ctxt)))
         goto cleanup;
 
-    if (virCPUDefParseXML(ctxt, NULL, type, cpu) < 0)
+    if (virCPUDefParseXML(ctxt, NULL, type, cpu, validateXML) < 0)
         goto cleanup;
 
     ret = 0;
@@ -323,7 +326,8 @@ int
 virCPUDefParseXML(xmlXPathContextPtr ctxt,
                   const char *xpath,
                   virCPUType type,
-                  virCPUDefPtr *cpu)
+                  virCPUDefPtr *cpu,
+                  bool validateXML)
 {
     g_autoptr(virCPUDef) def = NULL;
     g_autofree xmlNodePtr *nodes = NULL;
@@ -348,6 +352,19 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
         return -1;
     }
 
+    if (validateXML) {
+        g_autofree char *schemafile = NULL;
+
+        if (!(schemafile = virFileFindResource("cpu.rng",
+                                               abs_top_srcdir "/docs/schemas",
+                                               PKGDATADIR "/schemas")))
+            return -1;
+
+        if (virXMLValidateNodeAgainstSchema(schemafile, ctxt->doc,
+                                            ctxt->node) < 0)
+            return -1;
+    }
+
     def = virCPUDefNew();
 
     if (type == VIR_CPU_TYPE_AUTO) {
@@ -1146,7 +1163,7 @@ virCPUDefListParse(const char **xmlCPUs,
         if (!(doc = virXMLParseStringCtxt(xmlCPUs[i], _("(CPU_definition)"), &ctxt)))
             goto error;
 
-        if (virCPUDefParseXML(ctxt, NULL, cpuType, &cpus[i]) < 0)
+        if (virCPUDefParseXML(ctxt, NULL, cpuType, &cpus[i], false) < 0)
             goto error;
 
         xmlXPathFreeContext(ctxt);
index 24c51e3a639cdd1c685a48556da2e5c82f06ef84..3ef14b7932e7d7ee264d917c13d17cb74c8d72c7 100644 (file)
@@ -192,13 +192,15 @@ virCPUDefCopyWithoutModel(const virCPUDef *cpu);
 int
 virCPUDefParseXMLString(const char *xml,
                         virCPUType type,
-                        virCPUDefPtr *cpu);
+                        virCPUDefPtr *cpu,
+                        bool validateXML);
 
 int
 virCPUDefParseXML(xmlXPathContextPtr ctxt,
                   const char *xpath,
                   virCPUType mode,
-                  virCPUDefPtr *cpu);
+                  virCPUDefPtr *cpu,
+                  bool validateXML);
 
 bool
 virCPUDefIsEqual(virCPUDefPtr src,
index 175b632a388617d641a2d6a355cbbc3d9bf74374..c003b5c0305d75a37f5ad28bffeb1f847f58f6e6 100644 (file)
@@ -21917,7 +21917,8 @@ virDomainDefParseXML(xmlDocPtr xml,
     if (virDomainDefTunablesParse(def, ctxt, xmlopt, flags) < 0)
         goto error;
 
-    if (virCPUDefParseXML(ctxt, "./cpu[1]", VIR_CPU_TYPE_GUEST, &def->cpu) < 0)
+    if (virCPUDefParseXML(ctxt, "./cpu[1]", VIR_CPU_TYPE_GUEST, &def->cpu,
+                          false) < 0)
         goto error;
 
     if (virDomainNumaDefParseXML(def->numa, ctxt) < 0)
index 188c5d86b59612e28e6c0f06ee9cc6389f6e24c0..bf948119604c0f0653e68338a11c435863b6ec16 100644 (file)
@@ -109,14 +109,15 @@ virCPUCompareResult
 virCPUCompareXML(virArch arch,
                  virCPUDefPtr host,
                  const char *xml,
-                 bool failIncompatible)
+                 bool failIncompatible,
+                 bool validateXML)
 {
     g_autoptr(virCPUDef) cpu = NULL;
 
     VIR_DEBUG("arch=%s, host=%p, xml=%s",
               virArchToString(arch), host, NULLSTR(xml));
 
-    if (virCPUDefParseXMLString(xml, VIR_CPU_TYPE_AUTO, &cpu) < 0)
+    if (virCPUDefParseXMLString(xml, VIR_CPU_TYPE_AUTO, &cpu, validateXML) < 0)
         return VIR_CPU_COMPARE_ERROR;
 
     return virCPUCompare(arch, host, cpu, failIncompatible);
index ba8fdd07bab3ce45bd20fc81b7bf70d37264bc04..cc2d132275c4a10a2ad2a148e5562d0fce68aea0 100644 (file)
@@ -153,7 +153,8 @@ virCPUCompareResult
 virCPUCompareXML(virArch arch,
                  virCPUDefPtr host,
                  const char *xml,
-                 bool failIncompatible);
+                 bool failIncompatible,
+                 bool validateXML);
 
 virCPUCompareResult
 virCPUCompare(virArch arch,
index e28c64968899dcf2cfa74fa29395e432206e9652..824ed60dfd984e8a2bb0a70fee66e6da6fd95a5b 100644 (file)
@@ -6529,19 +6529,22 @@ libxlConnectCompareCPU(virConnectPtr conn,
     libxlDriverConfigPtr cfg;
     int ret = VIR_CPU_COMPARE_ERROR;
     bool failIncompatible;
+    bool validateXML;
 
-    virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE,
+    virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE |
+                  VIR_CONNECT_COMPARE_CPU_VALIDATE_XML,
                   VIR_CPU_COMPARE_ERROR);
 
     if (virConnectCompareCPUEnsureACL(conn) < 0)
         return ret;
 
     failIncompatible = !!(flags & VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE);
+    validateXML = !!(flags & VIR_CONNECT_COMPARE_CPU_VALIDATE_XML);
 
     cfg = libxlDriverConfigGet(driver);
 
     ret = virCPUCompareXML(cfg->caps->host.arch, cfg->caps->host.cpu,
-                           xmlDesc, failIncompatible);
+                           xmlDesc, failIncompatible, validateXML);
 
     virObjectUnref(cfg);
     return ret;
index 0687f4584ce47a2116a118036b2a66c8584cef35..9623123d3ce1e731ddfeb81d363e6c4ca12a0ffa 100644 (file)
@@ -3130,7 +3130,8 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
 
     qemuDomainSetPrivatePathsOld(driver, vm);
 
-    if (virCPUDefParseXML(ctxt, "./cpu", VIR_CPU_TYPE_GUEST, &priv->origCPU) < 0)
+    if (virCPUDefParseXML(ctxt, "./cpu", VIR_CPU_TYPE_GUEST, &priv->origCPU,
+                          false) < 0)
         goto error;
 
     priv->chardevStdioLogd = virXPathBoolean("boolean(./chardevStdioLogd)",
@@ -9997,7 +9998,7 @@ qemuDomainSaveCookieParse(xmlXPathContextPtr ctxt G_GNUC_UNUSED,
         return -1;
 
     if (virCPUDefParseXML(ctxt, "./cpu[1]", VIR_CPU_TYPE_GUEST,
-                          &cookie->cpu) < 0)
+                          &cookie->cpu, false) < 0)
         return -1;
 
     cookie->slirpHelper = virXPathBoolean("boolean(./slirpHelper)", ctxt) > 0;
index 5aaa969409cc62e738af6ed457c5ca4a14bdb9f0..8ef812cd94826f817bc40d84634e27819e45d251 100644 (file)
@@ -12202,20 +12202,23 @@ qemuConnectCompareCPU(virConnectPtr conn,
     virQEMUDriverPtr driver = conn->privateData;
     g_autoptr(virCPUDef) cpu = NULL;
     bool failIncompatible;
+    bool validateXML;
 
-    virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE,
+    virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE |
+                  VIR_CONNECT_COMPARE_CPU_VALIDATE_XML,
                   VIR_CPU_COMPARE_ERROR);
 
     if (virConnectCompareCPUEnsureACL(conn) < 0)
         return VIR_CPU_COMPARE_ERROR;
 
     failIncompatible = !!(flags & VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE);
+    validateXML = !!(flags & VIR_CONNECT_COMPARE_CPU_VALIDATE_XML);
 
     if (!(cpu = virQEMUDriverGetHostCPU(driver)))
         return VIR_CPU_COMPARE_ERROR;
 
     return virCPUCompareXML(driver->hostarch, cpu,
-                            xmlDesc, failIncompatible);
+                            xmlDesc, failIncompatible, validateXML);
 }
 
 
@@ -12270,18 +12273,21 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn,
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
     g_autoptr(virQEMUCaps) qemuCaps = NULL;
     bool failIncompatible;
+    bool validateXML;
     virCPUDefPtr hvCPU;
     virCPUDefPtr cpu = NULL;
     virArch arch;
     virDomainVirtType virttype;
 
-    virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE,
+    virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE |
+                  VIR_CONNECT_COMPARE_CPU_VALIDATE_XML,
                   VIR_CPU_COMPARE_ERROR);
 
     if (virConnectCompareHypervisorCPUEnsureACL(conn) < 0)
         goto cleanup;
 
     failIncompatible = !!(flags & VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE);
+    validateXML = !!(flags & VIR_CONNECT_COMPARE_CPU_VALIDATE_XML);
 
     qemuCaps = virQEMUCapsCacheLookupDefault(driver->qemuCapsCache,
                                              emulator,
@@ -12305,10 +12311,12 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn,
     }
 
     if (ARCH_IS_X86(arch)) {
-        ret = virCPUCompareXML(arch, hvCPU, xmlCPU, failIncompatible);
+        ret = virCPUCompareXML(arch, hvCPU, xmlCPU, failIncompatible,
+                               validateXML);
     } else if (ARCH_IS_S390(arch) &&
                virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_COMPARISON)) {
-        if (virCPUDefParseXMLString(xmlCPU, VIR_CPU_TYPE_AUTO, &cpu) < 0)
+        if (virCPUDefParseXMLString(xmlCPU, VIR_CPU_TYPE_AUTO, &cpu,
+                                    validateXML) < 0)
             goto cleanup;
 
         if (!cpu->model) {
index 91694000d8796088a25f2f9eaddd09ee623dd1c1..abe797759dea5056b1dc585896a289eb458dada5 100644 (file)
@@ -1263,7 +1263,8 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
         return -1;
 
     if (flags & QEMU_MIGRATION_COOKIE_CPU &&
-        virCPUDefParseXML(ctxt, "./cpu[1]", VIR_CPU_TYPE_GUEST, &mig->cpu) < 0)
+        virCPUDefParseXML(ctxt, "./cpu[1]", VIR_CPU_TYPE_GUEST, &mig->cpu,
+                          false) < 0)
         return -1;
 
     if (flags & QEMU_MIGRATION_COOKIE_ALLOW_REBOOT &&
index 383da949387e05363dbf01bda49b145a5bc1673d..78a7f2437af809777e8f644ff1fa922d6a9cdded 100644 (file)
@@ -81,7 +81,7 @@ cpuTestLoadXML(virArch arch, const char *name)
     if (!(doc = virXMLParseFileCtxt(xml, &ctxt)))
         goto cleanup;
 
-    virCPUDefParseXML(ctxt, NULL, VIR_CPU_TYPE_AUTO, &cpu);
+    virCPUDefParseXML(ctxt, NULL, VIR_CPU_TYPE_AUTO, &cpu, false);
 
  cleanup:
     xmlXPathFreeContext(ctxt);
@@ -120,7 +120,8 @@ cpuTestLoadMultiXML(virArch arch,
 
     for (i = 0; i < n; i++) {
         ctxt->node = nodes[i];
-        if (virCPUDefParseXML(ctxt, NULL, VIR_CPU_TYPE_HOST, &cpus[i]) < 0)
+        if (virCPUDefParseXML(ctxt, NULL, VIR_CPU_TYPE_HOST, &cpus[i],
+                              false) < 0)
             goto cleanup_cpus;
     }