From: KAMEZAWA Hiroyuki <kamezawa.hiroyu(a)jp.fujitsu.com>
Changelog:
- fixed typos.
- fixed string scan routine.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu(a)jp.fujitsu.com>
Signed-off-by: Lai Jiangshan <laijs(a)cn.fujitsu.com>
---
src/libvirt_private.syms | 1 +
src/nodeinfo.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++
src/nodeinfo.h | 3 +
3 files changed, 96 insertions(+), 0 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0c22dec..6e99243 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -792,6 +792,7 @@ virNodeDeviceObjUnlock;
# nodeinfo.h
nodeCapsInitNUMA;
+nodeGetCPUmap;
nodeGetCPUStats;
nodeGetCellsFreeMemory;
nodeGetFreeMemory;
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
index e0b66f7..fc1aaea 100644
--- a/src/nodeinfo.c
+++ b/src/nodeinfo.c
@@ -31,6 +31,7 @@
#include <dirent.h>
#include <sys/utsname.h>
#include <sched.h>
+#include <conf/domain_conf.h>
#if HAVE_NUMACTL
# define NUMA_VERSION1_COMPATIBILITY 1
@@ -569,6 +570,73 @@ 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 function parses
+ * it and returns cpumap.
+ */
+static const char *
+linuxParseCPUmap(int *max_cpuid, const char *path)
+{
+ FILE *fp;
+ char *map = NULL;
+ char *str = NULL;
+ size_t size = 128, pos = 0;
+ int max_id, i;
+
+ fp = fopen(path, "r");
+ if (!fp) {
+ virReportSystemError(errno, _("cannot open %s"), path);
+ goto error;
+ }
+
+ if (VIR_ALLOC_N(str, size) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ for (;;) {
+ pos += fread(str + pos, 1, size - pos, fp);
+ if (pos < size)
+ break;
+
+ size = size << 1;
+ if (VIR_REALLOC_N(str, size) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ }
+ if (pos == 0) {
+ virReportSystemError(errno, _("cannot read from %s"), path);
+ goto error;
+ }
+ str[pos - 1] = 0;
+
+ if (VIR_ALLOC_N(map, VIR_DOMAIN_CPUMASK_LEN) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ if (virDomainCpuSetParse(str, 0, map,
+ VIR_DOMAIN_CPUMASK_LEN) < 0) {
+ goto error;
+ }
+
+ for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; i++) {
+ if (map[i]) {
+ max_id = i;
+ }
+ }
+ *max_cpuid = max_id;
+
+ VIR_FORCE_FCLOSE(fp);
+ return map;
+
+error:
+ VIR_FORCE_FCLOSE(fp);
+ VIR_FREE(str);
+ VIR_FREE(map);
+ return NULL;
+}
#endif
int nodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED, virNodeInfoPtr nodeinfo) {
@@ -712,6 +780,30 @@ int nodeGetMemoryStats(virConnectPtr conn ATTRIBUTE_UNUSED,
#endif
}
+const char *
+nodeGetCPUmap(virConnectPtr conn ATTRIBUTE_UNUSED,
+ int *max_id ATTRIBUTE_UNUSED,
+ const char *mapname ATTRIBUTE_UNUSED)
+{
+#ifdef __linux__
+ char *path;
+ const char *cpumap;
+
+ if (virAsprintf(&path, CPU_SYS_PATH "/%s", mapname) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ cpumap = linuxParseCPUmap(max_id, path);
+ VIR_FREE(path);
+ return cpumap;
+#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..852e19d 100644
--- a/src/nodeinfo.h
+++ b/src/nodeinfo.h
@@ -46,4 +46,7 @@ int nodeGetCellsFreeMemory(virConnectPtr conn,
int maxCells);
unsigned long long nodeGetFreeMemory(virConnectPtr conn);
+const char *nodeGetCPUmap(virConnectPtr conn,
+ int *max_id,
+ const char *mapname);
#endif /* __VIR_NODEINFO_H__*/
--
1.7.4.4