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