cpu: Wire in XML validation

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>
This commit is contained in:
Tim Wiederhake 2020-10-07 10:54:55 +02:00 committed by Peter Krempa
parent 9faa31ce79
commit 4c3ed3b84e
12 changed files with 65 additions and 24 deletions

View 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,

View 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:

View File

@ -20,9 +20,11 @@
#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);

View 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,

View 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)

View 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);

View File

@ -153,7 +153,8 @@ virCPUCompareResult
virCPUCompareXML(virArch arch,
virCPUDefPtr host,
const char *xml,
bool failIncompatible);
bool failIncompatible,
bool validateXML);
virCPUCompareResult
virCPUCompare(virArch arch,

View 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;

View 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;

View 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) {

View 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 &&

View 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;
}