2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-30 13:58:34 +00:00

kerndat: check the lock field in fdinfo (v2)

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

v2: s/has_lock/has_fdinfo_lock/
Signed-off-by: Andrey Vagin <avagin@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
Andrey Vagin
2015-04-24 14:49:14 +03:00
committed by Pavel Emelyanov
parent a049768242
commit b9c14a09b0
3 changed files with 61 additions and 0 deletions

View File

@@ -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_fdinfo_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, "fdinfo_lock"))
chk_feature = check_fdinfo_lock;
else {
pr_err("Unknown feature %s\n", feat);
return -1;

View File

@@ -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_fdinfo_lock;
};
extern struct kerndat_s kdat;

View File

@@ -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_fdinfo_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;
}