diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 50c2de31835807c68594aa2e0314321246d01cd7..31de85740e87065da0b451635b9f3ef9c8c883d9 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 69f6fae000557d78404dcb72b54e21c5e1d144f3..2f0c8c7ae3c819529f9d79d10ceb45d19f61374a 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 50e2f487a61f49c24e0b172af822fa8bc71c7e95..7665c3a12bb152f946c994800fbe832f3cf3a89b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -721,6 +721,7 @@ cpuCompareXML; cpuDataFree; cpuDecode; cpuEncode; +cpuGetModels; cpuGuestData; cpuHasFeature; cpuMapOverride;