xref: /dflybsd-src/test/stress/stress2/lib/main.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
186d7f5d3SJohn Marino /*-
286d7f5d3SJohn Marino  * Copyright (c) 2008 Peter Holm <pho@FreeBSD.org>
386d7f5d3SJohn Marino  * All rights reserved.
486d7f5d3SJohn Marino  *
586d7f5d3SJohn Marino  * Redistribution and use in source and binary forms, with or without
686d7f5d3SJohn Marino  * modification, are permitted provided that the following conditions
786d7f5d3SJohn Marino  * are met:
886d7f5d3SJohn Marino  * 1. Redistributions of source code must retain the above copyright
986d7f5d3SJohn Marino  *    notice, this list of conditions and the following disclaimer.
1086d7f5d3SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
1186d7f5d3SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
1286d7f5d3SJohn Marino  *    documentation and/or other materials provided with the distribution.
1386d7f5d3SJohn Marino  *
1486d7f5d3SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1586d7f5d3SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1686d7f5d3SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1786d7f5d3SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1886d7f5d3SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1986d7f5d3SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2086d7f5d3SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2186d7f5d3SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2286d7f5d3SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2386d7f5d3SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2486d7f5d3SJohn Marino  * SUCH DAMAGE.
2586d7f5d3SJohn Marino  *
2686d7f5d3SJohn Marino  */
2786d7f5d3SJohn Marino 
2886d7f5d3SJohn Marino /* Main program for all test programs */
2986d7f5d3SJohn Marino 
3086d7f5d3SJohn Marino #include <stdio.h>
3186d7f5d3SJohn Marino #include <signal.h>
3286d7f5d3SJohn Marino #include <unistd.h>
3386d7f5d3SJohn Marino #include <stdlib.h>
3486d7f5d3SJohn Marino #include <string.h>
3586d7f5d3SJohn Marino #include <time.h>
3686d7f5d3SJohn Marino #include <err.h>
3786d7f5d3SJohn Marino #include <errno.h>
3886d7f5d3SJohn Marino #include <sys/wait.h>
3986d7f5d3SJohn Marino #include <sys/stat.h>
4086d7f5d3SJohn Marino 
4186d7f5d3SJohn Marino #include "stress.h"
4286d7f5d3SJohn Marino 
4386d7f5d3SJohn Marino static char const rcsid[] = "$Name:  $ $FreeBSD$";
4486d7f5d3SJohn Marino 
4586d7f5d3SJohn Marino volatile int done_testing;
4686d7f5d3SJohn Marino static int cleanupcalled = 0;
4786d7f5d3SJohn Marino char *home;
4886d7f5d3SJohn Marino 
4986d7f5d3SJohn Marino static	pid_t *r;
5086d7f5d3SJohn Marino 
5186d7f5d3SJohn Marino void
handler(int i)5286d7f5d3SJohn Marino handler(int i)
5386d7f5d3SJohn Marino {
5486d7f5d3SJohn Marino 	int j;
5586d7f5d3SJohn Marino 
5686d7f5d3SJohn Marino 	done_testing = 1;
5786d7f5d3SJohn Marino 	for (j = 0; j < op->incarnations; j++) {
5886d7f5d3SJohn Marino 		if (op->verbose > 2)
5986d7f5d3SJohn Marino 			printf("handler: kill -HUP %d\n", r[j]);
6086d7f5d3SJohn Marino 		if (r[j] != 0 && kill(r[j], SIGHUP) == -1)
6186d7f5d3SJohn Marino 			if (errno != ESRCH)
6286d7f5d3SJohn Marino 				warn("kill(%d, SIGHUP), %s:%d", r[j], __FILE__, __LINE__);
6386d7f5d3SJohn Marino 	}
6486d7f5d3SJohn Marino 	if (op->kill == 1) {
6586d7f5d3SJohn Marino 		sleep(5);
6686d7f5d3SJohn Marino 		/* test programs may have blocked for the SIGHUP, so try harder */
6786d7f5d3SJohn Marino 		for (j = 0; j < op->incarnations; j++) {
6886d7f5d3SJohn Marino 			if (op->verbose > 2)
6986d7f5d3SJohn Marino 				printf("handler: kill -KILL %d\n", r[j]);
7086d7f5d3SJohn Marino 			if (r[j] != 0)
7186d7f5d3SJohn Marino 				(void) kill(r[j], SIGKILL);
7286d7f5d3SJohn Marino 		}
7386d7f5d3SJohn Marino 	}
7486d7f5d3SJohn Marino }
7586d7f5d3SJohn Marino 
7686d7f5d3SJohn Marino void
run_test_handler(int i)7786d7f5d3SJohn Marino run_test_handler(int i)
7886d7f5d3SJohn Marino {
7986d7f5d3SJohn Marino 
8086d7f5d3SJohn Marino 	done_testing = 1;
8186d7f5d3SJohn Marino }
8286d7f5d3SJohn Marino 
8386d7f5d3SJohn Marino void
exit_handler(int i)8486d7f5d3SJohn Marino exit_handler(int i)
8586d7f5d3SJohn Marino {
8686d7f5d3SJohn Marino 
8786d7f5d3SJohn Marino 	exit(1);
8886d7f5d3SJohn Marino }
8986d7f5d3SJohn Marino 
9086d7f5d3SJohn Marino void
callcleanup(void)9186d7f5d3SJohn Marino callcleanup(void)
9286d7f5d3SJohn Marino {
9386d7f5d3SJohn Marino 	if (cleanupcalled == 0)
9486d7f5d3SJohn Marino 		cleanup();
9586d7f5d3SJohn Marino 	cleanupcalled = 1;
9686d7f5d3SJohn Marino }
9786d7f5d3SJohn Marino 
9886d7f5d3SJohn Marino static void
run_tests(int i)9986d7f5d3SJohn Marino run_tests(int i)
10086d7f5d3SJohn Marino {
10186d7f5d3SJohn Marino 	time_t start;
10286d7f5d3SJohn Marino 
10386d7f5d3SJohn Marino 	signal(SIGHUP, run_test_handler);
10486d7f5d3SJohn Marino 	signal(SIGINT, exit_handler);
10586d7f5d3SJohn Marino 	atexit(callcleanup);
10686d7f5d3SJohn Marino 	setup(i);
10786d7f5d3SJohn Marino 	if ((strcmp(getprogname(), "run") != 0) && (op->nodelay == 0))
10886d7f5d3SJohn Marino 		sleep(random_int(1,10));
10986d7f5d3SJohn Marino 	start = time(NULL);
11086d7f5d3SJohn Marino 	while (done_testing == 0 &&
11186d7f5d3SJohn Marino 			(time(NULL) - start) < op->run_time) {
11286d7f5d3SJohn Marino 		test();
11386d7f5d3SJohn Marino 	}
11486d7f5d3SJohn Marino 	callcleanup();
11586d7f5d3SJohn Marino 	exit(EXIT_SUCCESS);
11686d7f5d3SJohn Marino }
11786d7f5d3SJohn Marino 
11886d7f5d3SJohn Marino static void
run_incarnations(void)11986d7f5d3SJohn Marino run_incarnations(void)
12086d7f5d3SJohn Marino {
12186d7f5d3SJohn Marino 	int i;
12286d7f5d3SJohn Marino 	int s;
12386d7f5d3SJohn Marino 
12486d7f5d3SJohn Marino 	signal(SIGHUP, handler);
12586d7f5d3SJohn Marino 	for (i = 0; i < op->incarnations && done_testing == 0; i++) {
12686d7f5d3SJohn Marino 		if ((r[i] = fork()) == 0) {
12786d7f5d3SJohn Marino 			run_tests(i);
12886d7f5d3SJohn Marino 		}
12986d7f5d3SJohn Marino 		if (r[i] < 0) {
13086d7f5d3SJohn Marino 			warn("fork(), %s:%d", __FILE__, __LINE__);
13186d7f5d3SJohn Marino 			r[i] = 0;
13286d7f5d3SJohn Marino 			break;
13386d7f5d3SJohn Marino 		}
13486d7f5d3SJohn Marino 	}
13586d7f5d3SJohn Marino 	for (i = 0; i < op->incarnations; i++)
13686d7f5d3SJohn Marino 		if (r[i] != 0 && waitpid(r[i], &s, 0) == -1)
13786d7f5d3SJohn Marino 			warn("waitpid(%d), %s:%d", r[i], __FILE__, __LINE__);
13886d7f5d3SJohn Marino 
13986d7f5d3SJohn Marino 	exit(EXIT_SUCCESS);
14086d7f5d3SJohn Marino }
14186d7f5d3SJohn Marino 
14286d7f5d3SJohn Marino static int
run_test(void)14386d7f5d3SJohn Marino run_test(void)
14486d7f5d3SJohn Marino {
14586d7f5d3SJohn Marino 	pid_t p;
14686d7f5d3SJohn Marino 	time_t start;
14786d7f5d3SJohn Marino 	int status = 0;
14886d7f5d3SJohn Marino 
14986d7f5d3SJohn Marino 	if (random_int(1,100) > op->load)
15086d7f5d3SJohn Marino 		return (status);
15186d7f5d3SJohn Marino 
15286d7f5d3SJohn Marino 	show_status();
15386d7f5d3SJohn Marino 
15486d7f5d3SJohn Marino 	start = time(NULL);
15586d7f5d3SJohn Marino 	done_testing = 0;
15686d7f5d3SJohn Marino 	fflush(stdout);
15786d7f5d3SJohn Marino 	rmval();
15886d7f5d3SJohn Marino 	p = fork();
15986d7f5d3SJohn Marino 	if (p == 0)
16086d7f5d3SJohn Marino 		run_incarnations();
16186d7f5d3SJohn Marino 	if (p < 0)
16286d7f5d3SJohn Marino 		err(1, "fork() in %s:%d", __FILE__, __LINE__);
16386d7f5d3SJohn Marino 	while (done_testing != 1 &&
16486d7f5d3SJohn Marino 			(time(NULL) - start) < op->run_time)
16586d7f5d3SJohn Marino 		sleep(1);
16686d7f5d3SJohn Marino 	if (kill(p, SIGHUP) == -1)
16786d7f5d3SJohn Marino 		warn("kill(%d, SIGHUP), %s:%d", p, __FILE__, __LINE__);
16886d7f5d3SJohn Marino 
16986d7f5d3SJohn Marino 	if (waitpid(p, &status, 0) == -1)
17086d7f5d3SJohn Marino 		err(1, "waitpid(%d), %s:%d", p, __FILE__, __LINE__);
17186d7f5d3SJohn Marino 
17286d7f5d3SJohn Marino 	return (status);
17386d7f5d3SJohn Marino }
17486d7f5d3SJohn Marino 
17586d7f5d3SJohn Marino int
main(int argc,char ** argv)17686d7f5d3SJohn Marino main(int argc, char **argv)
17786d7f5d3SJohn Marino {
17886d7f5d3SJohn Marino 	struct stat sb;
17986d7f5d3SJohn Marino 	int status = 0;
18086d7f5d3SJohn Marino 
18186d7f5d3SJohn Marino 	options(argc, argv);
18286d7f5d3SJohn Marino 
18386d7f5d3SJohn Marino 	umask(0);
18486d7f5d3SJohn Marino 	if (stat(op->wd, &sb) == -1) {
18586d7f5d3SJohn Marino 		if (mkdir(op->wd, 0770) == -1)
18686d7f5d3SJohn Marino 			if (errno != EEXIST)
18786d7f5d3SJohn Marino 				err(1, "mkdir(%s) %s:%d", op->wd, __FILE__, __LINE__);
18886d7f5d3SJohn Marino 	}
18986d7f5d3SJohn Marino 	if (stat(op->cd, &sb) == -1) {
19086d7f5d3SJohn Marino 		if (mkdir(op->cd, 0770) == -1)
19186d7f5d3SJohn Marino 			if (errno != EEXIST)
19286d7f5d3SJohn Marino 				err(1, "mkdir(%s) %s:%d", op->cd, __FILE__, __LINE__);
19386d7f5d3SJohn Marino 	}
19486d7f5d3SJohn Marino 	if ((home = getcwd(NULL, 0)) == NULL)
19586d7f5d3SJohn Marino 		err(1, "getcwd(), %s:%d",  __FILE__, __LINE__);
19686d7f5d3SJohn Marino 	if (chdir(op->wd) == -1)
19786d7f5d3SJohn Marino 		err(1, "chdir(%s) %s:%d", op->wd, __FILE__, __LINE__);
19886d7f5d3SJohn Marino 
19986d7f5d3SJohn Marino 	r = (pid_t *)calloc(1, op->incarnations * sizeof(pid_t));
20086d7f5d3SJohn Marino 
20186d7f5d3SJohn Marino 	status = run_test();
20286d7f5d3SJohn Marino 
20386d7f5d3SJohn Marino 	return (status);
20486d7f5d3SJohn Marino }
205