[libvirt] [PATCH 1/3 V6] add nodeGetCPUmap() for getting available CPU IDs in a cpumap.

Lai Jiangshan laijs at cn.fujitsu.com
Thu Feb 16 07:15:07 UTC 2012


From: KAMEZAWA Hiroyuki <kamezawa.hiroyu at jp.fujitsu.com>

Changelog:
 - fixed typos.
 - fixed string scan routine.

Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu at jp.fujitsu.com>
Signed-off-by: Lai Jiangshan <laijs at 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




More information about the libvir-list mailing list