diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile index ab45b580af..20e4bc2721 100644 --- a/test/zdtm/static/Makefile +++ b/test/zdtm/static/Makefile @@ -54,6 +54,7 @@ TST_NOFILE := \ shm-mp \ ptrace_sig \ pidfd_self \ + pidfd_dead \ pidfd_child \ pidfd_kill \ pipe00 \ diff --git a/test/zdtm/static/pidfd_dead.c b/test/zdtm/static/pidfd_dead.c new file mode 100644 index 0000000000..8df245de65 --- /dev/null +++ b/test/zdtm/static/pidfd_dead.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "zdtmtst.h" + +const char *test_doc = "Check C/R of pidfds that point to dead processes\n"; +const char *test_author = "Bhavik Sachdev "; + +static int pidfd_open(pid_t pid, unsigned int flags) +{ + return syscall(SYS_pidfd_open, pid, flags); +} + +static int pidfd_send_signal(int pidfd, int sig, siginfo_t* info, unsigned int flags) +{ + return syscall(SYS_pidfd_send_signal, pidfd, sig, info, flags); +} + +static struct utsname buf; + +int main(int argc, char* argv[]) +{ + int child, ret; + int pidfd_one, pidfd_two; + unsigned major, minor; + struct statx stat_one, stat_two; + + test_init(argc, argv); + + ret = uname(&buf); + if (ret) + return 1; + + if (sscanf(buf.release, "%u.%u", &major, &minor) != 2) + return 1; + + if ((major < 6) || (minor < 9)) { + test_msg("statx on pidfd is only supported on 6.9 and above..\n"); + test_daemon(); + test_waitsig(); + pass(); + return 0; + } + + child = fork(); + if (child < 0) { + pr_perror("fork"); + return 1; + } else if (child == 0) { + while(1); + } + + pidfd_one = pidfd_open(child, 0); + if (pidfd_one < 0) { + pr_perror("pidfd_open"); + return 1; + } + + pidfd_two = pidfd_open(child, 0); + if (pidfd_two < 0) { + pr_perror("pidfd_open"); + return 1; + } + + if (pidfd_send_signal(pidfd_one, SIGKILL, NULL, 0)) { + pr_perror("pidfd_send_signal"); + return 1; + } + wait(NULL); + + test_daemon(); + test_waitsig(); + + /* + * After linux 6.9 we can compare inode numbers + * to determine if two pidfds point to the same process. + * While the inode number may change before and after C/R + * pidfds pointing to the same pid should have the same inode number. + */ + statx(pidfd_one, "", AT_EMPTY_PATH, STATX_ALL, &stat_one); + statx(pidfd_two, "", AT_EMPTY_PATH, STATX_ALL, &stat_two); + if (stat_one.stx_ino == stat_two.stx_ino) + pass(); + else + fail(); + + return 0; +}