[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