[libvirt] [PATCH v4 0/7] cpu: add function to get the models for an arch

This series adds a new API "virConnectGetCPUModelNames" that allows to retrieve the list of CPU models known by the hypervisor for a specific architecture. This new function is mainly needed by virt-manager to not read directly the cpu_map.xml file (it could also be different when accessing a remote daemon). *v4 main changes - cpuGetModels translates the arch name to the driver name. - virConnectGetCPUModelNames handles models==NULL, and - amended all the changes reported for v3 *v3 main changes - virConnectGetCPUModelNames returns the number of models instead of 0 on success. - Use VIR_INSERT_ELEMENT instead of VIR_EXPAND_N. - Fix a potential memory leak in the python bindings. - Move virsh changes to a separate commit. - Remove API documentation from libvirt.h. *v2 main changes - set a hard limit for the number of CPU models that is possible to fetch from a remote server. - Use VIR_EXPAND_N instead of VIR_REALLOC_N. - s|1.1.2|1.1.3| Giuseppe Scrivano (7): libvirt: add new public API virConnectGetCPUModelNames cpu: add function to get the models for an arch virConnectGetCPUModelNames: implement the remote protocol virConnectGetCPUModelNames: add the support for qemu virConnectGetCPUModelNames: add the support for the test protocol virsh: add function to get the CPU models for an arch python: add bindings for virConnectGetCPUModelNames daemon/remote.c | 52 ++++++++++++++++++++++++++ include/libvirt/libvirt.h.in | 4 ++ python/generator.py | 1 + python/libvirt-override-api.xml | 7 ++++ python/libvirt-override.c | 52 ++++++++++++++++++++++++++ python/libvirt-override.py | 11 ++++++ src/cpu/cpu.c | 82 ++++++++++++++++++++++++++++++++++++++++- src/cpu/cpu.h | 5 ++- src/driver.h | 7 ++++ src/libvirt.c | 51 +++++++++++++++++++++++++ src/libvirt_private.syms | 1 + src/libvirt_public.syms | 5 +++ src/qemu/qemu_driver.c | 14 +++++++ src/remote/remote_driver.c | 63 +++++++++++++++++++++++++++++++ src/remote/remote_protocol.x | 22 ++++++++++- src/remote_protocol-structs | 13 +++++++ src/test/test_driver.c | 11 ++++++ tools/virsh-host.c | 54 +++++++++++++++++++++++++++ tools/virsh.pod | 5 +++ 19 files changed, 457 insertions(+), 3 deletions(-) -- 1.8.3.1

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@redhat.com> --- include/libvirt/libvirt.h.in | 4 ++++ python/generator.py | 1 + src/driver.h | 7 ++++++ src/libvirt.c | 51 ++++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++++ 5 files changed, 68 insertions(+) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 7944dfb..83c219e 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -4006,6 +4006,10 @@ int virConnectCompareCPU(virConnectPtr conn, const char *xmlDesc, unsigned int flags); +int virConnectGetCPUModelNames(virConnectPtr conn, + const char *arch, + char ***models, + unsigned int flags); /** * virConnectBaselineCPUFlags diff --git a/python/generator.py b/python/generator.py index a91dde8..73107d7 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/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 3f65f12..6f99ed9 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -18525,6 +18525,57 @@ error: /** + * virConnectGetCPUModelNames: + * + * @conn: virConnect connection + * @arch: Architecture + * @models: Pointer to a variable to store the 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. Pass + * NULL if only the list length is needed. + * @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, number of elements in @models on success. + */ +int +virConnectGetCPUModelNames(virConnectPtr conn, const char *arch, char ***models, + unsigned int flags) +{ + VIR_DEBUG("conn=%p, arch=%s, models=%p, flags=%x", + conn, arch, models, flags); + virResetLastError(); + + if (models) + *models = NULL; + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + virCheckNonNullArgReturn(arch, -1); + + if (conn->driver->connectGetCPUModelNames) { + int ret; + + ret = conn->driver->connectGetCPUModelNames(conn, arch, models, flags); + if (ret < 0) + goto error; + + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(conn); + return -1; +} + + +/** * virConnectBaselineCPU: * * @conn: virConnect connection 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 .... -- 1.8.3.1

On 09/23/2013 03:45 AM, Giuseppe Scrivano wrote:
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@redhat.com> ---
+int +virConnectGetCPUModelNames(virConnectPtr conn, const char *arch, char ***models, + unsigned int flags) +{ + VIR_DEBUG("conn=%p, arch=%s, models=%p, flags=%x", + conn, arch, models, flags); + virResetLastError();
Indentation is off. ACK. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> --- src/cpu/cpu.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++- src/cpu/cpu.h | 5 ++- src/libvirt_private.syms | 1 + 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 50c2de3..31de857 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-2012 Red Hat, Inc. + * Copyright (C) 2009-2013 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 @@ -27,11 +27,13 @@ #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" #include "cpu_arm.h" #include "cpu_generic.h" +#include "util/virstring.h" #define NR_DRIVERS ARRAY_CARDINALITY(drivers) @@ -456,3 +458,81 @@ 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 (!data->data) { + VIR_FREE(name); + data->len++; + return 0; + } + + return VIR_INSERT_ELEMENT(data->data, data->len - 1, data->len, name); +} + + +static int +cpuGetArchModels(const char *arch, struct cpuGetModelsData *data) +{ + return cpuMapLoad(arch, cpuGetArchModelsCb, data); +} + + +int +cpuGetModels(const char *archName, char ***models) +{ + struct cpuGetModelsData data; + virArch arch; + struct cpuArchDriver *driver; + data.data = NULL; + data.len = 1; + + arch = virArchFromString(archName); + if (arch == VIR_ARCH_NONE) { + virReportError(VIR_ERR_INVALID_ARG, + _("cannot find architecture %s"), + archName); + goto error; + } + + driver = cpuGetSubDriver(arch); + if (driver == NULL) { + virReportError(VIR_ERR_INVALID_ARG, + _("cannot find a driver for the architecture %s"), + archName); + goto error; + } + + if (models && VIR_ALLOC_N(data.data, data.len) < 0) + goto error; + + if (cpuGetArchModels(driver->name, &data) < 0) + goto error; + + if (models) + *models = data.data; + + return data.len - 1; + +error: + virStringFreeList(data.data); + return -1; +} diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 69f6fae..2f0c8c7 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-2010 Red Hat, Inc. + * Copyright (C) 2009-2010, 2013 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 @@ -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/libvirt_private.syms b/src/libvirt_private.syms index 50e2f48..7665c3a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -721,6 +721,7 @@ cpuCompareXML; cpuDataFree; cpuDecode; cpuEncode; +cpuGetModels; cpuGuestData; cpuHasFeature; cpuMapOverride; -- 1.8.3.1

On 09/23/2013 03:45 AM, Giuseppe Scrivano wrote:
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> --- src/cpu/cpu.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++- src/cpu/cpu.h | 5 ++- src/libvirt_private.syms | 1 + 3 files changed, 86 insertions(+), 2 deletions(-)
ACK. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> --- daemon/remote.c | 52 ++++++++++++++++++++++++++++++++++++ src/remote/remote_driver.c | 63 ++++++++++++++++++++++++++++++++++++++++++++ src/remote/remote_protocol.x | 22 +++++++++++++++- src/remote_protocol-structs | 13 +++++++++ 4 files changed, 149 insertions(+), 1 deletion(-) diff --git a/daemon/remote.c b/daemon/remote.c index 2ff2288..9497cc1 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -5056,6 +5056,58 @@ cleanup: static int +remoteDispatchConnectGetCPUModelNames(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client ATTRIBUTE_UNUSED, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + remote_connect_get_cpu_model_names_args *args, + remote_connect_get_cpu_model_names_ret *ret) +{ + int len, rv = -1; + char **models = NULL; + struct daemonClientPrivate *priv = + virNetServerClientGetPrivateData(client); + + if (!priv->conn) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); + goto cleanup; + } + + len = virConnectGetCPUModelNames(priv->conn, args->arch, + args->need_results ? &models : NULL, + args->flags); + if (len < 0) + goto cleanup; + + if (len > REMOTE_CONNECT_CPU_MODELS_MAX) { + virReportError(VIR_ERR_RPC, + _("Too many CPU models '%d' for limit '%d'"), + len, REMOTE_CONNECT_CPU_MODELS_MAX); + goto cleanup; + } + + if (len && models) { + ret->models.models_val = models; + ret->models.models_len = len; + models = NULL; + } else { + ret->models.models_val = NULL; + ret->models.models_len = 0; + } + + ret->ret = len; + + rv = 0; + +cleanup: + if (rv < 0) + virNetMessageSaveError(rerr); + virStringFreeList(models); + return rv; +} + + +static int remoteDispatchDomainCreateXMLWithFiles(virNetServerPtr server ATTRIBUTE_UNUSED, virNetServerClientPtr client, virNetMessagePtr msg ATTRIBUTE_UNUSED, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 62e77a5..96ccb99 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -5541,6 +5541,68 @@ done: static int +remoteConnectGetCPUModelNames(virConnectPtr conn, + const char *arch, + char ***models, + unsigned int flags) +{ + int rv = -1; + size_t i; + char **retmodels = NULL; + remote_connect_get_cpu_model_names_args args; + remote_connect_get_cpu_model_names_ret ret; + + struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); + + args.arch = (char *) arch; + args.need_results = !!models; + args.flags = flags; + + memset(&ret, 0, sizeof(ret)); + if (call(conn, priv, 0, REMOTE_PROC_CONNECT_GET_CPU_MODEL_NAMES, + (xdrproc_t) xdr_remote_connect_get_cpu_model_names_args, + (char *) &args, + (xdrproc_t) xdr_remote_connect_get_cpu_model_names_ret, + (char *) &ret) < 0) + goto done; + + /* Check the length of the returned list carefully. */ + if (ret.models.models_len > REMOTE_CONNECT_CPU_MODELS_MAX) { + virReportError(VIR_ERR_RPC, + _("Too many model names '%d' for limit '%d'"), + ret.models.models_len, + REMOTE_CONNECT_CPU_MODELS_MAX); + goto cleanup; + } + + if (models) { + if (VIR_ALLOC_N(retmodels, ret.models.models_len + 1) < 0) + goto cleanup; + + for (i = 0; i < ret.models.models_len; i++) { + retmodels[i] = ret.models.models_val[i]; + ret.models.models_val[i] = NULL; + } + *models = retmodels; + retmodels = NULL; + } + + rv = ret.ret; + +cleanup: + virStringFreeList(retmodels); + + xdr_free((xdrproc_t) xdr_remote_connect_get_cpu_model_names_ret, (char *) &ret); + +done: + remoteDriverUnlock(priv); + return rv; +} + + +static int remoteDomainOpenGraphics(virDomainPtr dom, unsigned int idx, int fd, @@ -6933,6 +6995,7 @@ static virDriver remote_driver = { .domainMigratePerform3Params = remoteDomainMigratePerform3Params, /* 1.1.0 */ .domainMigrateFinish3Params = remoteDomainMigrateFinish3Params, /* 1.1.0 */ .domainMigrateConfirm3Params = remoteDomainMigrateConfirm3Params, /* 1.1.0 */ + .connectGetCPUModelNames = remoteConnectGetCPUModelNames, /* 1.1.3 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 85ad9ba..8d17bad 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -232,6 +232,9 @@ const REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX = 64; /* Upper limit on number of job stats */ const REMOTE_DOMAIN_JOB_STATS_MAX = 16; +/* Upper limit on number of CPU models */ +const REMOTE_CONNECT_CPU_MODELS_MAX = 8192; + /* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */ typedef opaque remote_uuid[VIR_UUID_BUFLEN]; @@ -2835,6 +2838,17 @@ struct remote_domain_event_device_removed_msg { remote_nonnull_string devAlias; }; +struct remote_connect_get_cpu_model_names_args { + remote_nonnull_string arch; + int need_results; + unsigned int flags; +}; + +struct remote_connect_get_cpu_model_names_ret { + remote_nonnull_string models<REMOTE_CONNECT_CPU_MODELS_MAX>; + int ret; +}; + /*----- Protocol. -----*/ /* Define the program number, protocol version and procedure numbers here. */ @@ -4998,5 +5012,11 @@ enum remote_procedure { * @generate: both * @acl: none */ - REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311 + REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311, + + /** + * @generate: none + * @acl: connect:read + */ + REMOTE_PROC_CONNECT_GET_CPU_MODEL_NAMES = 312 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 4e27aae..98d2d5b 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2316,6 +2316,18 @@ struct remote_domain_event_device_removed_msg { remote_nonnull_domain dom; remote_nonnull_string devAlias; }; +struct remote_connect_get_cpu_model_names_args { + remote_nonnull_string arch; + int need_results; + u_int flags; +}; +struct remote_connect_get_cpu_model_names_ret { + struct { + u_int models_len; + remote_nonnull_string * models_val; + } models; + int ret; +}; enum remote_procedure { REMOTE_PROC_CONNECT_OPEN = 1, REMOTE_PROC_CONNECT_CLOSE = 2, @@ -2628,4 +2640,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_CREATE_XML_WITH_FILES = 309, REMOTE_PROC_DOMAIN_CREATE_WITH_FILES = 310, REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311, + REMOTE_PROC_CONNECT_GET_CPU_MODEL_NAMES = 312, }; -- 1.8.3.1

On 09/23/2013 03:46 AM, Giuseppe Scrivano wrote:
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> --- daemon/remote.c | 52 ++++++++++++++++++++++++++++++++++++ src/remote/remote_driver.c | 63 ++++++++++++++++++++++++++++++++++++++++++++ src/remote/remote_protocol.x | 22 +++++++++++++++- src/remote_protocol-structs | 13 +++++++++ 4 files changed, 149 insertions(+), 1 deletion(-)
diff --git a/daemon/remote.c b/daemon/remote.c index 2ff2288..9497cc1 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -5056,6 +5056,58 @@ cleanup:
ACK. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> --- src/qemu/qemu_driver.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8a302d1..346a8f9 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -15767,6 +15767,19 @@ qemuNodeSuspendForDuration(virConnectPtr conn, return nodeSuspendForDuration(target, duration, flags); } +static int +qemuConnectGetCPUModelNames(virConnectPtr conn, + const char *arch, + char ***models, + unsigned int flags) +{ + virCheckFlags(0, -1); + if (virConnectGetCPUModelNamesEnsureACL(conn) < 0) + return -1; + + return cpuGetModels(arch, models); +} + static virDriver qemuDriver = { .no = VIR_DRV_QEMU, @@ -15954,6 +15967,7 @@ static virDriver qemuDriver = { .domainMigratePerform3Params = qemuDomainMigratePerform3Params, /* 1.1.0 */ .domainMigrateFinish3Params = qemuDomainMigrateFinish3Params, /* 1.1.0 */ .domainMigrateConfirm3Params = qemuDomainMigrateConfirm3Params, /* 1.1.0 */ + .connectGetCPUModelNames = qemuConnectGetCPUModelNames, /* 1.1.3 */ }; -- 1.8.3.1

On 09/23/2013 03:46 AM, Giuseppe Scrivano wrote:
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> --- src/qemu/qemu_driver.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
ACK. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> --- src/test/test_driver.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index cd65dc5..47c9d38 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -54,6 +54,7 @@ #include "virtypedparam.h" #include "virrandom.h" #include "virstring.h" +#include "cpu/cpu.h" #define VIR_FROM_THIS VIR_FROM_TEST @@ -5867,6 +5868,15 @@ testDomainScreenshot(virDomainPtr dom ATTRIBUTE_UNUSED, return ret; } +static int +testConnectGetCPUModelNames(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *arch, + char ***models, + unsigned int flags) +{ + virCheckFlags(0, -1); + return cpuGetModels(arch, models); +} static virDriver testDriver = { .no = VIR_DRV_TEST, @@ -5940,6 +5950,7 @@ static virDriver testDriver = { .domainScreenshot = testDomainScreenshot, /* 1.0.5 */ .domainGetMetadata = testDomainGetMetadata, /* 1.1.3 */ .domainSetMetadata = testDomainSetMetadata, /* 1.1.3 */ + .connectGetCPUModelNames = testConnectGetCPUModelNames, /* 1.1.3 */ }; static virNetworkDriver testNetworkDriver = { -- 1.8.3.1

On 09/23/2013 03:46 AM, Giuseppe Scrivano wrote:
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> --- src/test/test_driver.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
ACK. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> --- tools/virsh-host.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 5 +++++ 2 files changed, 59 insertions(+) diff --git a/tools/virsh-host.c b/tools/virsh-host.c index f69ab79..1d1bb97 100644 --- a/tools/virsh-host.c +++ b/tools/virsh-host.c @@ -665,6 +665,54 @@ cmdURI(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) } /* + * "cpu-models" command + */ +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 +cmdCPUModelNames(vshControl *ctl, const vshCmd *cmd) +{ + char **models; + size_t i; + int nmodels; + const char *arch = NULL; + + if (vshCommandOptStringReq(ctl, cmd, "arch", &arch) < 0) + return false; + + nmodels = virConnectGetCPUModelNames(ctl->conn, arch, &models, 0); + if (nmodels < 0) { + vshError(ctl, "%s", _("failed to get CPU model names")); + return false; + } + + for (i = 0; i < nmodels; i++) { + vshPrint(ctl, "%s\n", models[i]); + VIR_FREE(models[i]); + } + VIR_FREE(models); + + return true; +} + +/* * "version" command */ static const vshCmdInfo info_version[] = { @@ -889,6 +937,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 2864f3d..e12a800 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

On 09/23/2013 03:46 AM, Giuseppe Scrivano wrote:
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> --- tools/virsh-host.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 5 +++++ 2 files changed, 59 insertions(+)
ACK. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> --- python/generator.py | 2 +- python/libvirt-override-api.xml | 7 ++++++ python/libvirt-override.c | 52 +++++++++++++++++++++++++++++++++++++++++ python/libvirt-override.py | 11 +++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/python/generator.py b/python/generator.py index 73107d7..12c14f1 100755 --- a/python/generator.py +++ b/python/generator.py @@ -250,6 +250,7 @@ lxc_functions_failed = [] qemu_functions_failed = [] functions_skipped = [ "virConnectListDomains", + "virConnectGetCPUModelNames", ] lxc_functions_skipped = [] qemu_functions_skipped = [] @@ -366,7 +367,6 @@ 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/python/libvirt-override-api.xml b/python/libvirt-override-api.xml index 9a88215..1bceb05 100644 --- a/python/libvirt-override-api.xml +++ b/python/libvirt-override-api.xml @@ -476,6 +476,13 @@ <arg name='xmlCPUs' type='const char **' info='array of XML descriptions of host CPUs'/> <arg name='flags' type='unsigned int' info='fine-tuning flags, currently unused, pass 0.'/> </function> + <function name='virConnectGetCPUModelNames' file='python'> + <info>Get the list of supported CPU models.</info> + <return type='char *' info='list of supported CPU models'/> + <arg name='conn' type='virConnectPtr' info='virConnect connection'/> + <arg name='arch' type='const char *' info='arch'/> + <arg name='flags' type='unsigned int' info='fine-tuning flags, currently unused, pass 0.'/> + </function> <function name='virDomainSnapshotListNames' file='python'> <info>collect the list of snapshot names for the given domain</info> <arg name='dom' type='virDomainPtr' info='pointer to the domain'/> diff --git a/python/libvirt-override.c b/python/libvirt-override.c index cc76c47..5e4acc3 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -2276,6 +2276,58 @@ libvirt_virConnectGetVersion(PyObject *self ATTRIBUTE_UNUSED, return PyInt_FromLong(hvVersion); } +PyObject * +libvirt_virConnectGetCPUModelNames(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args) +{ + int c_retval; + virConnectPtr conn; + PyObject *rv = NULL, *pyobj_conn; + char **models = NULL; + size_t i; + int flags = 0; + const char *arch = NULL; + + if (!PyArg_ParseTuple(args, (char *)"Osi:virConnectGetCPUModelNames", + &pyobj_conn, &arch, &flags)) + return NULL; + conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); + + LIBVIRT_BEGIN_ALLOW_THREADS; + + c_retval = virConnectGetCPUModelNames(conn, arch, &models, flags); + + LIBVIRT_END_ALLOW_THREADS; + + if (c_retval == -1) + return VIR_PY_INT_FAIL; + + if ((rv = PyList_New(c_retval)) == NULL) + goto error; + + for (i = 0; i < c_retval; i++) { + PyObject *str; + if ((str = PyString_FromString(models[i])) == NULL) + goto error; + + PyList_SET_ITEM(rv, i, str); + } + +done: + if (models) { + for (i = 0; i < c_retval; i++) + VIR_FREE(models[i]); + VIR_FREE(models); + } + + return rv; + +error: + Py_XDECREF(rv); + rv = VIR_PY_INT_FAIL; + goto done; +} + static PyObject * libvirt_virConnectGetLibVersion(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) diff --git a/python/libvirt-override.py b/python/libvirt-override.py index ccfec48..3471a43 100644 --- a/python/libvirt-override.py +++ b/python/libvirt-override.py @@ -207,3 +207,14 @@ def virEventAddTimeout(timeout, cb, opaque): ret = libvirtmod.virEventAddTimeout(timeout, cbData) if ret == -1: raise libvirtError ('virEventAddTimeout() failed') return ret + +def getCPUModelNames(conn, arch, flags=0): + """ + get the list of supported CPU models. + @conn: virConnect connection + @arch: Architecture + @flags: extra flags; not used yet, so callers should always pass 0. + """ + ret = libvirtmod.virConnectGetCPUModelNames(conn._o, arch, flags) + if ret == None: raise libvirtError ('virConnectGetCPUModelNames() failed', conn=self) + return ret -- 1.8.3.1

On 09/23/2013 03:46 AM, Giuseppe Scrivano wrote:
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> --- python/generator.py | 2 +- python/libvirt-override-api.xml | 7 ++++++ python/libvirt-override.c | 52 +++++++++++++++++++++++++++++++++++++++++ python/libvirt-override.py | 11 +++++++++ 4 files changed, 71 insertions(+), 1 deletion(-)
+PyObject * +libvirt_virConnectGetCPUModelNames(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args) +{
So close - you forgot to list this function in the exports. With this squashed in: diff --git i/python/libvirt-override.c w/python/libvirt-override.c index 5e4acc3..e659bae 100644 --- i/python/libvirt-override.c +++ w/python/libvirt-override.c @@ -7223,6 +7223,7 @@ static PyMethodDef libvirtMethods[] = { #include "libvirt-export.c" {(char *) "virGetVersion", libvirt_virGetVersion, METH_VARARGS, NULL}, {(char *) "virConnectGetVersion", libvirt_virConnectGetVersion, METH_VARARGS, NULL}, + {(char *) "virConnectGetCPUModelNames", libvirt_virConnectGetCPUModelNames, METH_VARARGS, NULL}, {(char *) "virConnectGetLibVersion", libvirt_virConnectGetLibVersion, METH_VARARGS, NULL}, {(char *) "virConnectOpenAuth", libvirt_virConnectOpenAuth, METH_VARARGS, NULL}, {(char *) "virConnectListDomainsID", libvirt_virConnectListDomainsID, METH_VARARGS, NULL}, I was able to do a smoke test: $ ./run python Python 2.7.5 (default, Aug 22 2013, 09:31:58) [GCC 4.8.1 20130603 (Red Hat 4.8.1-1)] on linux2 Type "help", "copyright", "credits" or "license" for more information.
import libvirt conn = libvirt.open() conn.getCPUModelNames("x86_64") ['486', 'pentium', 'pentium2', 'pentium3', 'pentiumpro', 'coreduo', 'n270', 'core2duo', 'qemu32', 'kvm32', 'cpu64-rhel5', 'cpu64-rhel6', 'kvm64', 'qemu64', 'Conroe', 'Penryn', 'Nehalem', 'Westmere', 'SandyBridge', 'Haswell', 'athlon', 'phenom', 'Opteron_G1', 'Opteron_G2', 'Opteron_G3', 'Opteron_G4', 'Opteron_G5']
ACK and series pushed with my two minor fixes in 1 and 7. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (2)
-
Eric Blake
-
Giuseppe Scrivano