2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-22 18:07:57 +00:00

util: use close_range when it's supported

close_range is faster than reading /proc/self/fd and closing descriptors
one by one.

Signed-off-by: Andrei Vagin <avagin@gmail.com>
This commit is contained in:
Andrei Vagin 2024-07-08 19:31:38 -07:00
parent 42b177da62
commit 4f45572fde
10 changed files with 48 additions and 0 deletions

View File

@ -118,6 +118,7 @@ fsopen 430 430 (char *fsname, unsigned int flags)
fsconfig 431 431 (int fd, unsigned int cmd, const char *key, const char *value, int aux) fsconfig 431 431 (int fd, unsigned int cmd, const char *key, const char *value, int aux)
fsmount 432 432 (int fd, unsigned int flags, unsigned int attr_flags) fsmount 432 432 (int fd, unsigned int flags, unsigned int attr_flags)
clone3 435 435 (struct clone_args *uargs, size_t size) clone3 435 435 (struct clone_args *uargs, size_t size)
close_range 436 436 (unsigned int fd, unsigned int max_fd, unsigned int flags)
pidfd_open 434 434 (pid_t pid, unsigned int flags) pidfd_open 434 434 (pid_t pid, unsigned int flags)
openat2 437 437 (int dirfd, char *pathname, struct open_how *how, size_t size) openat2 437 437 (int dirfd, char *pathname, struct open_how *how, size_t size)
pidfd_getfd 438 438 (int pidfd, int targetfd, unsigned int flags) pidfd_getfd 438 438 (int pidfd, int targetfd, unsigned int flags)

View File

@ -115,6 +115,7 @@ __NR_fsopen 5430 sys_fsopen (char *fsname, unsigned int flags)
__NR_fsconfig 5431 sys_fsconfig (int fd, unsigned int cmd, const char *key, const char *value, int aux) __NR_fsconfig 5431 sys_fsconfig (int fd, unsigned int cmd, const char *key, const char *value, int aux)
__NR_fsmount 5432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags) __NR_fsmount 5432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags)
__NR_clone3 5435 sys_clone3 (struct clone_args *uargs, size_t size) __NR_clone3 5435 sys_clone3 (struct clone_args *uargs, size_t size)
__NR_close_range 5436 sys_close_range (unsigned int fd, unsigned int max_fd, unsigned int flags)
__NR_pidfd_open 5434 sys_pidfd_open (pid_t pid, unsigned int flags) __NR_pidfd_open 5434 sys_pidfd_open (pid_t pid, unsigned int flags)
__NR_openat2 5437 sys_openat2 (int dirfd, char *pathname, struct open_how *how, size_t size) __NR_openat2 5437 sys_openat2 (int dirfd, char *pathname, struct open_how *how, size_t size)
__NR_pidfd_getfd 5438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags) __NR_pidfd_getfd 5438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags)

View File

@ -114,6 +114,7 @@ __NR_fsopen 430 sys_fsopen (char *fsname, unsigned int flags)
__NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, const char *value, int aux) __NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, const char *value, int aux)
__NR_fsmount 432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags) __NR_fsmount 432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags)
__NR_clone3 435 sys_clone3 (struct clone_args *uargs, size_t size) __NR_clone3 435 sys_clone3 (struct clone_args *uargs, size_t size)
__NR_close_range 436 sys_close_range (unsigned int fd, unsigned int max_fd, unsigned int flags)
__NR_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags) __NR_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags)
__NR_openat2 437 sys_openat2 (int dirfd, char *pathname, struct open_how *how, size_t size) __NR_openat2 437 sys_openat2 (int dirfd, char *pathname, struct open_how *how, size_t size)
__NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags) __NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags)

View File

@ -114,6 +114,7 @@ __NR_fsopen 430 sys_fsopen (char *fsname, unsigned int flags)
__NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, const char *value, int aux) __NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, const char *value, int aux)
__NR_fsmount 432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags) __NR_fsmount 432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags)
__NR_clone3 435 sys_clone3 (struct clone_args *uargs, size_t size) __NR_clone3 435 sys_clone3 (struct clone_args *uargs, size_t size)
__NR_close_range 436 sys_close_range (unsigned int fd, unsigned int max_fd, unsigned int flags)
__NR_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags) __NR_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags)
__NR_openat2 437 sys_openat2 (int dirfd, char *pathname, struct open_how *how, size_t size) __NR_openat2 437 sys_openat2 (int dirfd, char *pathname, struct open_how *how, size_t size)
__NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags) __NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags)

View File

