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(a)redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
--
Thanks,
Hu Tao