[libvirt] [PATCHv3 0/4] implement virNodeGetCPUMap

This is the prerequisite patches I promised, plus v3 of patches 7-8 of 9 from Viktor's v2 series (1-6 are already committed, and patch 9 for python bindings I'm leaving for Viktor to touch up). Eric Blake (2): bitmap: add virBitmapCountBits nodeinfo: improve probing node cpu bitmap Viktor Mihajlovski (2): virNodeGetCPUMap: Implement support function in nodeinfo virNodeGetCPUMap: Implement driver support src/libvirt_private.syms | 4 +- src/lxc/lxc_driver.c | 1 + src/nodeinfo.c | 104 +++++++++++++++++++++++++++++++++------------ src/nodeinfo.h | 11 +++-- src/openvz/openvz_driver.c | 1 + src/qemu/qemu_driver.c | 7 +-- src/test/test_driver.c | 31 ++++++++++++++ src/uml/uml_driver.c | 1 + src/util/bitmap.c | 26 ++++++++++-- src/util/bitmap.h | 6 ++- tests/virbitmaptest.c | 7 +++ 11 files changed, 162 insertions(+), 37 deletions(-) -- 1.7.11.7

Sometimes it's handy to know how many bits are set. * src/util/bitmap.h (virBitmapCountBits): New prototype. (virBitmapNextSetBit): Use correct type. * src/util/bitmap.c (virBitmapNextSetBit): Likewise. (virBitmapCountBits): New function. * src/libvirt_private.syms (bitmap.h): Export it. * tests/virbitmaptest.c (test2): Test it. --- src/libvirt_private.syms | 1 + src/util/bitmap.c | 26 +++++++++++++++++++++++--- src/util/bitmap.h | 6 +++++- tests/virbitmaptest.c | 7 +++++++ 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 699c9a3..7a87f2b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -9,6 +9,7 @@ virBitmapClearAll; virBitmapClearBit; virBitmapCopy; +virBitmapCountBits; virBitmapEqual; virBitmapFormat; virBitmapFree; diff --git a/src/util/bitmap.c b/src/util/bitmap.c index 2797005..9a9152a 100644 --- a/src/util/bitmap.c +++ b/src/util/bitmap.c @@ -35,6 +35,7 @@ #include "buf.h" #include "util.h" #include "c-ctype.h" +#include "count-one-bits.h" struct _virBitmap { @@ -585,10 +586,10 @@ bool virBitmapIsAllSet(virBitmapPtr bitmap) * * returns the position of the found bit, or -1 if no bit found. */ -int virBitmapNextSetBit(virBitmapPtr bitmap, int pos) +ssize_t virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos) { - int nl; - int nb; + size_t nl; + size_t nb; unsigned long bits; if (pos < 0) @@ -613,3 +614,22 @@ int virBitmapNextSetBit(virBitmapPtr bitmap, int pos) return ffsl(bits) - 1 + nl * VIR_BITMAP_BITS_PER_UNIT; } + +/* Return the number of bits currently set in the map. */ +size_t +virBitmapCountBits(virBitmapPtr bitmap) +{ + size_t i; + size_t ret = 0; + int tail = bitmap->max_bit % VIR_BITMAP_BITS_PER_UNIT; + + /* Ensure tail bits are clear. */ + if (tail) + bitmap->map[bitmap->map_len - 1] &= + -1UL >> (VIR_BITMAP_BITS_PER_UNIT - tail); + + for (i = 0; i < bitmap->map_len; i++) + ret += count_one_bits_l(bitmap->map[i]); + + return ret; +} diff --git a/src/util/bitmap.h b/src/util/bitmap.h index 7755a17..346a1fb 100644 --- a/src/util/bitmap.h +++ b/src/util/bitmap.h @@ -1,6 +1,7 @@ /* * bitmap.h: Simple bitmap operations * + * Copyright (C) 2012 Red Hat, Inc. * Copyright (C) 2010 Novell, Inc. * * This library is free software; you can redistribute it and/or @@ -99,7 +100,10 @@ void virBitmapClearAll(virBitmapPtr bitmap) bool virBitmapIsAllSet(virBitmapPtr bitmap) ATTRIBUTE_NONNULL(1); -int virBitmapNextSetBit(virBitmapPtr bitmap, int pos) +ssize_t virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos) + ATTRIBUTE_NONNULL(1); + +size_t virBitmapCountBits(virBitmapPtr bitmap) ATTRIBUTE_NONNULL(1); #endif diff --git a/tests/virbitmaptest.c b/tests/virbitmaptest.c index 0aa28fd..f1eb9d5 100644 --- a/tests/virbitmaptest.c +++ b/tests/virbitmaptest.c @@ -99,6 +99,9 @@ static int test2(const void *data ATTRIBUTE_UNUSED) if (testBit(bitmap, 100, 1020, false) < 0) goto error; + if (virBitmapCountBits(bitmap) != 48) + goto error; + bitsString2 = virBitmapFormat(bitmap); if (strcmp(bitsString1, bitsString2)) goto error; @@ -106,6 +109,8 @@ static int test2(const void *data ATTRIBUTE_UNUSED) virBitmapSetAll(bitmap); if (testBit(bitmap, 0, size - 1, true) < 0) goto error; + if (virBitmapCountBits(bitmap) != size) + goto error; if (!virBitmapIsAllSet(bitmap)) goto error; @@ -113,6 +118,8 @@ static int test2(const void *data ATTRIBUTE_UNUSED) virBitmapClearAll(bitmap); if (testBit(bitmap, 0, size - 1, false) < 0) goto error; + if (virBitmapCountBits(bitmap) != 0) + goto error; ret = 0; -- 1.7.11.7

