1*6b13d60bSMuhammad Moinur Rahman /*-
2*6b13d60bSMuhammad Moinur Rahman * SPDX-License-Identifier: BSD-2-Clause
3*6b13d60bSMuhammad Moinur Rahman *
4*6b13d60bSMuhammad Moinur Rahman * Copyright (c) 2022 Dell Inc.
5*6b13d60bSMuhammad Moinur Rahman * Author: Eric van Gyzen
6*6b13d60bSMuhammad Moinur Rahman *
7*6b13d60bSMuhammad Moinur Rahman * Redistribution and use in source and binary forms, with or without
8*6b13d60bSMuhammad Moinur Rahman * modification, are permitted provided that the following conditions
9*6b13d60bSMuhammad Moinur Rahman * are met:
10*6b13d60bSMuhammad Moinur Rahman * 1. Redistributions of source code must retain the above copyright
11*6b13d60bSMuhammad Moinur Rahman * notice, this list of conditions and the following disclaimer.
12*6b13d60bSMuhammad Moinur Rahman * 2. Redistributions in binary form must reproduce the above copyright
13*6b13d60bSMuhammad Moinur Rahman * notice, this list of conditions and the following disclaimer in the
14*6b13d60bSMuhammad Moinur Rahman * documentation and/or other materials provided with the distribution.
15*6b13d60bSMuhammad Moinur Rahman *
16*6b13d60bSMuhammad Moinur Rahman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*6b13d60bSMuhammad Moinur Rahman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*6b13d60bSMuhammad Moinur Rahman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*6b13d60bSMuhammad Moinur Rahman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*6b13d60bSMuhammad Moinur Rahman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*6b13d60bSMuhammad Moinur Rahman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*6b13d60bSMuhammad Moinur Rahman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*6b13d60bSMuhammad Moinur Rahman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*6b13d60bSMuhammad Moinur Rahman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*6b13d60bSMuhammad Moinur Rahman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*6b13d60bSMuhammad Moinur Rahman * SUCH DAMAGE.
27*6b13d60bSMuhammad Moinur Rahman */
28*6b13d60bSMuhammad Moinur Rahman
29*6b13d60bSMuhammad Moinur Rahman #if 0
30*6b13d60bSMuhammad Moinur Rahman
31*6b13d60bSMuhammad Moinur Rahman 1. Run some "bad" tests that prevent kyua from removing the work directory.
32*6b13d60bSMuhammad Moinur Rahman We use "chflags uunlink". Mounting a file system from an md(4) device
33*6b13d60bSMuhammad Moinur Rahman is another common use case.
34*6b13d60bSMuhammad Moinur Rahman 2. Fork a lot, nearly wrapping the PID number space, so step 3 will re-use
35*6b13d60bSMuhammad Moinur Rahman a PID from step 1. Running the entire FreeBSD test suite is a more
36*6b13d60bSMuhammad Moinur Rahman realistic scenario for this step.
37*6b13d60bSMuhammad Moinur Rahman 3. Run some more tests. If the stars align, the bug is not fixed yet, and
38*6b13d60bSMuhammad Moinur Rahman kyua is built with debugging, kyua will abort with the following messages.
39*6b13d60bSMuhammad Moinur Rahman Without debugging, the tests in step 3 will reuse the context from step 1,
40*6b13d60bSMuhammad Moinur Rahman including stdout, stderr, and working directory, which are still populated
41*6b13d60bSMuhammad Moinur Rahman with stuff from step 1. When I found this bug, step 3 was
42*6b13d60bSMuhammad Moinur Rahman __test_cases_list__, which expects a certain format in stdout and failed
43*6b13d60bSMuhammad Moinur Rahman when it found something completely unrelated.
44*6b13d60bSMuhammad Moinur Rahman 4. You can clean up with: chflags -R nouunlink /tmp/kyua.*; rm -rf /tmp/kyua.*
45*6b13d60bSMuhammad Moinur Rahman
46*6b13d60bSMuhammad Moinur Rahman $ cc -o pid_wrap -latf-c pid_wrap.c
47*6b13d60bSMuhammad Moinur Rahman $ kyua test
48*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_0 -> passed [0.001s]
49*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_1 -> passed [0.001s]
50*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_2 -> passed [0.001s]
51*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_3 -> passed [0.001s]
52*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_4 -> passed [0.001s]
53*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_5 -> passed [0.001s]
54*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_6 -> passed [0.001s]
55*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_7 -> passed [0.001s]
56*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_8 -> passed [0.001s]
57*6b13d60bSMuhammad Moinur Rahman pid_wrap:leak_9 -> passed [0.001s]
58*6b13d60bSMuhammad Moinur Rahman pid_wrap:pid_wrap -> passed [1.113s]
59*6b13d60bSMuhammad Moinur Rahman pid_wrap:pid_wrap_0 -> passed [0.001s]
60*6b13d60bSMuhammad Moinur Rahman pid_wrap:pid_wrap_1 -> passed [0.001s]
61*6b13d60bSMuhammad Moinur Rahman pid_wrap:pid_wrap_2 -> passed [0.001s]
62*6b13d60bSMuhammad Moinur Rahman pid_wrap:pid_wrap_3 -> *** /usr/src/main/contrib/kyua/utils/process/executor.cpp:779: Invariant check failed: PID 60876 already in all_exec_handles; not properly cleaned up or reused too fast
63*6b13d60bSMuhammad Moinur Rahman *** Fatal signal 6 received
64*6b13d60bSMuhammad Moinur Rahman *** Log file is /home/vangyzen/.kyua/logs/kyua.20221006-193544.log
65*6b13d60bSMuhammad Moinur Rahman *** Please report this problem to kyua-discuss@googlegroups.com detailing what you were doing before the crash happened; if possible, include the log file mentioned above
66*6b13d60bSMuhammad Moinur Rahman Abort trap (core dumped)
67*6b13d60bSMuhammad Moinur Rahman
68*6b13d60bSMuhammad Moinur Rahman #endif
69*6b13d60bSMuhammad Moinur Rahman
70*6b13d60bSMuhammad Moinur Rahman #include <sys/stat.h>
71*6b13d60bSMuhammad Moinur Rahman
72*6b13d60bSMuhammad Moinur Rahman #include <atf-c++.hpp>
73*6b13d60bSMuhammad Moinur Rahman
74*6b13d60bSMuhammad Moinur Rahman #include <fcntl.h>
75*6b13d60bSMuhammad Moinur Rahman #include <signal.h>
76*6b13d60bSMuhammad Moinur Rahman #include <unistd.h>
77*6b13d60bSMuhammad Moinur Rahman
78*6b13d60bSMuhammad Moinur Rahman #include <cerrno>
79*6b13d60bSMuhammad Moinur Rahman #include <cstring>
80*6b13d60bSMuhammad Moinur Rahman
81*6b13d60bSMuhammad Moinur Rahman void
leak_work_dir()82*6b13d60bSMuhammad Moinur Rahman leak_work_dir()
83*6b13d60bSMuhammad Moinur Rahman {
84*6b13d60bSMuhammad Moinur Rahman int fd;
85*6b13d60bSMuhammad Moinur Rahman
86*6b13d60bSMuhammad Moinur Rahman ATF_REQUIRE((fd = open("unforgettable", O_CREAT|O_EXCL|O_WRONLY, 0600))
87*6b13d60bSMuhammad Moinur Rahman >= 0);
88*6b13d60bSMuhammad Moinur Rahman ATF_REQUIRE_EQ(0, fchflags(fd, UF_NOUNLINK));
89*6b13d60bSMuhammad Moinur Rahman ATF_REQUIRE_EQ(0, close(fd));
90*6b13d60bSMuhammad Moinur Rahman }
91*6b13d60bSMuhammad Moinur Rahman
92*6b13d60bSMuhammad Moinur Rahman void
wrap_pids()93*6b13d60bSMuhammad Moinur Rahman wrap_pids()
94*6b13d60bSMuhammad Moinur Rahman {
95*6b13d60bSMuhammad Moinur Rahman pid_t begin, current, target;
96*6b13d60bSMuhammad Moinur Rahman bool wrapped;
97*6b13d60bSMuhammad Moinur Rahman
98*6b13d60bSMuhammad Moinur Rahman begin = getpid();
99*6b13d60bSMuhammad Moinur Rahman target = begin - 15;
100*6b13d60bSMuhammad Moinur Rahman if (target <= 1) {
101*6b13d60bSMuhammad Moinur Rahman target += 99999; // PID_MAX
102*6b13d60bSMuhammad Moinur Rahman wrapped = true;
103*6b13d60bSMuhammad Moinur Rahman } else {
104*6b13d60bSMuhammad Moinur Rahman wrapped = false;
105*6b13d60bSMuhammad Moinur Rahman }
106*6b13d60bSMuhammad Moinur Rahman
107*6b13d60bSMuhammad Moinur Rahman ATF_REQUIRE(signal(SIGCHLD, SIG_IGN) != SIG_ERR);
108*6b13d60bSMuhammad Moinur Rahman
109*6b13d60bSMuhammad Moinur Rahman do {
110*6b13d60bSMuhammad Moinur Rahman current = vfork();
111*6b13d60bSMuhammad Moinur Rahman if (current == 0) {
112*6b13d60bSMuhammad Moinur Rahman _exit(0);
113*6b13d60bSMuhammad Moinur Rahman }
114*6b13d60bSMuhammad Moinur Rahman ATF_REQUIRE(current != -1);
115*6b13d60bSMuhammad Moinur Rahman if (current < begin) {
116*6b13d60bSMuhammad Moinur Rahman wrapped = true;
117*6b13d60bSMuhammad Moinur Rahman }
118*6b13d60bSMuhammad Moinur Rahman } while (!wrapped || current < target);
119*6b13d60bSMuhammad Moinur Rahman }
120*6b13d60bSMuhammad Moinur Rahman
121*6b13d60bSMuhammad Moinur Rahman void
test_work_dir_reuse()122*6b13d60bSMuhammad Moinur Rahman test_work_dir_reuse()
123*6b13d60bSMuhammad Moinur Rahman {
124*6b13d60bSMuhammad Moinur Rahman // If kyua is built with debugging, it would abort here before the fix.
125*6b13d60bSMuhammad Moinur Rahman }
126*6b13d60bSMuhammad Moinur Rahman
127*6b13d60bSMuhammad Moinur Rahman void
clean_up()128*6b13d60bSMuhammad Moinur Rahman clean_up()
129*6b13d60bSMuhammad Moinur Rahman {
130*6b13d60bSMuhammad Moinur Rahman (void)system("chflags -R nouunlink ../..");
131*6b13d60bSMuhammad Moinur Rahman }
132*6b13d60bSMuhammad Moinur Rahman
133*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_0);
ATF_TEST_CASE_BODY(leak_0)134*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_0) { leak_work_dir(); }
135*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_1);
ATF_TEST_CASE_BODY(leak_1)136*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_1) { leak_work_dir(); }
137*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_2);
ATF_TEST_CASE_BODY(leak_2)138*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_2) { leak_work_dir(); }
139*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_3);
ATF_TEST_CASE_BODY(leak_3)140*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_3) { leak_work_dir(); }
141*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_4);
ATF_TEST_CASE_BODY(leak_4)142*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_4) { leak_work_dir(); }
143*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_5);
ATF_TEST_CASE_BODY(leak_5)144*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_5) { leak_work_dir(); }
145*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_6);
ATF_TEST_CASE_BODY(leak_6)146*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_6) { leak_work_dir(); }
147*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_7);
ATF_TEST_CASE_BODY(leak_7)148*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_7) { leak_work_dir(); }
149*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_8);
ATF_TEST_CASE_BODY(leak_8)150*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_8) { leak_work_dir(); }
151*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_9);
ATF_TEST_CASE_BODY(leak_9)152*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_9) { leak_work_dir(); }
153*6b13d60bSMuhammad Moinur Rahman
154*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap);
ATF_TEST_CASE_BODY(pid_wrap)155*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap) { wrap_pids(); }
156*6b13d60bSMuhammad Moinur Rahman
157*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_0);
ATF_TEST_CASE_BODY(pid_wrap_0)158*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_0) { test_work_dir_reuse(); }
159*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_1);
ATF_TEST_CASE_BODY(pid_wrap_1)160*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_1) { test_work_dir_reuse(); }
161*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_2);
ATF_TEST_CASE_BODY(pid_wrap_2)162*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_2) { test_work_dir_reuse(); }
163*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_3);
ATF_TEST_CASE_BODY(pid_wrap_3)164*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_3) { test_work_dir_reuse(); }
165*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_4);
ATF_TEST_CASE_BODY(pid_wrap_4)166*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_4) { test_work_dir_reuse(); }
167*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_5);
ATF_TEST_CASE_BODY(pid_wrap_5)168*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_5) { test_work_dir_reuse(); }
169*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_6);
ATF_TEST_CASE_BODY(pid_wrap_6)170*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_6) { test_work_dir_reuse(); }
171*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_7);
ATF_TEST_CASE_BODY(pid_wrap_7)172*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_7) { test_work_dir_reuse(); }
173*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_8);
ATF_TEST_CASE_BODY(pid_wrap_8)174*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_8) { test_work_dir_reuse(); }
175*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_9);
ATF_TEST_CASE_BODY(pid_wrap_9)176*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_9) { test_work_dir_reuse(); }
177*6b13d60bSMuhammad Moinur Rahman
178*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(really_clean_up);
ATF_TEST_CASE_BODY(really_clean_up)179*6b13d60bSMuhammad Moinur Rahman ATF_TEST_CASE_BODY(really_clean_up) { clean_up(); }
180*6b13d60bSMuhammad Moinur Rahman
ATF_INIT_TEST_CASES(tcs)181*6b13d60bSMuhammad Moinur Rahman ATF_INIT_TEST_CASES(tcs)
182*6b13d60bSMuhammad Moinur Rahman {
183*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, leak_0);
184*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, leak_1);
185*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, leak_2);
186*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, leak_3);
187*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, leak_4);
188*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, leak_5);
189*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, leak_6);
190*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, leak_7);
191*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, leak_8);
192*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, leak_9);
193*6b13d60bSMuhammad Moinur Rahman
194*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, pid_wrap);
195*6b13d60bSMuhammad Moinur Rahman
196*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, pid_wrap_0);
197*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, pid_wrap_1);
198*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, pid_wrap_2);
199*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, pid_wrap_3);
200*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, pid_wrap_4);
201*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, pid_wrap_5);
202*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, pid_wrap_6);
203*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, pid_wrap_7);
204*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, pid_wrap_8);
205*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, pid_wrap_9);
206*6b13d60bSMuhammad Moinur Rahman
207*6b13d60bSMuhammad Moinur Rahman ATF_ADD_TEST_CASE(tcs, really_clean_up);
208*6b13d60bSMuhammad Moinur Rahman }
209