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

Jiri Denemark jdenemar at redhat.com
Fri Feb 5 15:56:50 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            |  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




More information about the libvir-list mailing list