Baseline CPU is the best CPU which can be used for a guest on any of the hosts. Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> --- src/cpu/cpu.c | 125 +++++++++++++++++++++++++++++++++++++++++++++- src/cpu/cpu.h | 23 ++++++++- src/cpu/cpu_generic.c | 3 +- src/cpu/cpu_x86.c | 3 +- src/libvirt_private.syms | 2 + 5 files changed, 152 insertions(+), 4 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 3e46948..1438d13 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1,7 +1,7 @@ /* * cpu.c: internal functions for CPU manipulation * - * Copyright (C) 2009 Red Hat, Inc. + * Copyright (C) 2009--2010 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 @@ -23,6 +23,7 @@ #include <config.h> +#include "memory.h" #include "xml.h" #include "cpu.h" #include "cpu_x86.h" @@ -245,3 +246,125 @@ cpuGuestData(virConnectPtr conn, return driver->guestData(host, guest, data); } + + +char * +cpuBaselineXML(virConnectPtr conn, + unsigned int ncpus, + const char **xmlCPUs, + unsigned int nmodels, + const char **models) +{ + xmlDocPtr doc = NULL; + xmlXPathContextPtr ctxt = NULL; + virCPUDefPtr *cpus = NULL; + virCPUDefPtr cpu; + char *cpustr; + unsigned int i; + + if (xmlCPUs == NULL && ncpus != 0) { + virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("nonzero ncpus doesn't match with NULL xmlCPUs")); + return NULL; + } + + if (ncpus < 1) { + virCPUReportError(conn, VIR_ERR_INVALID_ARG, "%s", _("No CPUs given")); + return NULL; + } + + if (VIR_ALLOC_N(cpus, ncpus)) + goto no_memory; + + for (i = 0; i < ncpus; i++) { + doc = xmlParseMemory(xmlCPUs[i], strlen(xmlCPUs[i])); + if (doc == NULL || (ctxt = xmlXPathNewContext(doc)) == NULL) + goto no_memory; + + ctxt->node = xmlDocGetRootElement(doc); + + cpus[i] = virCPUDefParseXML(conn, ctxt->node, ctxt, VIR_CPU_TYPE_HOST); + if (cpus[i] == NULL) + goto error; + + xmlXPathFreeContext(ctxt); + xmlFreeDoc(doc); + ctxt = NULL; + doc = NULL; + } + + if (!(cpu = cpuBaseline(conn, ncpus, cpus, nmodels, models))) + goto error; + + cpustr = virCPUDefFormat(conn, cpu, "", 0); + +cleanup: + if (cpus) { + for (i = 0; i < ncpus; i++) + virCPUDefFree(cpus[i]); + VIR_FREE(cpus); + } + virCPUDefFree(cpu); + xmlXPathFreeContext(ctxt); + xmlFreeDoc(doc); + + return cpustr; + +no_memory: + virReportOOMError(conn); +error: + cpustr = NULL; + goto cleanup; +} + + +virCPUDefPtr +cpuBaseline(virConnectPtr conn, + unsigned int ncpus, + virCPUDefPtr *cpus, + unsigned int nmodels, + const char **models) +{ + struct cpuArchDriver *driver; + virCPUDefPtr cpu; + + if (cpus == NULL && ncpus != 0) { + virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("nonzero ncpus doesn't match with NULL cpus")); + return NULL; + } + + if (ncpus < 1) { + virCPUReportError(conn, VIR_ERR_INVALID_ARG, "%s", _("No CPUs given")); + return NULL; + } + + if (models == NULL && nmodels != 0) { + virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("nonzero nmodels doesn't match with NULL models")); + return NULL; + } + + if ((driver = cpuGetSubDriver(conn, cpus[0]->arch)) == NULL) + return NULL; + + if (driver->baseline == NULL) { + virCPUReportError(conn, VIR_ERR_NO_SUPPORT, + _("cannot compute baseline CPU of %s architecture"), + cpus[0]->arch); + return NULL; + } + + if ((cpu = driver->baseline(ncpus, cpus, nmodels, models))) { + int i; + + cpu->type = VIR_CPU_TYPE_GUEST; + cpu->match = VIR_CPU_MATCH_EXACT; + VIR_FREE(cpu->arch); + + for (i = 0; i < cpu->nfeatures; i++) + cpu->features[i].policy = VIR_CPU_FEATURE_REQUIRE; + } + + return cpu; +} diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 5b1636d..a51fac8 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -1,7 +1,7 @@ /* * cpu.h: internal functions for CPU manipulation * - * Copyright (C) 2009 Red Hat, Inc. + * Copyright (C) 2009--2010 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,12 @@ typedef virCPUCompareResult virCPUDefPtr guest, union cpuData **data); +typedef virCPUDefPtr +(*cpuArchBaseline) (unsigned int ncpus, + virCPUDefPtr *cpus, + unsigned int nmodels, + const char **models); + struct cpuArchDriver { const char *name; @@ -81,6 +87,7 @@ struct cpuArchDriver { cpuArchDataFree free; cpuArchNodeData nodeData; cpuArchGuestData guestData; + cpuArchBaseline baseline; }; @@ -126,4 +133,18 @@ cpuGuestData(virConnectPtr conn, virCPUDefPtr guest, union cpuData **data); +extern char * +cpuBaselineXML(virConnectPtr conn, + unsigned int ncpus, + const char **xmlCPUs, + unsigned int nmodels, + const char **models); + +extern virCPUDefPtr +cpuBaseline (virConnectPtr conn, + unsigned int ncpus, + virCPUDefPtr *cpus, + unsigned int nmodels, + const char **models); + #endif /* __VIR_CPU_H__ */ diff --git a/src/cpu/cpu_generic.c b/src/cpu/cpu_generic.c index b18c1b4..16bc4b0 100644 --- a/src/cpu/cpu_generic.c +++ b/src/cpu/cpu_generic.c @@ -118,5 +118,6 @@ struct cpuArchDriver cpuDriverGeneric = { .encode = NULL, .free = NULL, .nodeData = NULL, - .guestData = NULL + .guestData = NULL, + .baseline = NULL, }; diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index ce55588..f316db1 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -1205,5 +1205,6 @@ struct cpuArchDriver cpuDriverX86 = { #else .nodeData = NULL, #endif - .guestData = x86GuestData + .guestData = x86GuestData, + .baseline = NULL, }; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 7573af3..aa826d6 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -72,6 +72,8 @@ virCgroupSetFreezerState; # cpu.h +cpuBaseline; +cpuBaselineXML; cpuCompare; cpuCompareXML; cpuDataFree; -- 1.6.6.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list