[v2,1/4] kdat: Calculate number of possible cpus

Submitted by Kirill Tkhai on May 19, 2016, 1:11 p.m.

Details

Message ID 146366348430.28218.6337679623935313043.stgit@pro
State Rejected
Series "aio: Support two versions of io_setup()"
Headers show

Commit Message

Kirill Tkhai May 19, 2016, 1:11 p.m.
To determ io_setup() version we need to calculate number of possible cpus,
that is implemented in this patch.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/include/kerndat.h |    1 +
 criu/kerndat.c         |   76 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+)

Patch hide | download patch | download mbox

diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h
index 15f8622..8c1e585 100644
--- a/criu/include/kerndat.h
+++ b/criu/include/kerndat.h
@@ -33,6 +33,7 @@  struct kerndat_s {
 	unsigned long task_size;
 	bool ipv6;
 	bool has_loginuid;
+	unsigned nr_cpus_possible;
 	enum pagemap_func pmap;
 };
 
diff --git a/criu/kerndat.c b/criu/kerndat.c
index 8127b6e..83f812c 100644
--- a/criu/kerndat.c
+++ b/criu/kerndat.c
@@ -446,6 +446,78 @@  int kerndat_loginuid(bool only_dump)
 	return 0;
 }
 
+static int kerndat_possible_cpus(void)
+{
+	char buf[PAGE_SIZE + 1], *p;
+	int fd, count, ret = 0;
+
+	fd = open("/sys/devices/system/cpu/possible", O_RDONLY);
+	if (fd < 0) {
+		pr_perror("Possible cpus: open");
+		return -1;
+	}
+
+	count = read(fd, buf, PAGE_SIZE);
+	close(fd);
+	if (count <= 0) {
+		pr_perror("Can't read possible cpus");
+		return -1;
+	}
+	buf[count] = '\0';
+	if (count > 1 && buf[count-1] == '\n')
+		buf[--count] = '\0';
+	p = buf;
+
+	count = 0;
+	/* Content is like "0-2,4,6-7" */
+	while (p && *p != '\0') {
+		int a, b;
+		char del;
+
+		ret = sscanf(p, "%d%c", &a, &del);
+		if (ret < 1) {
+			ret = -1;
+			break;
+		} else if (ret == 1) {
+			ret = ++count;
+			break;
+		}
+
+		p = strchr(p, del);
+		p++;
+		if (del == ',') {
+			count++;
+			continue;
+		}
+		BUG_ON(del != '-');
+
+		if (sscanf(p, "%d", &b) != 1) {
+			ret = -1;
+			break;
+		}
+		BUG_ON(b <= a);
+		count += b - a + 1;
+
+		do {
+			b /= 10;
+			p++;
+		} while (b > 0);
+		p = strchr(p, ',');
+		if (p)
+			p++;
+	}
+
+	if (ret < 0)
+		pr_err("Can't parse: %s\n", buf);
+	else {
+		pr_info("nr_cpus_possible=%d\n", count);
+		kdat.nr_cpus_possible = count;
+		ret = 0;
+	}
+
+	return ret;
+}
+
 int kerndat_init(void)
 {
 	int ret;
@@ -467,6 +539,8 @@  int kerndat_init(void)
 		ret = get_ipv6();
 	if (!ret)
 		ret = kerndat_loginuid(true);
+	if (!ret)
+		ret = kerndat_possible_cpus();
 
 	kerndat_lsm();
 
@@ -494,6 +568,8 @@  int kerndat_init_rst(void)
 		ret = get_ipv6();
 	if (!ret)
 		ret = kerndat_loginuid(false);
+	if (!ret)
+		ret = kerndat_possible_cpus();
 
 	kerndat_lsm();