xref: /dflybsd-src/test/stress/stress2/lib/main.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1*86d7f5d3SJohn Marino /*-
2*86d7f5d3SJohn Marino  * Copyright (c) 2008 Peter Holm <pho@FreeBSD.org>
3*86d7f5d3SJohn Marino  * All rights reserved.
4*86d7f5d3SJohn Marino  *
5*86d7f5d3SJohn Marino  * Redistribution and use in source and binary forms, with or without
6*86d7f5d3SJohn Marino  * modification, are permitted provided that the following conditions
7*86d7f5d3SJohn Marino  * are met:
8*86d7f5d3SJohn Marino  * 1. Redistributions of source code must retain the above copyright
9*86d7f5d3SJohn Marino  *    notice, this list of conditions and the following disclaimer.
10*86d7f5d3SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
11*86d7f5d3SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
12*86d7f5d3SJohn Marino  *    documentation and/or other materials provided with the distribution.
13*86d7f5d3SJohn Marino  *
14*86d7f5d3SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*86d7f5d3SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*86d7f5d3SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*86d7f5d3SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*86d7f5d3SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*86d7f5d3SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*86d7f5d3SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*86d7f5d3SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*86d7f5d3SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*86d7f5d3SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*86d7f5d3SJohn Marino  * SUCH DAMAGE.
25*86d7f5d3SJohn Marino  *
26*86d7f5d3SJohn Marino  */
27*86d7f5d3SJohn Marino 
28*86d7f5d3SJohn Marino /* Main program for all test programs */
29*86d7f5d3SJohn Marino 
30*86d7f5d3SJohn Marino #include <stdio.h>
31*86d7f5d3SJohn Marino #include <signal.h>
32*86d7f5d3SJohn Marino #include <unistd.h>
33*86d7f5d3SJohn Marino #include <stdlib.h>
34*86d7f5d3SJohn Marino #include <string.h>
35*86d7f5d3SJohn Marino #include <time.h>
36*86d7f5d3SJohn Marino #include <err.h>
37*86d7f5d3SJohn Marino #include <errno.h>
38*86d7f5d3SJohn Marino #include <sys/wait.h>
39*86d7f5d3SJohn Marino #include <sys/stat.h>
40*86d7f5d3SJohn Marino 
41*86d7f5d3SJohn Marino #include "stress.h"
42*86d7f5d3SJohn Marino 
43*86d7f5d3SJohn Marino static char const rcsid[] = "$Name:  $ $FreeBSD$";
44*86d7f5d3SJohn Marino 
45*86d7f5d3SJohn Marino volatile int done_testing;
46*86d7f5d3SJohn Marino static int cleanupcalled = 0;
47*86d7f5d3SJohn Marino char *home;
48*86d7f5d3SJohn Marino 
49*86d7f5d3SJohn Marino static	pid_t *r;
50*86d7f5d3SJohn Marino 
51*86d7f5d3SJohn Marino void
handler(int i)52*86d7f5d3SJohn Marino handler(int i)
53*86d7f5d3SJohn Marino {
54*86d7f5d3SJohn Marino 	int j;
55*86d7f5d3SJohn Marino 
56*86d7f5d3SJohn Marino 	done_testing = 1;
57*86d7f5d3SJohn Marino 	for (j = 0; j < op->incarnations; j++) {
58*86d7f5d3SJohn Marino 		if (op->verbose > 2)
59*86d7f5d3SJohn Marino 			printf("handler: kill -HUP %d\n", r[j]);
60*86d7f5d3SJohn Marino 		if (r[j] != 0 && kill(r[j], SIGHUP) == -1)
61*86d7f5d3SJohn Marino 			if (errno != ESRCH)
62*86d7f5d3SJohn Marino 				warn("kill(%d, SIGHUP), %s:%d", r[j], __FILE__, __LINE__);
63*86d7f5d3SJohn Marino 	}
64*86d7f5d3SJohn Marino 	if (op->kill == 1) {
65*86d7f5d3SJohn Marino 		sleep(5);
66*86d7f5d3SJohn Marino 		/* test programs may have blocked for the SIGHUP, so try harder */
67*86d7f5d3SJohn Marino 		for (j = 0; j < op->incarnations; j++) {
68*86d7f5d3SJohn Marino 			if (op->verbose > 2)
69*86d7f5d3SJohn Marino 				printf("handler: kill -KILL %d\n", r[j]);
70*86d7f5d3SJohn Marino 			if (r[j] != 0)
71*86d7f5d3SJohn Marino 				(void) kill(r[j], SIGKILL);
72*86d7f5d3SJohn Marino 		}
73*86d7f5d3SJohn Marino 	}
74*86d7f5d3SJohn Marino }
75*86d7f5d3SJohn Marino 
76*86d7f5d3SJohn Marino void
run_test_handler(int i)77*86d7f5d3SJohn Marino run_test_handler(int i)
78*86d7f5d3SJohn Marino {
79*86d7f5d3SJohn Marino 
80*86d7f5d3SJohn Marino 	done_testing = 1;
81*86d7f5d3SJohn Marino }
82*86d7f5d3SJohn Marino 
83*86d7f5d3SJohn Marino void
exit_handler(int i)84*86d7f5d3SJohn Marino exit_handler(int i)
85*86d7f5d3SJohn Marino {
86*86d7f5d3SJohn Marino 
87*86d7f5d3SJohn Marino 	exit(1);
88*86d7f5d3SJohn Marino }
89*86d7f5d3SJohn Marino 
90*86d7f5d3SJohn Marino void
callcleanup(void)91*86d7f5d3SJohn Marino callcleanup(void)
92*86d7f5d3SJohn Marino {
93*86d7f5d3SJohn Marino 	if (cleanupcalled == 0)
94*86d7f5d3SJohn Marino 		cleanup();
95*86d7f5d3SJohn Marino 	cleanupcalled = 1;
96*86d7f5d3SJohn Marino }
97*86d7f5d3SJohn Marino 
98*86d7f5d3SJohn Marino static void
run_tests(int i)99*86d7f5d3SJohn Marino run_tests(int i)
100*86d7f5d3SJohn Marino {
101*86d7f5d3SJohn Marino 	time_t start;
102*86d7f5d3SJohn Marino 
103*86d7f5d3SJohn Marino 	signal(SIGHUP, run_test_handler);
104*86d7f5d3SJohn Marino 	signal(SIGINT, exit_handler);
105*86d7f5d3SJohn Marino 	atexit(callcleanup);
106*86d7f5d3SJohn Marino 	setup(i);
107*86d7f5d3SJohn Marino 	if ((strcmp(getprogname(), "run") != 0) && (op->nodelay == 0))
108*86d7f5d3SJohn Marino 		sleep(random_int(1,10));
109*86d7f5d3SJohn Marino 	start = time(NULL);
110*86d7f5d3SJohn Marino 	while (done_testing == 0 &&
111*86d7f5d3SJohn Marino 			(time(NULL) - start) < op->run_time) {
112*86d7f5d3SJohn Marino 		test();
113*86d7f5d3SJohn Marino 	}
114*86d7f5d3SJohn Marino 	callcleanup();
115*86d7f5d3SJohn Marino 	exit(EXIT_SUCCESS);
116*86d7f5d3SJohn Marino }
117*86d7f5d3SJohn Marino 
118*86d7f5d3SJohn Marino static void
run_incarnations(void)119*86d7f5d3SJohn Marino run_incarnations(void)
120*86d7f5d3SJohn Marino {
121*86d7f5d3SJohn Marino 	int i;
122*86d7f5d3SJohn Marino 	int s;
123*86d7f5d3SJohn Marino 
124*86d7f5d3SJohn Marino 	signal(SIGHUP, handler);
125*86d7f5d3SJohn Marino 	for (i = 0; i < op->incarnations && done_testing == 0; i++) {
126*86d7f5d3SJohn Marino 		if ((r[i] = fork()) == 0) {
127*86d7f5d3SJohn Marino 			run_tests(i);
128*86d7f5d3SJohn Marino 		}
129*86d7f5d3SJohn Marino 		if (r[i] < 0) {
130*86d7f5d3SJohn Marino 			warn("fork(), %s:%d", __FILE__, __LINE__);
131*86d7f5d3SJohn Marino 			r[i] = 0;
132*86d7f5d3SJohn Marino 			break;
133*86d7f5d3SJohn Marino 		}
134*86d7f5d3SJohn Marino 	}
135*86d7f5d3SJohn Marino 	for (i = 0; i < op->incarnations; i++)
136*86d7f5d3SJohn Marino 		if (r[i] != 0 && waitpid(r[i], &s, 0) == -1)
137*86d7f5d3SJohn Marino 			warn("waitpid(%d), %s:%d", r[i], __FILE__, __LINE__);
138*86d7f5d3SJohn Marino 
139*86d7f5d3SJohn Marino 	exit(EXIT_SUCCESS);
140*86d7f5d3SJohn Marino }
141*86d7f5d3SJohn Marino 
142*86d7f5d3SJohn Marino static int
run_test(void)143*86d7f5d3SJohn Marino run_test(void)
144*86d7f5d3SJohn Marino {
145*86d7f5d3SJohn Marino 	pid_t p;
146*86d7f5d3SJohn Marino 	time_t start;
147*86d7f5d3SJohn Marino 	int status = 0;
148*86d7f5d3SJohn Marino 
149*86d7f5d3SJohn Marino 	if (random_int(1,100) > op->load)
150*86d7f5d3SJohn Marino 		return (status);
151*86d7f5d3SJohn Marino 
152*86d7f5d3SJohn Marino 	show_status();
153*86d7f5d3SJohn Marino 
154*86d7f5d3SJohn Marino 	start = time(NULL);
155*86d7f5d3SJohn Marino 	done_testing = 0;
156*86d7f5d3SJohn Marino 	fflush(stdout);
157*86d7f5d3SJohn Marino 	rmval();
158*86d7f5d3SJohn Marino 	p = fork();
159*86d7f5d3SJohn Marino 	if (p == 0)
160*86d7f5d3SJohn Marino 		run_incarnations();
161*86d7f5d3SJohn Marino 	if (p < 0)
162*86d7f5d3SJohn Marino 		err(1, "fork() in %s:%d", __FILE__, __LINE__);
163*86d7f5d3SJohn Marino 	while (done_testing != 1 &&
164*86d7f5d3SJohn Marino 			(time(NULL) - start) < op->run_time)
165*86d7f5d3SJohn Marino 		sleep(1);
166*86d7f5d3SJohn Marino 	if (kill(p, SIGHUP) == -1)
167*86d7f5d3SJohn Marino 		warn("kill(%d, SIGHUP), %s:%d", p, __FILE__, __LINE__);
168*86d7f5d3SJohn Marino 
169*86d7f5d3SJohn Marino 	if (waitpid(p, &status, 0) == -1)
170*86d7f5d3SJohn Marino 		err(1, "waitpid(%d), %s:%d", p, __FILE__, __LINE__);
171*86d7f5d3SJohn Marino 
172*86d7f5d3SJohn Marino 	return (status);
173*86d7f5d3SJohn Marino }
174*86d7f5d3SJohn Marino 
175*86d7f5d3SJohn Marino int
main(int argc,char ** argv)176*86d7f5d3SJohn Marino main(int argc, char **argv)
177*86d7f5d3SJohn Marino {
178*86d7f5d3SJohn Marino 	struct stat sb;
179*86d7f5d3SJohn Marino 	int status = 0;
180*86d7f5d3SJohn Marino 
181*86d7f5d3SJohn Marino 	options(argc, argv);
182*86d7f5d3SJohn Marino 
183*86d7f5d3SJohn Marino 	umask(0);
184*86d7f5d3SJohn Marino 	if (stat(op->wd, &sb) == -1) {
185*86d7f5d3SJohn Marino 		if (mkdir(op->wd, 0770) == -1)
186*86d7f5d3SJohn Marino 			if (errno != EEXIST)
187*86d7f5d3SJohn Marino 				err(1, "mkdir(%s) %s:%d", op->wd, __FILE__, __LINE__);
188*86d7f5d3SJohn Marino 	}
189*86d7f5d3SJohn Marino 	if (stat(op->cd, &sb) == -1) {
190*86d7f5d3SJohn Marino 		if (mkdir(op->cd, 0770) == -1)
191*86d7f5d3SJohn Marino 			if (errno != EEXIST)
192*86d7f5d3SJohn Marino 				err(1, "mkdir(%s) %s:%d", op->cd, __FILE__, __LINE__);
193*86d7f5d3SJohn Marino 	}
194*86d7f5d3SJohn Marino 	if ((home = getcwd(NULL, 0)) == NULL)
195*86d7f5d3SJohn Marino 		err(1, "getcwd(), %s:%d",  __FILE__, __LINE__);
196*86d7f5d3SJohn Marino 	if (chdir(op->wd) == -1)
197*86d7f5d3SJohn Marino 		err(1, "chdir(%s) %s:%d", op->wd, __FILE__, __LINE__);
198*86d7f5d3SJohn Marino 
199*86d7f5d3SJohn Marino 	r = (pid_t *)calloc(1, op->incarnations * sizeof(pid_t));
200*86d7f5d3SJohn Marino 
201*86d7f5d3SJohn Marino 	status = run_test();
202*86d7f5d3SJohn Marino 
203*86d7f5d3SJohn Marino 	return (status);
204*86d7f5d3SJohn Marino }
205