On Sat, Jan 28, 2012 at 03:24:04PM +0900, KAMEZAWA Hiroyuki wrote: > add nodeGetCPUmap() for getting available CPU IDs in a bitmap. > add virBitmapParseCommaSeparetedFormat() for parsing bitmap in > comma separeted ascii format. This format of bitmap is used in Linux > sysfs and cpuset. > > * cpuacct's percpu usage information is provided based on > /sys/devices/system/cpu/present cpu map. > So, this kind of call is required. This routine itself may be > useful for other purpose. > > libvirt_private.syms | 2 + > nodeinfo.c | 51 ++++++++++++++++++++++++++++++++++++++++ > nodeinfo.h | 4 +++ > util/bitmap.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++ > util/bitmap.h | 6 +++- > 5 files changed, 127 insertions(+), 1 deletion(-) > --- > 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 915a43f..fd44322 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -17,6 +17,7 @@ virBitmapFree; > virBitmapGetBit; > virBitmapSetBit; > virBitmapString; > +virBitmapParseCommaSeparatedFormat; > > > # buf.h > @@ -800,6 +801,7 @@ nodeGetCellsFreeMemory; > nodeGetFreeMemory; > nodeGetInfo; > nodeGetMemoryStats; > +nodeGetCPUmap; > > > # nwfilter_conf.h > diff --git a/src/nodeinfo.c b/src/nodeinfo.c > index e0b66f7..92bada7 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 parse > + * 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..c7e1a81 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, expecially in Linux, s/expecially/especially/ > + * comma-separated format is sometimes used. For example, a bitmap 11111011 is > + * represetned as 0-4,6-7. This function parse comma-separated format s/parse/parses/ > + * and returns virBitmap. Found max bit is returend, too. s/returend/returned/ > + * > + * 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)) { (*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)) { (*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.1 > > > -- > libvir-list mailing list > libvir-list@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/libvir-list -- Thanks, Hu Tao -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list