mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-18 00:58:31 +00:00
criu: check if pidfd_getfd syscall is supported
pidfd_getfd syscall will be needed later to send pidfds between pre-dump/dump iterations for pid reuse detection. v2: - check size written/read of val_a/val_b is correct - return with error when val_a != val_b Signed-off-by: Zeyad Yasser <zeyady98@gmail.com>
This commit is contained in:
parent
30e8d8cadf
commit
a9508c9864
8 changed files with 74 additions and 0 deletions
|
|
@ -117,3 +117,4 @@ fsconfig 431 431 (int fd, unsigned int cmd, const char *key, const char *value
|
|||
fsmount 432 432 (int fd, unsigned int flags, unsigned int attr_flags)
|
||||
clone3 435 435 (struct clone_args *uargs, size_t size)
|
||||
pidfd_open 434 434 (pid_t pid, unsigned int flags)
|
||||
pidfd_getfd 438 438 (int pidfd, int targetfd, unsigned int flags)
|
||||
|
|
|
|||
|
|
@ -114,3 +114,4 @@ __NR_fsconfig 5431 sys_fsconfig (int fd, unsigned int cmd, const char *key,
|
|||
__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_pidfd_open 5434 sys_pidfd_open (pid_t pid, unsigned int flags)
|
||||
__NR_pidfd_getfd 5438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags)
|
||||
|
|
|
|||
|
|
@ -113,3 +113,4 @@ __NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, co
|
|||
__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_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags)
|
||||
__NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags)
|
||||
|
|
|
|||
|
|
@ -113,3 +113,4 @@ __NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, co
|
|||
__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_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags)
|
||||
__NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags)
|
||||
|
|
|
|||
|
|
@ -101,3 +101,4 @@ __NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, co
|
|||
__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_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags)
|
||||
__NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags)
|
||||
|
|
|
|||
|
|
@ -112,3 +112,4 @@ __NR_fsconfig 431 sys_fsconfig (int fd, unsigned int cmd, const char *key, c
|
|||
__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_pidfd_open 434 sys_pidfd_open (pid_t pid, unsigned int flags)
|
||||
__NR_pidfd_getfd 438 sys_pidfd_getfd (int pidfd, int targetfd, unsigned int flags)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ struct kerndat_s {
|
|||
bool has_timens;
|
||||
bool has_newifindex;
|
||||
bool has_pidfd_open;
|
||||
bool has_pidfd_getfd;
|
||||
};
|
||||
|
||||
extern struct kerndat_s kdat;
|
||||
|
|
|
|||
|
|
@ -1068,6 +1068,69 @@ static void kerndat_has_pidfd_open(void)
|
|||
close_safe(&pidfd);
|
||||
}
|
||||
|
||||
static int kerndat_has_pidfd_getfd(void)
|
||||
{
|
||||
int ret;
|
||||
int fds[2];
|
||||
int val_a, val_b;
|
||||
int pidfd, stolen_fd;
|
||||
|
||||
ret = 0;
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds)) {
|
||||
pr_perror("Can't open unix socket pair");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
val_a = 1984;
|
||||
if (write(fds[0], &val_a, sizeof(val_a)) != sizeof(val_a)) {
|
||||
pr_perror("Can't write to socket");
|
||||
ret = -1;
|
||||
goto close_pair;
|
||||
}
|
||||
|
||||
pidfd = syscall(SYS_pidfd_open, getpid(), 0);
|
||||
if (pidfd == -1) {
|
||||
pr_warn("Can't get pidfd\n");
|
||||
/*
|
||||
* If pidfd_open is not supported then pidfd_getfd
|
||||
* will not be supported as well.
|
||||
*/
|
||||
kdat.has_pidfd_getfd = false;
|
||||
goto close_pair;
|
||||
}
|
||||
|
||||
stolen_fd = syscall(SYS_pidfd_getfd, pidfd, fds[1], 0);
|
||||
if (stolen_fd == -1) {
|
||||
kdat.has_pidfd_getfd = false;
|
||||
goto close_all;
|
||||
}
|
||||
|
||||
if (read(fds[1], &val_b, sizeof(val_b)) != sizeof(val_b)) {
|
||||
pr_perror("Can't read from socket");
|
||||
ret = -1;
|
||||
goto close_all;
|
||||
}
|
||||
|
||||
if (val_b == val_a) {
|
||||
kdat.has_pidfd_getfd = true;
|
||||
} else {
|
||||
/* If val_b != val_a then something unexpected happend. */
|
||||
pr_err("Unexpected value read from socket\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
close_all:
|
||||
close_safe(&stolen_fd);
|
||||
close_safe(&pidfd);
|
||||
close_pair:
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kerndat_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -1205,6 +1268,10 @@ int kerndat_init(void)
|
|||
pr_err("kerndat_has_newifindex failed when initializing kerndat.\n");
|
||||
ret = -1;
|
||||
}
|
||||
if (!ret && kerndat_has_pidfd_getfd()) {
|
||||
pr_err("kerndat_has_pidfd_getfd failed when initializing kerndat.\n");
|
||||
ret = -1;
|
||||
}
|
||||
if (!ret)
|
||||
kerndat_has_pidfd_open();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue