[libvirt] [PATCH v2 1/5] cpu_models: add new public API

Giuseppe Scrivano gscrivan at redhat.com
Fri Sep 6 23:11:22 UTC 2013


The new function virConnectGetCPUModelNames allows to retrieve the list
of CPU models known by the hypervisor for a specific architecture.

Signed-off-by: Giuseppe Scrivano <gscrivan at redhat.com>
---
 include/libvirt/libvirt.h.in | 18 +++++++++++++
 python/generator.py          |  1 +
 src/cpu/cpu.c                | 64 ++++++++++++++++++++++++++++++++++++++++++++
 src/cpu/cpu.h                |  3 +++
 src/driver.h                 |  7 +++++
 src/libvirt.c                | 47 ++++++++++++++++++++++++++++++++
 src/libvirt_private.syms     |  1 +
 src/libvirt_public.syms      |  5 ++++
 tools/virsh-host.c           | 48 +++++++++++++++++++++++++++++++++
 tools/virsh.pod              |  5 ++++
 10 files changed, 199 insertions(+)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index a47e33c..43fb738 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -4006,6 +4006,24 @@ int virConnectCompareCPU(virConnectPtr conn,
                          const char *xmlDesc,
                          unsigned int flags);
 
+/**
+ * virConnectGetCPUModelNames:
+ *
+ * @conn: virConnect connection
+ * @arch: Architecture
+ * @models: NULL terminated array of the CPU models supported for the specified
+ * architecture.  Each element and the array itself must be freed by the caller
+ * with free.
+ * @flags: extra flags; not used yet, so callers should always pass 0.
+ *
+ * Get the list of supported CPU models for a specific architecture.
+ *
+ * Returns -1 on error, 0 on success.
+ */
+int virConnectGetCPUModelNames(virConnectPtr conn,
+                               const char *arch,
+                               char ***models,
+                               unsigned int flags);
 
 /**
  * virConnectBaselineCPUFlags
diff --git a/python/generator.py b/python/generator.py
index fb321c6..0301403 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -366,6 +366,7 @@ foreign_encoding_args = (
 # Class methods which are written by hand in libvirt.c but the Python-level
 # code is still automatically generated (so they are not in skip_function()).
 skip_impl = (
+    "virConnectGetCPUModelNames",
     'virConnectGetVersion',
     'virConnectGetLibVersion',
     'virConnectListDomainsID',
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 50c2de3..854c272 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -27,6 +27,7 @@
 #include "viralloc.h"
 #include "virxml.h"
 #include "cpu.h"
+#include "cpu_map.h"
 #include "cpu_x86.h"
 #include "cpu_powerpc.h"
 #include "cpu_s390.h"
@@ -456,3 +457,66 @@ cpuModelIsAllowed(const char *model,
     }
     return false;
 }
+
+struct cpuGetModelsData
+{
+    char **data;
+    size_t len;  /* It includes the last element of DATA, which is NULL. */
+};
+
+static int
+cpuGetArchModelsCb(enum cpuMapElement element,
+                   xmlXPathContextPtr ctxt,
+                   void *cbdata)
+{
+    char *name;
+    struct cpuGetModelsData *data = cbdata;
+    if (element != CPU_MAP_ELEMENT_MODEL)
+        return 0;
+
+    name = virXPathString("string(@name)", ctxt);
+    if (name == NULL)
+        return -1;
+
+    if (VIR_EXPAND_N(data->data, data->len, 1) < 0)
+        return -1;
+
+    data->data[data->len - 2] = name;
+    data->data[data->len - 1] = NULL;
+    return 0;
+}
+
+
+static int
+cpuGetArchModels(const char *arch, struct cpuGetModelsData *data)
+{
+    return cpuMapLoad(arch, cpuGetArchModelsCb, data);
+}
+
+
+int
+cpuGetModels(const char *arch, char ***models)
+{
+    struct cpuGetModelsData data;
+
+    *models = data.data = NULL;
+    data.len = 1;
+
+    if (VIR_ALLOC_N(data.data, data.len) < 0)
+        goto error;
+
+    if (cpuGetArchModels(arch, &data) < 0)
+        goto error;
+
+    *models = data.data;
+    return 0;
+
+error:
+    if (data.data) {
+        char **it;
+        for (it = data.data; *it; it++)
+            VIR_FREE(*it);
+        VIR_FREE(data.data);
+    }
+    return -1;
+}
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 69f6fae..ebbc7c1 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -175,4 +175,7 @@ cpuModelIsAllowed(const char *model,
                   const char **models,
                   unsigned int nmodels);
 
+extern int
+cpuGetModels(const char *arch, char ***models);
+
 #endif /* __VIR_CPU_H__ */
diff --git a/src/driver.h b/src/driver.h
index be64333..8cd164a 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -682,6 +682,12 @@ typedef char *
                             unsigned int flags);
 
 typedef int
+(*virDrvConnectGetCPUModelNames)(virConnectPtr conn,
+                                 const char *args,
+                                 char ***models,
+                                 unsigned int flags);
+
+typedef int
 (*virDrvDomainGetJobInfo)(virDomainPtr domain,
                           virDomainJobInfoPtr info);
 
@@ -1332,6 +1338,7 @@ struct _virDriver {
     virDrvDomainMigratePerform3Params domainMigratePerform3Params;
     virDrvDomainMigrateFinish3Params domainMigrateFinish3Params;
     virDrvDomainMigrateConfirm3Params domainMigrateConfirm3Params;
+    virDrvConnectGetCPUModelNames connectGetCPUModelNames;
 };
 
 
diff --git a/src/libvirt.c b/src/libvirt.c
index 07a3fd5..f75469f 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -18519,6 +18519,53 @@ error:
 
 
 /**
+ * virConnectGetCPUModelNames:
+ *
+ * @conn: virConnect connection
+ * @arch: Architecture
+ * @models: NULL terminated array of the CPU models supported for the specified
+ * architecture.  Each element and the array itself must be freed by the caller
+ * with free.
+ * @flags: extra flags; not used yet, so callers should always pass 0.
+ *
+ * Get the list of supported CPU models for a specific architecture.
+ *
+ * Returns -1 on error, 0 on success.
+ */
+int
+virConnectGetCPUModelNames(virConnectPtr conn, const char *arch, char ***models,
+                           unsigned int flags)
+{
+    VIR_DEBUG("conn=%p, arch=%s, flags=%x", conn, arch, flags);
+    virResetLastError();
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+        virDispatchError(NULL);
+        return -1;
+    }
+
+    if (arch == NULL) {
+        virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    if (conn->driver->connectGetCPUModelNames) {
+        if (conn->driver->connectGetCPUModelNames(conn, arch, models, flags) < 0)
+            goto error;
+
+        return 0;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(conn);
+    return -1;
+}
+
+
+/**
  * virConnectBaselineCPU:
  *
  * @conn: virConnect connection
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 35f0f1b..b456c2d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -719,6 +719,7 @@ cpuCompareXML;
 cpuDataFree;
 cpuDecode;
 cpuEncode;
+cpuGetModels;
 cpuGuestData;
 cpuHasFeature;
 cpuMapOverride;
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index bbdf78a..fe9b497 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -634,4 +634,9 @@ LIBVIRT_1.1.1 {
         virDomainSetMemoryStatsPeriod;
 } LIBVIRT_1.1.0;
 
+LIBVIRT_1.1.3 {
+    global:
+        virConnectGetCPUModelNames;
+} LIBVIRT_1.1.1;
+
 # .... define new API here using predicted next version number ....
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 880ae4b..ebab5ae 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -92,6 +92,25 @@ static const vshCmdOptDef opts_freecell[] = {
     {.name = NULL}
 };
 
+static const vshCmdInfo info_cpu_models[] = {
+    {.name = "help",
+     .data = N_("CPU models.")
+    },
+    {.name = "desc",
+     .data = N_("Get the CPU models for an arch.")
+    },
+    {.name = NULL}
+};
+
+static const vshCmdOptDef opts_cpu_models[] = {
+    {.name = "arch",
+     .type = VSH_OT_DATA,
+     .flags = VSH_OFLAG_REQ,
+     .help = N_("architecture")
+    },
+    {.name = NULL}
+};
+
 static bool
 cmdFreecell(vshControl *ctl, const vshCmd *cmd)
 {
@@ -626,6 +645,29 @@ cmdURI(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
     return true;
 }
 
+static bool
+cmdCPUModelNames(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
+{
+    char **models, **it;
+    const char *arch = NULL;
+
+    if (vshCommandOptStringReq(ctl, cmd, "arch", &arch) < 0)
+        return false;
+
+    if (virConnectGetCPUModelNames(ctl->conn, arch, &models, 0) < 0) {
+        vshError(ctl, "%s", _("failed to get CPU Models Names"));
+        return false;
+    }
+
+    for (it = models; *it; it++) {
+        vshPrint(ctl, "%s\n", *it);
+        VIR_FREE(*it);
+    }
+    VIR_FREE(models);
+
+    return true;
+}
+
 /*
  * "version" command
  */
@@ -851,6 +893,12 @@ const vshCmdDef hostAndHypervisorCmds[] = {
      .info = info_capabilities,
      .flags = 0
     },
+    {.name = "cpu-models",
+     .handler = cmdCPUModelNames,
+     .opts = opts_cpu_models,
+     .info = info_cpu_models,
+     .flags = 0
+    },
     {.name = "freecell",
      .handler = cmdFreecell,
      .opts = opts_freecell,
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 0ae5178..72555e7 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -163,6 +163,7 @@ group as an option.  For example:
 
   Host and Hypervisor (help keyword 'host'):
      capabilities                   capabilities
+     cpu-models                     show the CPU models for an architecture
      connect                        (re)connect to hypervisor
      freecell                       NUMA free memory
      hostname                       print the hypervisor hostname
@@ -358,6 +359,10 @@ current domain is in.
 
 =over 4
 
+=item B<cpu-models> I<arch>
+
+Print the list of CPU models known for the specified architecture.
+
 =item B<running>
 
 The domain is currently running on a CPU
-- 
1.8.3.1




More information about the libvir-list mailing list