[CRIU] [PATCH 1/2] kerndat: check the lock field in fdinfo

Andrey Vagin avagin at openvz.org
Mon Apr 20 07:41:39 PDT 2015


Starting with the 4.1 kernel, fdinfo contains information about file
locks.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-check.c        | 20 ++++++++++++++++++++
 include/kerndat.h |  2 ++
 kerndat.c         | 39 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+)

diff --git a/cr-check.c b/cr-check.c
index 3518773..d21c0e8 100644
--- a/cr-check.c
+++ b/cr-check.c
@@ -671,6 +671,23 @@ static int check_aio_remap(void)
 	return 0;
 }
 
+static int check_fdinfo_lock(void)
+{
+	if (kerndat_fdinfo_has_lock())
+		return -1;
+
+	if (!kdat.has_lock) {
+		if (!opts.check_ms_kernel) {
+			pr_err("fdinfo doesn't contain the lock field\n");
+			return -1;
+		} else {
+			pr_warn("fdinfo doesn't contain the lock field\n");
+		}
+	}
+
+	return 0;
+}
+
 static int (*chk_feature)(void);
 
 int cr_check(void)
@@ -723,6 +740,7 @@ int cr_check(void)
 	ret |= check_timerfd();
 	ret |= check_mnt_id();
 	ret |= check_aio_remap();
+	ret |= check_fdinfo_lock();
 
 out:
 	if (!ret)
@@ -774,6 +792,8 @@ int check_add_feature(char *feat)
 		chk_feature = check_tun;
 	else if (!strcmp(feat, "userns"))
 		chk_feature = check_userns;
+	else if (!strcmp(feat, "lock"))
+		chk_feature = check_fdinfo_lock;
 	else {
 		pr_err("Unknown feature %s\n", feat);
 		return -1;
diff --git a/include/kerndat.h b/include/kerndat.h
index 12517d1..2134bb2 100644
--- a/include/kerndat.h
+++ b/include/kerndat.h
@@ -13,6 +13,7 @@ struct stat;
 extern int kerndat_init(void);
 extern int kerndat_init_rst(void);
 extern int kerndat_get_dirty_track(void);
+extern int kerndat_fdinfo_has_lock(void);
 
 struct kerndat_s {
 	dev_t shmem_dev;
@@ -21,6 +22,7 @@ struct kerndat_s {
 	u64 zero_page_pfn;
 	bool has_dirty_track;
 	bool has_memfd;
+	bool has_lock;
 };
 
 extern struct kerndat_s kdat;
diff --git a/kerndat.c b/kerndat.c
index 63a3da5..985a5d0 100644
--- a/kerndat.c
+++ b/kerndat.c
@@ -1,6 +1,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <stdio.h>
+#include <sys/file.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/mman.h>
@@ -273,6 +274,42 @@ static bool kerndat_has_memfd_create(void)
 	return 0;
 }
 
+int kerndat_fdinfo_has_lock()
+{
+	int fd, pfd = -1, exit_code = -1, len;
+	char buf[PAGE_SIZE];
+
+	fd = open("/proc/locks", O_RDONLY);
+	if (fd < 0) {
+		pr_perror("Unable to open /proc/locks");
+		return -1;
+	}
+
+	if (flock(fd, LOCK_SH)) {
+		pr_perror("Can't take a lock\n");
+		return -1;
+	}
+
+	pfd = open_proc(PROC_SELF, "fdinfo/%d", fd);
+	if (pfd < 0)
+		goto out;
+
+	len = read(pfd, buf, sizeof(buf));
+	if (len < 0) {
+		pr_perror("Unable to read");
+		goto out;
+	}
+
+	kdat.has_lock = (strstr(buf, "lock:") != NULL);
+
+	exit_code = 0;
+out:
+	close(pfd);
+	close(fd);
+
+	return exit_code;
+}
+
 int kerndat_init(void)
 {
 	int ret;
@@ -284,6 +321,8 @@ int kerndat_init(void)
 		ret = init_zero_page_pfn();
 	if (!ret)
 		ret = get_last_cap();
+	if (!ret)
+		ret = kerndat_fdinfo_has_lock();
 
 	return ret;
 }
-- 
2.1.0



More information about the CRIU mailing list