Skip to content

Commit f9fdfca

Browse files
bsach64avagin
authored andcommitted
zdtm: Check pidfd fdinfo entry is consistent
Ensures that entries in /proc/<pid>/fdinfo/<pidfd> are same. Signed-off-by: Bhavik Sachdev <[email protected]>
1 parent 99ec620 commit f9fdfca

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

test/zdtm/static/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ TST_NOFILE := \
5353
shm \
5454
shm-mp \
5555
ptrace_sig \
56+
pidfd_self \
5657
pipe00 \
5758
pipe01 \
5859
pipe02 \

test/zdtm/static/pidfd_self.c

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#include <sys/syscall.h>
2+
#include <signal.h>
3+
#include <unistd.h>
4+
5+
#include "zdtmtst.h"
6+
7+
const char *test_doc = "Check pidfd /proc/self/fdinfo/<pidfd> entry remains consistent after checkpoint/restore\n";
8+
const char *test_author = "Bhavik Sachdev <[email protected]>";
9+
10+
struct pidfd_status {
11+
unsigned int flags;
12+
pid_t pid;
13+
};
14+
15+
static int pidfd_open(pid_t pid, unsigned int flags)
16+
{
17+
return syscall(__NR_pidfd_open, pid, flags);
18+
}
19+
20+
static int pidfd_send_signal(int pidfd, int sig, siginfo_t* info, unsigned int flags)
21+
{
22+
return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags);
23+
}
24+
25+
static void show_pidfd(char *prefix, struct pidfd_status *s)
26+
{
27+
test_msg("\n\t%s\n\tflags: 0%o\n\tpid: %d\n", prefix, s->flags, s->pid);
28+
}
29+
30+
static int parse_self_fdinfo(int pidfd, struct pidfd_status *s)
31+
{
32+
char buf[256];
33+
int ret = -1;
34+
FILE *f;
35+
36+
sprintf(buf, "/proc/self/fdinfo/%d", pidfd);
37+
f = fopen(buf, "r");
38+
if (!f) {
39+
perror("Can't open /proc/self/fdinfo/ to parse");
40+
return -1;
41+
}
42+
43+
memset(s, 0, sizeof(*s));
44+
45+
/*
46+
* flags: file access mode (octal) 02000002 => [O_RDWR | O_CLOEXEC]
47+
* pid: the pid to which we have pidfd open
48+
*/
49+
while (fgets(buf, sizeof(buf), f)) {
50+
if (!fgets(buf, sizeof(buf), f))
51+
goto parse_err;
52+
53+
if (sscanf(buf, "flags: 0%o", &s->flags) != 1) {
54+
goto parse_err;
55+
}
56+
57+
if (!fgets(buf, sizeof(buf), f))
58+
goto parse_err;
59+
if (!fgets(buf, sizeof(buf), f))
60+
goto parse_err;
61+
62+
if (!fgets(buf, sizeof(buf), f))
63+
goto parse_err;
64+
65+
if (sscanf(buf, "Pid: %d", &s->pid) != 1)
66+
goto parse_err;
67+
ret = 0;
68+
break;
69+
}
70+
71+
if (ret)
72+
goto parse_err;
73+
err:
74+
fclose(f);
75+
return ret;
76+
77+
parse_err:
78+
pr_perror("Format error");
79+
goto err;
80+
}
81+
82+
static int check_pidfd(int fd, struct pidfd_status *old)
83+
{
84+
struct pidfd_status new;
85+
86+
if (parse_self_fdinfo(fd, &new))
87+
return -1;
88+
89+
show_pidfd("restored", &new);
90+
91+
if (old->flags != new.flags || old->pid != new.pid)
92+
return -1;
93+
94+
return 0;
95+
}
96+
97+
int main(int argc, char* argv[])
98+
{
99+
struct pidfd_status old;
100+
int pidfd, ret;
101+
102+
test_init(argc, argv);
103+
104+
pidfd = pidfd_open(getpid(), 0);
105+
if (pidfd < 0) {
106+
pr_perror("pidfd_open failed");
107+
return 1;
108+
}
109+
110+
parse_self_fdinfo(pidfd, &old);
111+
112+
show_pidfd("old", &old);
113+
114+
if (pidfd_send_signal(pidfd, 0, NULL, 0)) {
115+
pr_perror("Could not send signal");
116+
return 1;
117+
}
118+
119+
test_daemon();
120+
test_waitsig();
121+
122+
ret = check_pidfd(pidfd, &old);
123+
if (ret) {
124+
fail();
125+
goto err;
126+
}
127+
128+
if (pidfd_send_signal(pidfd, 0, NULL, 0)) {
129+
pr_perror("Could not send signal");
130+
fail();
131+
goto err;
132+
}
133+
134+
pass();
135+
close(pidfd);
136+
return 0;
137+
err:
138+
close(pidfd);
139+
return 1;
140+
}

0 commit comments

Comments
 (0)