[libvirt] [PATCH 2/4] cpu: push more parsing logic into common code
Jiri Denemark
jdenemar at redhat.com
Tue Aug 14 14:35:31 UTC 2018
On Wed, Aug 01, 2018 at 18:02:30 +0100, Daniel P. Berrangé wrote:
> The x86 and ppc impls both duplicate some logic when parsing CPU
> features. Change the callback signature so that this duplication can be
> pushed up a level to common code.
>
> Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
> ---
> src/cpu/cpu_map.c | 106 +++++++++++++++---------
> src/cpu/cpu_map.h | 22 ++---
> src/cpu/cpu_ppc64.c | 112 ++++++-------------------
> src/cpu/cpu_x86.c | 196 +++++++++++++-------------------------------
> 4 files changed, 155 insertions(+), 281 deletions(-)
>
> diff --git a/src/cpu/cpu_map.c b/src/cpu/cpu_map.c
> index 9e090919ed..17ed53fda6 100644
> --- a/src/cpu/cpu_map.c
> +++ b/src/cpu/cpu_map.c
> @@ -35,31 +35,51 @@
>
> VIR_LOG_INIT("cpu.cpu_map");
>
> -VIR_ENUM_IMPL(cpuMapElement, CPU_MAP_ELEMENT_LAST,
> - "vendor",
> - "feature",
> - "model")
> -
> -
> -static int load(xmlXPathContextPtr ctxt,
> - cpuMapElement element,
> - cpuMapLoadCallback callback,
> - void *data)
> +static int
> +loadData(const char *mapfile,
> + xmlXPathContextPtr ctxt,
> + const char *xpath,
Do you have any further plans with @xpath and actually pass something
more fancy than just an element name in it? If not, I'd suggest
renaming this parameter as "element" or something similar. Initially I
was confused what XPath expression you'd be passing to loadData and
whether including the expression in the error messages is a good idea.
> + cpuMapLoadCallback callback,
> + void *data)
> {
> int ret = -1;
> xmlNodePtr ctxt_node;
> xmlNodePtr *nodes = NULL;
> int n;
> + size_t i;
> + int rv;
>
> ctxt_node = ctxt->node;
>
> - n = virXPathNodeSet(cpuMapElementTypeToString(element), ctxt, &nodes);
> - if (n < 0)
> + n = virXPathNodeSet(xpath, ctxt, &nodes);
> + if (n < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("cannot find '%s' in CPU map '%s'"), xpath, mapfile);
virXPathNodeSet already reports an appropriate error message before
returning -1. Not to mention that the function would return 0 if the
element was not found (in which case you don't want to report error
anyway). Simply removing the call to virReportError will fix both
issues.
> goto cleanup;
> + }
>
> - if (n > 0 &&
> - callback(element, ctxt, nodes, n, data) < 0)
> + if (n > 0 && !callback) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Unexpected %s in CPU map '%s'"), xpath, mapfile);
> goto cleanup;
> + }
> +
> + for (i = 0; i < n; i++) {
> + xmlNodePtr old = ctxt->node;
> + char *name = virXMLPropString(nodes[i], "name");
> + if (!name) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("cannot find %s name in CPU map '%s'"), xpath, mapfile);
> + goto cleanup;
> + }
> + VIR_DEBUG("Load %s name %s", xpath, name);
> + ctxt->node = nodes[i];
> + rv = callback(ctxt, name, data);
> + ctxt->node = old;
> + VIR_FREE(name);
> + if (rv < 0)
> + goto cleanup;
> + }
>
> ret = 0;
>
> @@ -72,13 +92,14 @@ static int load(xmlXPathContextPtr ctxt,
>
> static int
> cpuMapLoadInclude(const char *filename,
> - cpuMapLoadCallback cb,
> + cpuMapLoadCallback vendorCB,
> + cpuMapLoadCallback featureCB,
> + cpuMapLoadCallback modelCB,
> void *data)
> {
> xmlDocPtr xml = NULL;
> xmlXPathContextPtr ctxt = NULL;
> int ret = -1;
> - int element;
> char *mapfile;
>
> if (!(mapfile = virFileFindResource(filename,
> @@ -93,13 +114,14 @@ cpuMapLoadInclude(const char *filename,
>
> 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;
> - }
> - }
> + if (loadData(mapfile, ctxt, "vendor", vendorCB, data) < 0)
> + goto cleanup;
> +
> + if (loadData(mapfile, ctxt, "feature", featureCB, data) < 0)
> + goto cleanup;
> +
> + if (loadData(mapfile, ctxt, "model", modelCB, data) < 0)
> + goto cleanup;
>
> ret = 0;
>
> @@ -113,7 +135,9 @@ cpuMapLoadInclude(const char *filename,
>
>
> static int loadIncludes(xmlXPathContextPtr ctxt,
> - cpuMapLoadCallback callback,
> + cpuMapLoadCallback vendorCB,
> + cpuMapLoadCallback featureCB,
> + cpuMapLoadCallback modelCB,
> void *data)
> {
> int ret = -1;
> @@ -131,7 +155,7 @@ static int loadIncludes(xmlXPathContextPtr ctxt,
> for (i = 0; i < n; i++) {
> char *filename = virXMLPropString(nodes[i], "filename");
> VIR_DEBUG("Finding CPU map include '%s'", filename);
> - if (cpuMapLoadInclude(filename, callback, data) < 0) {
> + if (cpuMapLoadInclude(filename, vendorCB, featureCB, modelCB, data) < 0) {
> VIR_FREE(filename);
> goto cleanup;
> }
> @@ -149,7 +173,9 @@ static int loadIncludes(xmlXPathContextPtr ctxt,
>
>
> int cpuMapLoad(const char *arch,
> - cpuMapLoadCallback cb,
> + cpuMapLoadCallback vendorCB,
> + cpuMapLoadCallback featureCB,
> + cpuMapLoadCallback modelCB,
> void *data)
> {
> xmlDocPtr xml = NULL;
> @@ -157,7 +183,6 @@ int cpuMapLoad(const char *arch,
> virBuffer buf = VIR_BUFFER_INITIALIZER;
> char *xpath = NULL;
> int ret = -1;
> - int element;
> char *mapfile;
>
> if (!(mapfile = virFileFindResource("cpu_map.xml",
> @@ -173,9 +198,15 @@ int cpuMapLoad(const char *arch,
> goto cleanup;
> }
>
> - if (cb == NULL) {
> + if (vendorCB == NULL) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + "%s", _("no vendor callback provided"));
> + goto cleanup;
> + }
> +
> + if (modelCB == NULL) {
> virReportError(VIR_ERR_INTERNAL_ERROR,
> - "%s", _("no callback provided"));
> + "%s", _("no model callback provided"));
> goto cleanup;
> }
I'd remove both checks as suggested by John.
...
Jirka
More information about the libvir-list
mailing list