From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> add virBitmapParseCommaSeparetedFormat() for parsing bitmap in comma separeted ascii format. This format of bitmap is used in Linux sysfs and cpuset. Changelog: - fixed typos. - fixed string scan routine. Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxx> --- src/libvirt_private.syms | 2 + src/nodeinfo.c | 51 ++++++++++++++++++++++++++++++++++++ src/nodeinfo.h | 4 +++ src/util/bitmap.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++ src/util/bitmap.h | 6 +++- 5 files changed, 127 insertions(+), 1 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d6ad36c..14b144f 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -17,6 +17,7 @@ virBitmapFree; virBitmapGetBit; virBitmapSetBit; virBitmapString; +virBitmapParseCommaSeparatedFormat; # buf.h @@ -797,6 +798,7 @@ nodeGetCellsFreeMemory; nodeGetFreeMemory; nodeGetInfo; nodeGetMemoryStats; +nodeGetCPUmap; # nwfilter_conf.h diff --git a/src/nodeinfo.c b/src/nodeinfo.c index e0b66f7..b0ebb88 100644 --- a/src/nodeinfo.c +++ b/src/nodeinfo.c @@ -47,6 +47,7 @@ #include "count-one-bits.h" #include "intprops.h" #include "virfile.h" +#include "bitmap.h" #define VIR_FROM_THIS VIR_FROM_NONE @@ -569,6 +570,33 @@ int linuxNodeGetMemoryStats(FILE *meminfo, cleanup: 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 functin parses + * it and returns bitmap. + */ +static virBitmapPtr linuxParseCPUmap(int *max_cpuid, const char *path) +{ + char str[1024]; + FILE *fp; + virBitmapPtr map = NULL; + + fp = fopen(path, "r"); + if (!fp) { + virReportSystemError(errno, _("cannot open %s"), path); + goto cleanup; + } + if (fgets(str, sizeof(str), fp) == NULL) { + virReportSystemError(errno, _("cannot read from %s"), path); + goto cleanup; + } + map = virBitmapParseCommaSeparatedFormat(str, max_cpuid); + +cleanup: + VIR_FORCE_FCLOSE(fp); + return map; +} #endif int nodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED, virNodeInfoPtr nodeinfo) { @@ -712,6 +740,29 @@ int nodeGetMemoryStats(virConnectPtr conn ATTRIBUTE_UNUSED, #endif } +virBitmapPtr nodeGetCPUmap(virConnectPtr conn ATTRIBUTE_UNUSED, + int *max_id, + const char *mapname) +{ +#ifdef __linux__ + char *path; + virBitmapPtr map; + + if (virAsprintf(&path, CPU_SYS_PATH "/%s", mapname) < 0) { + virReportOOMError(); + return NULL; + } + + map = linuxParseCPUmap(max_id, path); + VIR_FREE(path); + return map; +#else + nodeReportError(VIR_ERR_NO_SUPPORT, "%s", + _("node cpumap not implemented on this platform")); + return -1; +#endif +} + #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 4766152..7f26b77 100644 --- a/src/nodeinfo.h +++ b/src/nodeinfo.h @@ -26,6 +26,7 @@ # include "libvirt/libvirt.h" # include "capabilities.h" +# include "bitmap.h" int nodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo); int nodeCapsInitNUMA(virCapsPtr caps); @@ -46,4 +47,7 @@ int nodeGetCellsFreeMemory(virConnectPtr conn, int maxCells); unsigned long long nodeGetFreeMemory(virConnectPtr conn); +virBitmapPtr nodeGetCPUmap(virConnectPtr conn, + int *max_id, + const char *mapname); #endif /* __VIR_NODEINFO_H__*/ diff --git a/src/util/bitmap.c b/src/util/bitmap.c index 8c326c4..6dead3b 100644 --- a/src/util/bitmap.c +++ b/src/util/bitmap.c @@ -33,6 +33,11 @@ #include "bitmap.h" #include "memory.h" #include "buf.h" +#include "c-ctype.h" +#include "util.h" +#include "virterror_internal.h" + +#define VIR_FROM_THIS VIR_FROM_NONE struct _virBitmap { @@ -180,3 +185,63 @@ char *virBitmapString(virBitmapPtr bitmap) return virBufferContentAndReset(&buf); } + +/** + * virBitmapParseCommaSeparatedFormat: + * + * When bitmap is printed in ascii format, especially in Linux, + * comma-separated format is sometimes used. For example, a bitmap 11111011 is + * represetned as 0-4,6-7. This function parses comma-separated format + * and returns virBitmap. Found max bit is returned, too. + * + * This functions stops if characters other than digits, ',', '-' are + * found. This function will be useful for parsing linux's bitmap. + */ +virBitmapPtr virBitmapParseCommaSeparatedFormat(char *buf, int *max_bit) +{ + char *pos = buf; + virBitmapPtr map = NULL; + int val, x; + + /* at first, find the highest number */ + val = 0; + while ((*pos != '\n') && (*pos != 0)) { + if (c_isdigit(*pos)) { + virStrToLong_i(pos, &pos, 10, &val); + } else if ((*pos == ',') || (*pos == '-')) { + ++pos; + } else + break; + } + *max_bit = val; + + map = virBitmapAlloc(val + 1); + if (map == NULL) { /* we may return NULL at failure of parsing */ + virReportOOMError(); + return NULL; + } + + pos = buf; + while ((*pos != '\n') && (*pos != 0)) { + if (c_isdigit(*pos)) { + virStrToLong_i(pos, &pos, 10, &val); + if (virBitmapSetBit(map, val) < 0) + goto failed; + } else if (*pos == ',') { + ++pos; + } else if (*pos == '-') { + x = val; + pos++; + virStrToLong_i(pos, &pos, 10, &val); + for (;x <= val; ++x) { + if (virBitmapSetBit(map, x) < 0) + goto failed; + } + } else + break; + } + return map; +failed: + virBitmapFree(map); + return NULL; +} diff --git a/src/util/bitmap.h b/src/util/bitmap.h index ef62cca..e3d3e2b 100644 --- a/src/util/bitmap.h +++ b/src/util/bitmap.h @@ -61,5 +61,9 @@ int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result) char *virBitmapString(virBitmapPtr bitmap) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - +/* + * parese comma-separeted bitmap format and allocate virBitmap. + */ +virBitmapPtr virBitmapParseCommaSeparatedFormat(char *buf, int *max_bit) + ATTRIBUTE_RETURN_CHECK; #endif -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list