[libvirt] [PATCH v2 1/9] Functions for computing baseline CPU from a set of host CPUs

Jiri Denemark jdenemar at redhat.com
Thu Feb 11 15:43:51 UTC 2010


Baseline CPU is the best CPU which can be used for a guest on any of the
hosts.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/cpu/cpu.c            |  123 +++++++++++++++++++++++++++++++++++++++++++++-
 src/cpu/cpu.h            |   21 ++++++++-
 src/cpu/cpu_generic.c    |    3 +-
 src/cpu/cpu_x86.c        |    3 +-
 src/libvirt_private.syms |    2 +
 5 files changed, 148 insertions(+), 4 deletions(-)

diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index e9ecc98..501a00c 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"
@@ -237,3 +238,123 @@ cpuGuestData(virCPUDefPtr host,
 
     return driver->guestData(host, guest, data);
 }
+
+
+char *
+cpuBaselineXML(const char **xmlCPUs,
+               unsigned int ncpus,
+               const char **models,
+               unsigned int nmodels)
+{
+    xmlDocPtr doc = NULL;
+    xmlXPathContextPtr ctxt = NULL;
+    virCPUDefPtr *cpus = NULL;
+    virCPUDefPtr cpu = NULL;
+    char *cpustr;
+    unsigned int i;
+
+    if (xmlCPUs == NULL && ncpus != 0) {
+        virCPUReportError(VIR_ERR_INTERNAL_ERROR,
+                "%s", _("nonzero ncpus doesn't match with NULL xmlCPUs"));
+        return NULL;
+    }
+
+    if (ncpus < 1) {
+        virCPUReportError(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(ctxt->node, ctxt, VIR_CPU_TYPE_HOST);
+        if (cpus[i] == NULL)
+            goto error;
+
+        xmlXPathFreeContext(ctxt);
+        xmlFreeDoc(doc);
+        ctxt = NULL;
+        doc = NULL;
+    }
+
+    if (!(cpu = cpuBaseline(cpus, ncpus, models, nmodels)))
+        goto error;
+
+    cpustr = virCPUDefFormat(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();
+error:
+    cpustr = NULL;
+    goto cleanup;
+}
+
+
+virCPUDefPtr
+cpuBaseline(virCPUDefPtr *cpus,
+            unsigned int ncpus,
+            const char **models,
+            unsigned int nmodels)
+{
+    struct cpuArchDriver *driver;
+    virCPUDefPtr cpu;
+
+    if (cpus == NULL && ncpus != 0) {
+        virCPUReportError(VIR_ERR_INTERNAL_ERROR,
+                "%s", _("nonzero ncpus doesn't match with NULL cpus"));
+        return NULL;
+    }
+
+    if (ncpus < 1) {
+        virCPUReportError(VIR_ERR_INVALID_ARG, "%s", _("No CPUs given"));
+        return NULL;
+    }
+
+    if (models == NULL && nmodels != 0) {
+        virCPUReportError(VIR_ERR_INTERNAL_ERROR,
+                "%s", _("nonzero nmodels doesn't match with NULL models"));
+        return NULL;
+    }
+
+    if ((driver = cpuGetSubDriver(cpus[0]->arch)) == NULL)
+        return NULL;
+
+    if (driver->baseline == NULL) {
+        virCPUReportError(VIR_ERR_NO_SUPPORT,
+                _("cannot compute baseline CPU of %s architecture"),
+                cpus[0]->arch);
+        return NULL;
+    }
+
+    if ((cpu = driver->baseline(cpus, ncpus, models, nmodels))) {
+        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 7ee0ce6..c8d961d 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)  (virCPUDefPtr *cpus,
+                     unsigned int ncpus,
+                     const char **models,
+                     unsigned int nmodels);
+
 
 struct cpuArchDriver {
     const char *name;
@@ -81,6 +87,7 @@ struct cpuArchDriver {
     cpuArchDataFree     free;
     cpuArchNodeData     nodeData;
     cpuArchGuestData    guestData;
+    cpuArchBaseline     baseline;
 };
 
 
@@ -119,4 +126,16 @@ cpuGuestData(virCPUDefPtr host,
              virCPUDefPtr guest,
              union cpuData **data);
 
+extern char *
+cpuBaselineXML(const char **xmlCPUs,
+               unsigned int ncpus,
+               const char **models,
+               unsigned int nmodels);
+
+extern virCPUDefPtr
+cpuBaseline (virCPUDefPtr *cpus,
+             unsigned int ncpus,
+             const char **models,
+             unsigned int nmodels);
+
 #endif /* __VIR_CPU_H__ */
diff --git a/src/cpu/cpu_generic.c b/src/cpu/cpu_generic.c
index 566fed0..eac314d 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 c6ed078..a6db86d 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




More information about the libvir-list mailing list