[CRIU] [PATCH 3/4] kdat: Add fetching files stat

Cyrill Gorcunov gorcunov at openvz.org
Tue May 30 11:13:32 PDT 2017


Will need it to unlimit the files allocation
for service fd reserving and later for parasite code run
(which is implemented in vz7 instance and soon will be
ported into vanilla).

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 criu/include/kerndat.h |  4 +++
 criu/kerndat.c         | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+)

diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h
index da184c0542a2..2dcfd0eb75a6 100644
--- a/criu/include/kerndat.h
+++ b/criu/include/kerndat.h
@@ -1,6 +1,7 @@
 #ifndef __CR_KERNDAT_H__
 #define __CR_KERNDAT_H__
 
+#include <stdbool.h>
 #include "int.h"
 
 struct stat;
@@ -14,6 +15,7 @@ extern int kerndat_init(void);
 extern int kerndat_get_dirty_track(void);
 extern int kerndat_fdinfo_has_lock(void);
 extern int kerndat_loginuid(void);
+extern int kerndat_files_stat(bool early);
 
 enum pagemap_func {
 	PM_UNKNOWN,
@@ -52,6 +54,8 @@ struct kerndat_s {
 	bool has_nspid;
 	bool has_ns_get_userns;
 	bool has_ns_get_parent;
+	unsigned int sysctl_nr_open;
+	unsigned long files_stat_max_files;
 };
 
 extern struct kerndat_s kdat;
diff --git a/criu/kerndat.c b/criu/kerndat.c
index 3204d4bc1d12..c37c2f1d30db 100644
--- a/criu/kerndat.c
+++ b/criu/kerndat.c
@@ -149,6 +149,74 @@ static void kerndat_mmap_min_addr(void)
 		 (unsigned long)kdat.mmap_min_addr);
 }
 
+int kerndat_files_stat(bool early)
+{
+	static const uint32_t NR_OPEN_DEFAULT = 1024 * 1024;
+	static const uint64_t MAX_FILES_DEFAULT = 8192;
+	uint64_t max_files;
+	uint32_t nr_open;
+
+	struct sysctl_req req[] = {
+		{
+			.name	= "fs/file-max",
+			.arg	= &max_files,
+			.type	= CTL_U64,
+		},
+		{
+			.name	= "fs/nr_open",
+			.arg	= &nr_open,
+			.type	= CTL_U32,
+		},
+	};
+
+	if (!early) {
+		if (sysctl_op(req, ARRAY_SIZE(req), CTL_READ, 0)) {
+			pr_warn("Can't fetch file_stat, using kernel defaults\n");
+			nr_open = NR_OPEN_DEFAULT;
+			max_files = MAX_FILES_DEFAULT;
+		}
+	} else {
+		char buf[64];
+		int fd1, fd2;
+		ssize_t ret;
+
+		fd1 = open("/proc/sys/fs/file-max", O_RDONLY);
+		fd2 = open("/proc/sys/fs/nr_open", O_RDONLY);
+
+		nr_open = NR_OPEN_DEFAULT;
+		max_files = MAX_FILES_DEFAULT;
+
+		if (fd1 < 0 || fd2 < 0) {
+			pr_warn("Can't fetch file_stat, using kernel defaults\n");
+		} else {
+			ret = read(fd1, buf, sizeof(buf) - 1);
+			if (ret > 0) {
+				buf[ret] = '\0';
+				max_files = atol(buf);
+			}
+			ret = read(fd2, buf, sizeof(buf));
+			if (ret > 0) {
+				buf[ret] = '\0';
+				nr_open = atol(buf);
+			}
+		}
+
+		if (fd1 >= 0)
+			close(fd1);
+		if (fd2 >= 0)
+			close(fd2);
+	}
+
+	kdat.sysctl_nr_open = nr_open;
+	kdat.files_stat_max_files = max_files;
+
+	pr_debug("files stat: %s %lu, %s %u\n",
+		 req[0].name, kdat.files_stat_max_files,
+		 req[1].name, kdat.sysctl_nr_open);
+
+	return 0;
+}
+
 static int kerndat_get_shmemdev(void)
 {
 	void *map;
@@ -823,6 +891,7 @@ int kerndat_init(void)
 
 	kerndat_lsm();
 	kerndat_mmap_min_addr();
+	kerndat_files_stat(false);
 
 	if (!ret)
 		kerndat_save_cache();
-- 
2.7.4



More information about the CRIU mailing list