@ -102,6 +102,7 @@ __NR_fsopen 430 sys_fsopen (char *fsname, unsigned int flags)
__NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, const char *value, int aux) __NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, const char *value, int aux)
__NR_fsmount 432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags) __NR_fsmount 432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags)
__NR_clone3 435 sys_clone3 (struct clone_args *uargs, size_t size) __NR_clone3 435 sys_clone3 (struct clone_args *uargs, size_t size)
__NR_close_range 436 sys_close_range (unsigned int fd, unsigned int max_fd, unsigned int flags)
__NR_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags) __NR_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags)
__NR_openat2 437 sys_openat2 (int dirfd, char *pathname, struct open_how *how, size_t size) __NR_openat2 437 sys_openat2 (int dirfd, char *pathname, struct open_how *how, size_t size)
__NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags) __NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags)

View File

@ -113,6 +113,7 @@ __NR_fsopen 430 sys_fsopen (char *fsname, unsigned int flags)
__NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, const char *value, int aux) __NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, const char *value, int aux)
__NR_fsmount 432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags) __NR_fsmount 432 sys_fsmount (int fd, unsigned int flags, unsigned int attr_flags)
__NR_clone3 435 sys_clone3 (struct clone_args *uargs, size_t size) __NR_clone3 435 sys_clone3 (struct clone_args *uargs, size_t size)
__NR_close_range 436 sys_close_range (unsigned int fd, unsigned int max_fd, unsigned int flags)
__NR_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags) __NR_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags)
__NR_openat2 437 sys_openat2 (int dirfd, char *pathname, struct open_how *how, size_t size) __NR_openat2 437 sys_openat2 (int dirfd, char *pathname, struct open_how *how, size_t size)
__NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags) __NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags)

View File

@ -88,6 +88,7 @@ struct kerndat_s {
bool has_membarrier_get_registrations; bool has_membarrier_get_registrations;
bool has_pagemap_scan; bool has_pagemap_scan;
bool has_shstk; bool has_shstk;
bool has_close_range;
}; };
extern struct kerndat_s kdat; extern struct kerndat_s kdat;

View File

@ -411,4 +411,6 @@ extern void util_init(void);
extern char *resolve_mountpoint(char *path); extern char *resolve_mountpoint(char *path);
extern int cr_close_range(unsigned int fd, unsigned int max_fd, unsigned int flags);
#endif /* __CR_UTIL_H__ */ #endif /* __CR_UTIL_H__ */

View File

@ -1699,6 +1699,27 @@ static int kerndat_has_membarrier_get_registrations(void)
return 0; return 0;
} }
static int kerndat_has_close_range(void)
{
/* fd is greater than max_fd, so close_range should return EINVAL. */
if (cr_close_range(2, 1, 0) == 0) {
pr_err("close_range succeeded unexpectedly\n");
return -1;
}
if (errno == ENOSYS) {
pr_debug("close_range isn't supported\n");
return 0;
}
if (errno != EINVAL) {
pr_perror("close_range returned unexpected error code");
return -1;
}
kdat.has_close_range = true;
return 0;
}
/* /*
* Some features depend on resource that can be dynamically changed * Some features depend on resource that can be dynamically changed
* at the OS runtime. There are cases that we cannot determine the * at the OS runtime. There are cases that we cannot determine the
@ -1956,6 +1977,10 @@ int kerndat_init(void)
pr_err("kerndat_has_shstk failed when initializing kerndat.\n"); pr_err("kerndat_has_shstk failed when initializing kerndat.\n");
ret = -1; ret = -1;
} }
if (!ret && kerndat_has_close_range()) {
pr_err("kerndat_has_close_range has failed when initializing kerndat.\n");
ret = -1;
}
kerndat_lsm(); kerndat_lsm();
kerndat_mmap_min_addr(); kerndat_mmap_min_addr();

View File

@ -54,6 +54,7 @@
#include "action-scripts.h" #include "action-scripts.h"
#include "compel/infect-util.h" #include "compel/infect-util.h"
#include <compel/plugins/std/syscall-codes.h>
#define VMA_OPT_LEN 128 #define VMA_OPT_LEN 128
@ -518,12 +519,25 @@ int cr_system(int in, int out, int err, char *cmd, char *const argv[], unsigned
return cr_system_userns(in, out, err, cmd, argv, flags, -1); return cr_system_userns(in, out, err, cmd, argv, flags, -1);
} }
int cr_close_range(unsigned int fd, unsigned int max_fd, unsigned int flags)
{
return syscall(__NR_close_range, fd, max_fd, flags);
}
static int close_fds(int minfd) static int close_fds(int minfd)
{ {
DIR *dir; DIR *dir;
struct dirent *de; struct dirent *de;
int fd, ret, dfd; int fd, ret, dfd;
if (kdat.has_close_range) {
if (cr_close_range(minfd, ~0, 0)) {
pr_perror("close_range failed");
return -1;
}
return 0;
}
dir = opendir("/proc/self/fd"); dir = opendir("/proc/self/fd");
if (dir == NULL) { if (dir == NULL) {
pr_perror("Can't open /proc/self/fd"); pr_perror("Can't open /proc/self/fd");