Commit b9c14a09 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

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: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent a0497682
...@@ -671,6 +671,23 @@ static int check_aio_remap(void) ...@@ -671,6 +671,23 @@ static int check_aio_remap(void)
return 0; 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); static int (*chk_feature)(void);
int cr_check(void) int cr_check(void)
...@@ -723,6 +740,7 @@ int cr_check(void) ...@@ -723,6 +740,7 @@ int cr_check(void)
ret |= check_timerfd(); ret |= check_timerfd();
ret |= check_mnt_id(); ret |= check_mnt_id();
ret |= check_aio_remap(); ret |= check_aio_remap();
ret |= check_fdinfo_lock();
out: out:
if (!ret) if (!ret)
...@@ -774,6 +792,8 @@ int check_add_feature(char *feat) ...@@ -774,6 +792,8 @@ int check_add_feature(char *feat)
chk_feature = check_tun; chk_feature = check_tun;
else if (!strcmp(feat, "userns")) else if (!strcmp(feat, "userns"))
chk_feature = check_userns; chk_feature = check_userns;
else if (!strcmp(feat, "fdinfo_lock"))
chk_feature = check_fdinfo_lock;
else { else {
pr_err("Unknown feature %s\n", feat); pr_err("Unknown feature %s\n", feat);
return -1; return -1;
......
...@@ -13,6 +13,7 @@ struct stat; ...@@ -13,6 +13,7 @@ struct stat;
extern int kerndat_init(void); extern int kerndat_init(void);
extern int kerndat_init_rst(void); extern int kerndat_init_rst(void);
extern int kerndat_get_dirty_track(void); extern int kerndat_get_dirty_track(void);
extern int kerndat_fdinfo_has_lock(void);
struct kerndat_s { struct kerndat_s {
dev_t shmem_dev; dev_t shmem_dev;
...@@ -21,6 +22,7 @@ struct kerndat_s { ...@@ -21,6 +22,7 @@ struct kerndat_s {
u64 zero_page_pfn; u64 zero_page_pfn;
bool has_dirty_track; bool has_dirty_track;
bool has_memfd; bool has_memfd;
bool has_fdinfo_lock;
}; };
extern struct kerndat_s kdat; extern struct kerndat_s kdat;
......
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <sys/file.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/mman.h> #include <sys/mman.h>
...@@ -273,6 +274,42 @@ static bool kerndat_has_memfd_create(void) ...@@ -273,6 +274,42 @@ static bool kerndat_has_memfd_create(void)
return 0; 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 kerndat_init(void)
{ {
int ret; int ret;
...@@ -284,6 +321,8 @@ int kerndat_init(void) ...@@ -284,6 +321,8 @@ int kerndat_init(void)
ret = init_zero_page_pfn(); ret = init_zero_page_pfn();
if (!ret) if (!ret)
ret = get_last_cap(); ret = get_last_cap();
if (!ret)
ret = kerndat_fdinfo_has_lock();
return ret; return ret;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment