]> Git Repo - linux.git/blob - tools/testing/selftests/kcmp/kcmp_test.c
scsi: zfcp: Trace when request remove fails after qdio send fails
[linux.git] / tools / testing / selftests / kcmp / kcmp_test.c
1 // SPDX-License-Identifier: GPL-2.0
2 #define _GNU_SOURCE
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <signal.h>
7 #include <limits.h>
8 #include <unistd.h>
9 #include <errno.h>
10 #include <string.h>
11 #include <fcntl.h>
12 #include <linux/unistd.h>
13 #include <linux/kcmp.h>
14
15 #include <sys/syscall.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <sys/wait.h>
19 #include <sys/epoll.h>
20
21 #include "../kselftest.h"
22
23 static long sys_kcmp(int pid1, int pid2, int type, unsigned long fd1, unsigned long fd2)
24 {
25         return syscall(__NR_kcmp, pid1, pid2, type, fd1, fd2);
26 }
27
28 static const unsigned int duped_num = 64;
29
30 int main(int argc, char **argv)
31 {
32         const char kpath[] = "kcmp-test-file";
33         struct kcmp_epoll_slot epoll_slot;
34         struct epoll_event ev;
35         int pid1, pid2;
36         int pipefd[2];
37         int fd1, fd2;
38         int epollfd;
39         int status;
40         int fddup;
41
42         fd1 = open(kpath, O_RDWR | O_CREAT | O_TRUNC, 0644);
43         pid1 = getpid();
44
45         if (fd1 < 0) {
46                 perror("Can't create file");
47                 ksft_exit_fail();
48         }
49
50         if (pipe(pipefd)) {
51                 perror("Can't create pipe");
52                 ksft_exit_fail();
53         }
54
55         epollfd = epoll_create1(0);
56         if (epollfd < 0) {
57                 perror("epoll_create1 failed");
58                 ksft_exit_fail();
59         }
60
61         memset(&ev, 0xff, sizeof(ev));
62         ev.events = EPOLLIN | EPOLLOUT;
63
64         if (epoll_ctl(epollfd, EPOLL_CTL_ADD, pipefd[0], &ev)) {
65                 perror("epoll_ctl failed");
66                 ksft_exit_fail();
67         }
68
69         fddup = dup2(pipefd[1], duped_num);
70         if (fddup < 0) {
71                 perror("dup2 failed");
72                 ksft_exit_fail();
73         }
74
75         if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fddup, &ev)) {
76                 perror("epoll_ctl failed");
77                 ksft_exit_fail();
78         }
79         close(fddup);
80
81         pid2 = fork();
82         if (pid2 < 0) {
83                 perror("fork failed");
84                 ksft_exit_fail();
85         }
86
87         if (!pid2) {
88                 int pid2 = getpid();
89                 int ret;
90
91                 ksft_print_header();
92                 ksft_set_plan(3);
93
94                 fd2 = open(kpath, O_RDWR, 0644);
95                 if (fd2 < 0) {
96                         perror("Can't open file");
97                         ksft_exit_fail();
98                 }
99
100                 /* An example of output and arguments */
101                 printf("pid1: %6d pid2: %6d FD: %2ld FILES: %2ld VM: %2ld "
102                        "FS: %2ld SIGHAND: %2ld IO: %2ld SYSVSEM: %2ld "
103                        "INV: %2ld\n",
104                        pid1, pid2,
105                        sys_kcmp(pid1, pid2, KCMP_FILE,          fd1, fd2),
106                        sys_kcmp(pid1, pid2, KCMP_FILES,         0, 0),
107                        sys_kcmp(pid1, pid2, KCMP_VM,            0, 0),
108                        sys_kcmp(pid1, pid2, KCMP_FS,            0, 0),
109                        sys_kcmp(pid1, pid2, KCMP_SIGHAND,       0, 0),
110                        sys_kcmp(pid1, pid2, KCMP_IO,            0, 0),
111                        sys_kcmp(pid1, pid2, KCMP_SYSVSEM,       0, 0),
112
113                         /* This one should fail */
114                        sys_kcmp(pid1, pid2, KCMP_TYPES + 1,     0, 0));
115
116                 /* This one should return same fd */
117                 ret = sys_kcmp(pid1, pid2, KCMP_FILE, fd1, fd1);
118                 if (ret) {
119                         printf("FAIL: 0 expected but %d returned (%s)\n",
120                                 ret, strerror(errno));
121                         ksft_inc_fail_cnt();
122                         ret = -1;
123                 } else {
124                         printf("PASS: 0 returned as expected\n");
125                         ksft_inc_pass_cnt();
126                 }
127
128                 /* Compare with self */
129                 ret = sys_kcmp(pid1, pid1, KCMP_VM, 0, 0);
130                 if (ret) {
131                         printf("FAIL: 0 expected but %d returned (%s)\n",
132                                 ret, strerror(errno));
133                         ksft_inc_fail_cnt();
134                         ret = -1;
135                 } else {
136                         printf("PASS: 0 returned as expected\n");
137                         ksft_inc_pass_cnt();
138                 }
139
140                 /* Compare epoll target */
141                 epoll_slot = (struct kcmp_epoll_slot) {
142                         .efd    = epollfd,
143                         .tfd    = duped_num,
144                         .toff   = 0,
145                 };
146                 ret = sys_kcmp(pid1, pid1, KCMP_EPOLL_TFD, pipefd[1],
147                                (unsigned long)(void *)&epoll_slot);
148                 if (ret) {
149                         printf("FAIL: 0 expected but %d returned (%s)\n",
150                                 ret, strerror(errno));
151                         ksft_inc_fail_cnt();
152                         ret = -1;
153                 } else {
154                         printf("PASS: 0 returned as expected\n");
155                         ksft_inc_pass_cnt();
156                 }
157
158
159                 if (ret)
160                         ksft_exit_fail();
161                 else
162                         ksft_exit_pass();
163         }
164
165         waitpid(pid2, &status, P_ALL);
166
167         return 0;
168 }
This page took 0.04304 seconds and 4 git commands to generate.