On 10/25/2012 03:36 AM, Eric Blake wrote:
Sometimes it's handy to know how many bits are set.
* src/util/bitmap.h (virBitmapCountBits): New prototype. (virBitmapNextSetBit): Use correct type. * src/util/bitmap.c (virBitmapNextSetBit): Likewise. (virBitmapCountBits): New function. * src/libvirt_private.syms (bitmap.h): Export it. * tests/virbitmaptest.c (test2): Test it. You might want to add a sign-off. +/* Return the number of bits currently set in the map. */ +size_t +virBitmapCountBits(virBitmapPtr bitmap) +{ + size_t i; + size_t ret = 0; + int tail = bitmap->max_bit % VIR_BITMAP_BITS_PER_UNIT; + + /* Ensure tail bits are clear. */ + if (tail) + bitmap->map[bitmap->map_len - 1] &= + -1UL >> (VIR_BITMAP_BITS_PER_UNIT - tail); Probably not necessary, as the bitmap is initialized to zero.
Works for me. -- Mit freundlichen Grüßen/Kind Regards Viktor Mihajlovski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martin Jetter Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

On 10/25/2012 08:35 AM, Viktor Mihajlovski wrote:
On 10/25/2012 03:36 AM, Eric Blake wrote:
Sometimes it's handy to know how many bits are set.
* src/util/bitmap.h (virBitmapCountBits): New prototype. (virBitmapNextSetBit): Use correct type. * src/util/bitmap.c (virBitmapNextSetBit): Likewise. (virBitmapCountBits): New function. * src/libvirt_private.syms (bitmap.h): Export it. * tests/virbitmaptest.c (test2): Test it. You might want to add a sign-off. +/* Return the number of bits currently set in the map. */ +size_t +virBitmapCountBits(virBitmapPtr bitmap) +{ + size_t i; + size_t ret = 0; + int tail = bitmap->max_bit % VIR_BITMAP_BITS_PER_UNIT; + + /* Ensure tail bits are clear. */ + if (tail) + bitmap->map[bitmap->map_len - 1] &= + -1UL >> (VIR_BITMAP_BITS_PER_UNIT - tail); Probably not necessary, as the bitmap is initialized to zero.
Absolutely necessary, or 'make check' fails. But debatable whether to put it here, or to shift it to virBitmapSetAll() (as THAT appears to be the only culprit function that ever sets tail-bits to 1).
Works for me.
Thanks for the review. I think I'll move the tail clearing to virBitmapSetAll, as that is likely to be the less-frequently called function, and maintaining the invariant that tail bits are always clear seems nicer than assuming they are undefined and having to explicitly clear tail bits prior to a count operation. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 10/25/2012 10:46 AM, Eric Blake wrote:
+ + /* Ensure tail bits are clear. */ + if (tail) + bitmap->map[bitmap->map_len - 1] &= + -1UL >> (VIR_BITMAP_BITS_PER_UNIT - tail); Probably not necessary, as the bitmap is initialized to zero.
Absolutely necessary, or 'make check' fails. But debatable whether to put it here, or to shift it to virBitmapSetAll() (as THAT appears to be the only culprit function that ever sets tail-bits to 1).
Works for me.
Thanks for the review. I think I'll move the tail clearing to virBitmapSetAll, as that is likely to be the less-frequently called function, and maintaining the invariant that tail bits are always clear seems nicer than assuming they are undefined and having to explicitly clear tail bits prior to a count operation.
I've now pushed the series with this squashed in. Thanks for your initial work, and for testing my changes. diff --git i/src/util/bitmap.c w/src/util/bitmap.c index 9a9152a..2dd3403 100644 --- i/src/util/bitmap.c +++ w/src/util/bitmap.c @@ -528,8 +528,15 @@ size_t virBitmapSize(virBitmapPtr bitmap) */ void virBitmapSetAll(virBitmapPtr bitmap) { + int tail = bitmap->max_bit % VIR_BITMAP_BITS_PER_UNIT; + memset(bitmap->map, 0xff, bitmap->map_len * (VIR_BITMAP_BITS_PER_UNIT / CHAR_BIT)); + + /* Ensure tail bits are clear. */ + if (tail) + bitmap->map[bitmap->map_len - 1] &= + -1UL >> (VIR_BITMAP_BITS_PER_UNIT - tail); } /** @@ -621,12 +628,6 @@ virBitmapCountBits(virBitmapPtr bitmap) { size_t i; size_t ret = 0; - int tail = bitmap->max_bit % VIR_BITMAP_BITS_PER_UNIT; - - /* Ensure tail bits are clear. */ - if (tail) - bitmap->map[bitmap->map_len - 1] &= - -1UL >> (VIR_BITMAP_BITS_PER_UNIT - tail); for (i = 0; i < bitmap->map_len; i++) ret += count_one_bits_l(bitmap->map[i]); -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Callers should not need to know what the name of the file to be read in the Linux-specific version of nodeGetCPUmap; furthermore, qemu cares about online cpus, not present cpus, when determining which cpus to skip. While at it, I fixed the fact that we were computing the maximum online cpu id by doing a slow iteration, when what we really want to know is the max available cpu. * src/nodeinfo.h (nodeGetCPUmap): Rename... (nodeGetCPUBitmap): ...and simplify signature. * src/nodeinfo.c (linuxParseCPUmax): New function. (linuxParseCPUmap): Simplify and alter signature. (nodeGetCPUBitmap): Change implementation. * src/libvirt_private.syms (nodeinfo.h): Reflect rename. * src/qemu/qemu_driver.c (qemuDomainGetPercpuStats): Update caller. --- src/libvirt_private.syms | 2 +- src/nodeinfo.c | 76 +++++++++++++++++++++++++++++++----------------- src/nodeinfo.h | 5 ++-- src/qemu/qemu_driver.c | 6 ++-- 4 files changed, 56 insertions(+), 33 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 7a87f2b..a9cae52 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -907,7 +907,7 @@ virNodeDeviceObjUnlock; # nodeinfo.h nodeCapsInitNUMA; -nodeGetCPUmap; +nodeGetCPUBitmap; nodeGetCPUStats; nodeGetCellsFreeMemory; nodeGetFreeMemory; diff --git a/src/nodeinfo.c b/src/nodeinfo.c index 8f96b8b..461b5dc 100644 --- a/src/nodeinfo.c +++ b/src/nodeinfo.c @@ -755,34 +755,55 @@ cleanup: return ret; } + +/* Determine the maximum cpu id from a Linux sysfs cpu/present file. */ +static int +linuxParseCPUmax(const char *path) +{ + char *str = NULL; + char *tmp; + int ret = -1; + + if (virFileReadAll(path, 5 * VIR_DOMAIN_CPUMASK_LEN, &str) < 0) { + virReportOOMError(); + goto cleanup; + } + + tmp = str; + do { + if (virStrToLong_i(tmp, &tmp, 10, &ret) < 0 || + !strchr(",-\n", *tmp)) { + virReportError(VIR_ERR_NO_SUPPORT, + _("failed to parse %s"), path); + ret = -1; + goto cleanup; + } + } while (*tmp++ != '\n'); + ret++; + +cleanup: + VIR_FREE(str); + return ret; +} + /* - * Linux maintains cpu bit map. For example, if cpuid=5's flag is not set - * and max cpu is 7. The map file shows 0-4,6-7. This function parses - * it and returns cpumap. + * Linux maintains cpu bit map under cpu/online. For example, if + * cpuid=5's flag is not set and max cpu is 7, the map file shows + * 0-4,6-7. This function parses it and returns cpumap. */ static virBitmapPtr -linuxParseCPUmap(int *max_cpuid, const char *path) +linuxParseCPUmap(int max_cpuid, const char *path) { virBitmapPtr map = NULL; char *str = NULL; - int max_id = 0, i; if (virFileReadAll(path, 5 * VIR_DOMAIN_CPUMASK_LEN, &str) < 0) { virReportOOMError(); goto error; } - if (virBitmapParse(str, 0, &map, - VIR_DOMAIN_CPUMASK_LEN) < 0) { + if (virBitmapParse(str, 0, &map, max_cpuid) < 0) goto error; - } - - i = -1; - while ((i = virBitmapNextSetBit(map, i)) >= 0) { - max_id = i; - } - - *max_cpuid = max_id; VIR_FREE(str); return map; @@ -929,21 +950,24 @@ int nodeGetMemoryStats(virConnectPtr conn ATTRIBUTE_UNUSED, } virBitmapPtr -nodeGetCPUmap(virConnectPtr conn ATTRIBUTE_UNUSED, - int *max_id ATTRIBUTE_UNUSED, - const char *mapname ATTRIBUTE_UNUSED) +nodeGetCPUBitmap(virConnectPtr conn ATTRIBUTE_UNUSED, + int *max_id ATTRIBUTE_UNUSED) { #ifdef __linux__ - char *path; virBitmapPtr cpumap; - - if (virAsprintf(&path, SYSFS_SYSTEM_PATH "/cpu/%s", mapname) < 0) { - virReportOOMError(); + int present; + + present = linuxParseCPUmax(SYSFS_SYSTEM_PATH "/cpu/present"); + /* XXX should we also work on older kernels, like RHEL5, that lack + * cpu/present and cpu/online files? Those kernels also lack cpu + * hotplugging, so it would be a matter of finding the largest + * cpu/cpuNN directory, and creating a map that size with all bits + * set. */ + if (present < 0) return NULL; - } - - cpumap = linuxParseCPUmap(max_id, path); - VIR_FREE(path); + cpumap = linuxParseCPUmap(present, SYSFS_SYSTEM_PATH "/cpu/online"); + if (max_id && cpumap) + *max_id = present; return cpumap; #else virReportError(VIR_ERR_NO_SUPPORT, "%s", diff --git a/src/nodeinfo.h b/src/nodeinfo.h index 2eda846..73c6f51 100644 --- a/src/nodeinfo.h +++ b/src/nodeinfo.h @@ -46,9 +46,8 @@ int nodeGetCellsFreeMemory(virConnectPtr conn, int maxCells); unsigned long long nodeGetFreeMemory(virConnectPtr conn); -virBitmapPtr nodeGetCPUmap(virConnectPtr conn, - int *max_id, - const char *mapname); +virBitmapPtr nodeGetCPUBitmap(virConnectPtr conn, + int *max_id); int nodeGetMemoryParameters(virConnectPtr conn, virTypedParameterPtr params, diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 254f191..57e6403 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -13615,8 +13615,8 @@ qemuDomainGetPercpuStats(virDomainPtr domain, if (nparams == 0 && ncpus != 0) return QEMU_NB_PER_CPU_STAT_PARAM; - /* To parse account file, we need "present" cpu map. */ - map = nodeGetCPUmap(domain->conn, &max_id, "present"); + /* To parse account file, we need bitmap of online cpus. */ + map = nodeGetCPUBitmap(domain->conn, &max_id); if (!map) return rv; @@ -13681,7 +13681,7 @@ qemuDomainGetPercpuStats(virDomainPtr domain, goto cleanup; /* Check that the mapping of online cpus didn't change mid-parse. */ - map2 = nodeGetCPUmap(domain->conn, &max_id, "present"); + map2 = nodeGetCPUBitmap(domain->conn, &max_id); if (!map2 || !virBitmapEqual(map, map2)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("the set of online cpus changed while reading")); -- 1.7.11.7

On 10/25/2012 03:36 AM, Eric Blake wrote:
Callers should not need to know what the name of the file to be read in the Linux-specific version of nodeGetCPUmap; furthermore, qemu cares about online cpus, not present cpus, when determining which cpus to skip.
While at it, I fixed the fact that we were computing the maximum online cpu id by doing a slow iteration, when what we really want to know is the max available cpu.
* src/nodeinfo.h (nodeGetCPUmap): Rename... (nodeGetCPUBitmap): ...and simplify signature. * src/nodeinfo.c (linuxParseCPUmax): New function. (linuxParseCPUmap): Simplify and alter signature. (nodeGetCPUBitmap): Change implementation. * src/libvirt_private.syms (nodeinfo.h): Reflect rename. * src/qemu/qemu_driver.c (qemuDomainGetPercpuStats): Update caller.
Tested-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> -- Mit freundlichen Grüßen/Kind Regards Viktor Mihajlovski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martin Jetter Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

On 10/24/2012 07:36 PM, Eric Blake wrote:
Callers should not need to know what the name of the file to be read in the Linux-specific version of nodeGetCPUmap; furthermore, qemu cares about online cpus, not present cpus, when determining which cpus to skip.
While at it, I fixed the fact that we were computing the maximum online cpu id by doing a slow iteration, when what we really want to know is the max available cpu.
* src/nodeinfo.h (nodeGetCPUmap): Rename... (nodeGetCPUBitmap): ...and simplify signature. * src/nodeinfo.c (linuxParseCPUmax): New function. (linuxParseCPUmap): Simplify and alter signature. (nodeGetCPUBitmap): Change implementation. * src/libvirt_private.syms (nodeinfo.h): Reflect rename. * src/qemu/qemu_driver.c (qemuDomainGetPercpuStats): Update caller.
Shoot. Now that I've pushed this, I'm getting: # virsh cpu-stats dom error: Failed to virDomainGetCPUStats() error: An error occurred, but the cause is unknown on a host with 6 out of 8 cpus online, where it gave reasonable answers pre-patch. I'm still investigating. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> Added an implemention of virNodeGetCPUMap to nodeinfo.c, (nodeGetCPUMap) which can be used by all drivers for a Linux hypervisor host. Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> --- src/libvirt_private.syms | 1 + src/nodeinfo.c | 28 ++++++++++++++++++++++++++++ src/nodeinfo.h | 6 ++++++ 3 files changed, 35 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a9cae52..80bdf99 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -908,6 +908,7 @@ virNodeDeviceObjUnlock; # nodeinfo.h nodeCapsInitNUMA; nodeGetCPUBitmap; +nodeGetCPUMap; nodeGetCPUStats; nodeGetCellsFreeMemory; nodeGetFreeMemory; diff --git a/src/nodeinfo.c b/src/nodeinfo.c index 461b5dc..8b494df 100644 --- a/src/nodeinfo.c +++ b/src/nodeinfo.c @@ -1249,6 +1249,34 @@ nodeGetMemoryParameters(virConnectPtr conn ATTRIBUTE_UNUSED, #endif } +int nodeGetCPUMap(virConnectPtr conn, + unsigned char **cpumap, + unsigned int *online, + unsigned int flags) +{ + virBitmapPtr cpus = NULL; + int maxpresent; + int ret = -1; + int dummy; + + virCheckFlags(0, -1); + + if (!(cpus = nodeGetCPUBitmap(conn, &maxpresent))) + goto cleanup; + + if (cpumap && virBitmapToData(cpus, cpumap, &dummy) < 0) + goto cleanup; + if (online) + *online = virBitmapCountBits(cpus); + + ret = maxpresent; +cleanup: + if (ret < 0 && cpumap) + VIR_FREE(*cpumap); + virBitmapFree(cpus); + return ret; +} + #if HAVE_NUMACTL # if LIBNUMA_API_VERSION <= 1 # define NUMA_MAX_N_CPUS 4096 diff --git a/src/nodeinfo.h b/src/nodeinfo.h index 73c6f51..44aa55d 100644 --- a/src/nodeinfo.h +++ b/src/nodeinfo.h @@ -58,4 +58,10 @@ int nodeSetMemoryParameters(virConnectPtr conn, virTypedParameterPtr params, int nparams, unsigned int flags); + +int nodeGetCPUMap(virConnectPtr conn, + unsigned char **cpumap, + unsigned int *online, + unsigned int flags); + #endif /* __VIR_NODEINFO_H__*/ -- 1.7.11.7

On 10/25/2012 03:49 AM, Eric Blake wrote:
+int nodeGetCPUMap(virConnectPtr conn, + unsigned char **cpumap, + unsigned int *online, + unsigned int flags) +{ + virBitmapPtr cpus = NULL; + int maxpresent; + int ret = -1; + int dummy; + + virCheckFlags(0, -1); + + if (!(cpus = nodeGetCPUBitmap(conn, &maxpresent))) + goto cleanup; + + if (cpumap && virBitmapToData(cpus, cpumap, &dummy) < 0) + goto cleanup; + if (online) + *online = virBitmapCountBits(cpus);
Much nicer now. Tested-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> -- Mit freundlichen Grüßen/Kind Regards Viktor Mihajlovski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martin Jetter Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

From: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> Driver support added for: - test, pretending 8 host CPUS, 3 being online - qemu, lxc, ..., using nodeGetCPUMap Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> --- src/lxc/lxc_driver.c | 1 + src/openvz/openvz_driver.c | 1 + src/qemu/qemu_driver.c | 1 + src/test/test_driver.c | 31 +++++++++++++++++++++++++++++++ src/uml/uml_driver.c | 1 + 5 files changed, 35 insertions(+) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 87305db..2072f00 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2736,6 +2736,7 @@ static virDriver lxcDriver = { .nodeGetMemoryStats = nodeGetMemoryStats, /* 0.9.3 */ .nodeGetCellsFreeMemory = nodeGetCellsFreeMemory, /* 0.6.5 */ .nodeGetFreeMemory = nodeGetFreeMemory, /* 0.6.5 */ + .nodeGetCPUMap = nodeGetCPUMap, /* 1.0.0 */ .domainEventRegister = lxcDomainEventRegister, /* 0.7.0 */ .domainEventDeregister = lxcDomainEventDeregister, /* 0.7.0 */ .isEncrypted = lxcIsEncrypted, /* 0.7.3 */ diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 2f51c1c..fb3c552 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -2127,6 +2127,7 @@ static virDriver openvzDriver = { .nodeGetMemoryStats = nodeGetMemoryStats, /* 0.9.12 */ .nodeGetCellsFreeMemory = nodeGetCellsFreeMemory, /* 0.9.12 */ .nodeGetFreeMemory = nodeGetFreeMemory, /* 0.9.12 */ + .nodeGetCPUMap = nodeGetCPUMap, /* 1.0.0 */ .getCapabilities = openvzGetCapabilities, /* 0.4.6 */ .listDomains = openvzListDomains, /* 0.3.1 */ .numOfDomains = openvzNumDomains, /* 0.3.1 */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 57e6403..18be7d9 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -14203,6 +14203,7 @@ static virDriver qemuDriver = { .domainGetCPUStats = qemuDomainGetCPUStats, /* 0.9.11 */ .nodeGetMemoryParameters = nodeGetMemoryParameters, /* 0.10.2 */ .nodeSetMemoryParameters = nodeSetMemoryParameters, /* 0.10.2 */ + .nodeGetCPUMap = nodeGetCPUMap, /* 1.0.0 */ }; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index c9f9115..58c4e67 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -5687,6 +5687,36 @@ static int testListAllDomains(virConnectPtr conn, return ret; } +static int +testNodeGetCPUMap(virConnectPtr conn, + unsigned char **cpumap, + unsigned int *online, + unsigned int flags) +{ + testConnPtr privconn = conn->privateData; + int ret = -1; + + virCheckFlags(0, -1); + + testDriverLock(privconn); + if (cpumap) { + if (VIR_ALLOC_N(*cpumap, 1) < 0) { + virReportOOMError(); + goto cleanup; + } + *cpumap[0] = 0x15; + } + + if (online) + *online = 3; + + ret = 8; + +cleanup: + testDriverUnlock(privconn); + return ret; +} + static virDriver testDriver = { .no = VIR_DRV_TEST, @@ -5756,6 +5786,7 @@ static virDriver testDriver = { .domainEventRegisterAny = testDomainEventRegisterAny, /* 0.8.0 */ .domainEventDeregisterAny = testDomainEventDeregisterAny, /* 0.8.0 */ .isAlive = testIsAlive, /* 0.9.8 */ + .nodeGetCPUMap = testNodeGetCPUMap, /* 1.0.0 */ }; static virNetworkDriver testNetworkDriver = { diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index ba37eb7..2c6e820 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -2612,6 +2612,7 @@ static virDriver umlDriver = { .nodeGetMemoryStats = nodeGetMemoryStats, /* 0.9.3 */ .nodeGetCellsFreeMemory = nodeGetCellsFreeMemory, /* 0.5.0 */ .nodeGetFreeMemory = nodeGetFreeMemory, /* 0.5.0 */ + .nodeGetCPUMap = nodeGetCPUMap, /* 1.0.0 */ .domainEventRegister = umlDomainEventRegister, /* 0.9.4 */ .domainEventDeregister = umlDomainEventDeregister, /* 0.9.4 */ .isEncrypted = umlIsEncrypted, /* 0.7.3 */ -- 1.7.11.7

On 10/25/2012 03:49 AM, Eric Blake wrote:
From: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
Driver support added for: - test, pretending 8 host CPUS, 3 being online - qemu, lxc, ..., using nodeGetCPUMap
Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> --- src/lxc/lxc_driver.c | 1 + src/openvz/openvz_driver.c | 1 + src/qemu/qemu_driver.c | 1 + src/test/test_driver.c | 31 +++++++++++++++++++++++++++++++ src/uml/uml_driver.c | 1 + 5 files changed, 35 insertions(+)
Looks good, I have tested qemu and test drivers. -- Mit freundlichen Grüßen/Kind Regards Viktor Mihajlovski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martin Jetter Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294
participants (2)
-
Eric Blake
-
Viktor Mihajlovski