From 6438640b53fef3e889c21a2ed016638b91c5ac80 Mon Sep 17 00:00:00 2001 Message-Id: <6438640b53fef3e889c21a2ed016638b91c5ac80@dist-git> From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Fri, 21 Jun 2019 09:24:44 +0200 Subject: [PATCH] cpu: allow include files for CPU definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow for syntax to reference other files in the CPU database directory Reviewed-by: Jiri Denemark Signed-off-by: Daniel P. Berrangé (cherry picked from commit eda5f575f2a7530fc7f6471f88496778a9bc9fcb) https://bugzilla.redhat.com/show_bug.cgi?id=1686895 Signed-off-by: Jiri Denemark Message-Id: <800e5ebbc30502fd780a3ef84fe524f1dc0ffd67.1561068591.git.jdenemar@redhat.com> Reviewed-by: Ján Tomko --- src/cpu/cpu_map.c | 92 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu_map.c b/src/cpu/cpu_map.c index d263eb8cdd..333c7ef24f 100644 --- a/src/cpu/cpu_map.c +++ b/src/cpu/cpu_map.c @@ -1,7 +1,7 @@ /* * cpu_map.c: internal functions for handling CPU mapping configuration * - * Copyright (C) 2009-2010 Red Hat, Inc. + * Copyright (C) 2009-2018 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -70,6 +70,89 @@ static int load(xmlXPathContextPtr ctxt, return ret; } +static int +cpuMapLoadInclude(const char *filename, + cpuMapLoadCallback cb, + void *data) +{ + xmlDocPtr xml = NULL; + xmlXPathContextPtr ctxt = NULL; + int ret = -1; + int element; + char *mapfile; + + if (!(mapfile = virFileFindResource(filename, + abs_topsrcdir "/src/cpu", + PKGDATADIR))) + return -1; + + VIR_DEBUG("Loading CPU map include from %s", mapfile); + + if (!(xml = virXMLParseFileCtxt(mapfile, &ctxt))) + goto cleanup; + + ctxt->node = xmlDocGetRootElement(xml); + + for (element = 0; element < CPU_MAP_ELEMENT_LAST; element++) { + if (load(ctxt, element, cb, data) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot parse CPU map '%s'"), mapfile); + goto cleanup; + } + } + + ret = 0; + + cleanup: + xmlXPathFreeContext(ctxt); + xmlFreeDoc(xml); + VIR_FREE(mapfile); + + return ret; +} + + +static int +loadIncludes(xmlXPathContextPtr ctxt, + cpuMapLoadCallback callback, + void *data) +{ + int ret = -1; + xmlNodePtr ctxt_node; + xmlNodePtr *nodes = NULL; + int n; + size_t i; + + ctxt_node = ctxt->node; + + n = virXPathNodeSet("include", ctxt, &nodes); + if (n < 0) + goto cleanup; + + for (i = 0; i < n; i++) { + char *filename = virXMLPropString(nodes[i], "filename"); + if (!filename) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Missing 'filename' in CPU map include")); + goto cleanup; + } + VIR_DEBUG("Finding CPU map include '%s'", filename); + if (cpuMapLoadInclude(filename, callback, data) < 0) { + VIR_FREE(filename); + goto cleanup; + } + VIR_FREE(filename); + } + + ret = 0; + + cleanup: + ctxt->node = ctxt_node; + VIR_FREE(nodes); + + return ret; +} + int cpuMapLoad(const char *arch, cpuMapLoadCallback cb, @@ -88,7 +171,7 @@ int cpuMapLoad(const char *arch, PKGDATADIR))) return -1; - VIR_DEBUG("Loading CPU map from %s", mapfile); + VIR_DEBUG("Loading '%s' CPU map from %s", NULLSTR(arch), mapfile); if (arch == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -122,11 +205,14 @@ int cpuMapLoad(const char *arch, for (element = 0; element < CPU_MAP_ELEMENT_LAST; element++) { if (load(ctxt, element, cb, data) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot parse CPU map for %s architecture"), arch); + _("cannot parse CPU map '%s'"), mapfile); goto cleanup; } } + if (loadIncludes(ctxt, cb, data) < 0) + goto cleanup; + ret = 0; cleanup: -- 2.22.0