xref: /aosp_15_r20/external/ltp/tools/genload/stress.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /* A program to put stress on a POSIX system (stress).
2*49cdfc7eSAndroid Build Coastguard Worker  *
3*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (C) 2001, 2002 Amos Waterland <[email protected]>
4*49cdfc7eSAndroid Build Coastguard Worker  *
5*49cdfc7eSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or modify it
6*49cdfc7eSAndroid Build Coastguard Worker  * under the terms of the GNU General Public License as published by the Free
7*49cdfc7eSAndroid Build Coastguard Worker  * Software Foundation; either version 2 of the License, or (at your option)
8*49cdfc7eSAndroid Build Coastguard Worker  * any later version.
9*49cdfc7eSAndroid Build Coastguard Worker  *
10*49cdfc7eSAndroid Build Coastguard Worker  * This program is distributed in the hope that it will be useful, but WITHOUT
11*49cdfc7eSAndroid Build Coastguard Worker  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12*49cdfc7eSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13*49cdfc7eSAndroid Build Coastguard Worker  * more details.
14*49cdfc7eSAndroid Build Coastguard Worker  *
15*49cdfc7eSAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License along
16*49cdfc7eSAndroid Build Coastguard Worker  * with this program; if not, write to the Free Software Foundation, Inc.,
17*49cdfc7eSAndroid Build Coastguard Worker  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18*49cdfc7eSAndroid Build Coastguard Worker  */
19*49cdfc7eSAndroid Build Coastguard Worker 
20*49cdfc7eSAndroid Build Coastguard Worker #include <ctype.h>
21*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
22*49cdfc7eSAndroid Build Coastguard Worker #include <libgen.h>
23*49cdfc7eSAndroid Build Coastguard Worker #include <math.h>
24*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
25*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
26*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
27*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h>
28*49cdfc7eSAndroid Build Coastguard Worker #include <time.h>
29*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
30*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
31*49cdfc7eSAndroid Build Coastguard Worker 
32*49cdfc7eSAndroid Build Coastguard Worker /* By default, print all messages of severity info and above.  */
33*49cdfc7eSAndroid Build Coastguard Worker static int global_debug = 2;
34*49cdfc7eSAndroid Build Coastguard Worker 
35*49cdfc7eSAndroid Build Coastguard Worker /* By default, just print warning for non-critical errors.  */
36*49cdfc7eSAndroid Build Coastguard Worker static int global_ignore = 1;
37*49cdfc7eSAndroid Build Coastguard Worker 
38*49cdfc7eSAndroid Build Coastguard Worker /* By default, retry on non-critical errors every 50ms.  */
39*49cdfc7eSAndroid Build Coastguard Worker static int global_retry = 50000;
40*49cdfc7eSAndroid Build Coastguard Worker 
41*49cdfc7eSAndroid Build Coastguard Worker /* By default, use this as backoff coefficient for good fork throughput.  */
42*49cdfc7eSAndroid Build Coastguard Worker static int global_backoff = 3000;
43*49cdfc7eSAndroid Build Coastguard Worker 
44*49cdfc7eSAndroid Build Coastguard Worker /* By default, do not timeout.  */
45*49cdfc7eSAndroid Build Coastguard Worker static int global_timeout = 0;
46*49cdfc7eSAndroid Build Coastguard Worker 
47*49cdfc7eSAndroid Build Coastguard Worker /* Name of this program */
48*49cdfc7eSAndroid Build Coastguard Worker static char *global_progname = PACKAGE;
49*49cdfc7eSAndroid Build Coastguard Worker 
50*49cdfc7eSAndroid Build Coastguard Worker /* By default, do not hang after allocating memory.  */
51*49cdfc7eSAndroid Build Coastguard Worker static int global_vmhang = 0;
52*49cdfc7eSAndroid Build Coastguard Worker 
53*49cdfc7eSAndroid Build Coastguard Worker /* Implemention of runtime-selectable severity message printing.  */
54*49cdfc7eSAndroid Build Coastguard Worker #define dbg if (global_debug >= 3) \
55*49cdfc7eSAndroid Build Coastguard Worker             fprintf (stdout, "%s: debug: (%d) ", global_progname, __LINE__), \
56*49cdfc7eSAndroid Build Coastguard Worker             fprintf
57*49cdfc7eSAndroid Build Coastguard Worker #define out if (global_debug >= 2) \
58*49cdfc7eSAndroid Build Coastguard Worker             fprintf (stdout, "%s: info: ", global_progname), \
59*49cdfc7eSAndroid Build Coastguard Worker             fprintf
60*49cdfc7eSAndroid Build Coastguard Worker #define wrn if (global_debug >= 1) \
61*49cdfc7eSAndroid Build Coastguard Worker             fprintf (stderr, "%s: warn: (%d) ", global_progname, __LINE__), \
62*49cdfc7eSAndroid Build Coastguard Worker             fprintf
63*49cdfc7eSAndroid Build Coastguard Worker #define err if (global_debug >= 0) \
64*49cdfc7eSAndroid Build Coastguard Worker             fprintf (stderr, "%s: error: (%d) ", global_progname, __LINE__), \
65*49cdfc7eSAndroid Build Coastguard Worker             fprintf
66*49cdfc7eSAndroid Build Coastguard Worker 
67*49cdfc7eSAndroid Build Coastguard Worker /* Implementation of check for option argument correctness.  */
68*49cdfc7eSAndroid Build Coastguard Worker #define assert_arg(A) \
69*49cdfc7eSAndroid Build Coastguard Worker           if (++i == argc || ((arg = argv[i])[0] == '-' && \
70*49cdfc7eSAndroid Build Coastguard Worker               !isdigit ((int)arg[1]) )) \
71*49cdfc7eSAndroid Build Coastguard Worker             { \
72*49cdfc7eSAndroid Build Coastguard Worker               err (stderr, "missing argument to option '%s'\n", A); \
73*49cdfc7eSAndroid Build Coastguard Worker               exit (1); \
74*49cdfc7eSAndroid Build Coastguard Worker             }
75*49cdfc7eSAndroid Build Coastguard Worker 
76*49cdfc7eSAndroid Build Coastguard Worker /* Prototypes for utility functions.  */
77*49cdfc7eSAndroid Build Coastguard Worker int usage(int status);
78*49cdfc7eSAndroid Build Coastguard Worker int version(int status);
79*49cdfc7eSAndroid Build Coastguard Worker long long atoll_s(const char *nptr);
80*49cdfc7eSAndroid Build Coastguard Worker long long atoll_b(const char *nptr);
81*49cdfc7eSAndroid Build Coastguard Worker 
82*49cdfc7eSAndroid Build Coastguard Worker /* Prototypes for the worker functions.  */
83*49cdfc7eSAndroid Build Coastguard Worker int hogcpu(long long forks);
84*49cdfc7eSAndroid Build Coastguard Worker int hogio(long long forks);
85*49cdfc7eSAndroid Build Coastguard Worker int hogvm(long long forks, long long chunks, long long bytes);
86*49cdfc7eSAndroid Build Coastguard Worker int hoghdd(long long forks, int clean, long long files, long long bytes);
87*49cdfc7eSAndroid Build Coastguard Worker 
main(int argc,char ** argv)88*49cdfc7eSAndroid Build Coastguard Worker int main(int argc, char **argv)
89*49cdfc7eSAndroid Build Coastguard Worker {
90*49cdfc7eSAndroid Build Coastguard Worker 	int i, pid, children = 0, retval = 0;
91*49cdfc7eSAndroid Build Coastguard Worker 	long starttime, stoptime, runtime;
92*49cdfc7eSAndroid Build Coastguard Worker 
93*49cdfc7eSAndroid Build Coastguard Worker 	/* Variables that indicate which options have been selected.  */
94*49cdfc7eSAndroid Build Coastguard Worker 	int do_dryrun = 0;
95*49cdfc7eSAndroid Build Coastguard Worker 	int do_timeout = 0;
96*49cdfc7eSAndroid Build Coastguard Worker 	int do_cpu = 0;		/* Default to 1 fork. */
97*49cdfc7eSAndroid Build Coastguard Worker 	long long do_cpu_forks = 1;
98*49cdfc7eSAndroid Build Coastguard Worker 	int do_io = 0;		/* Default to 1 fork. */
99*49cdfc7eSAndroid Build Coastguard Worker 	long long do_io_forks = 1;
100*49cdfc7eSAndroid Build Coastguard Worker 	int do_vm = 0;		/* Default to 1 fork, 1 chunk of 256MB.  */
101*49cdfc7eSAndroid Build Coastguard Worker 	long long do_vm_forks = 1;
102*49cdfc7eSAndroid Build Coastguard Worker 	long long do_vm_chunks = 1;
103*49cdfc7eSAndroid Build Coastguard Worker 	long long do_vm_bytes = 256 * 1024 * 1024;
104*49cdfc7eSAndroid Build Coastguard Worker 	int do_hdd = 0;		/* Default to 1 fork, clean, 1 file of 1GB.  */
105*49cdfc7eSAndroid Build Coastguard Worker 	long long do_hdd_forks = 1;
106*49cdfc7eSAndroid Build Coastguard Worker 	int do_hdd_clean = 0;
107*49cdfc7eSAndroid Build Coastguard Worker 	long long do_hdd_files = 1;
108*49cdfc7eSAndroid Build Coastguard Worker 	long long do_hdd_bytes = 1024 * 1024 * 1024;
109*49cdfc7eSAndroid Build Coastguard Worker 
110*49cdfc7eSAndroid Build Coastguard Worker 	/* Record our start time.  */
111*49cdfc7eSAndroid Build Coastguard Worker 	if ((starttime = time(NULL)) == -1) {
112*49cdfc7eSAndroid Build Coastguard Worker 		err(stderr, "failed to acquire current time\n");
113*49cdfc7eSAndroid Build Coastguard Worker 		exit(1);
114*49cdfc7eSAndroid Build Coastguard Worker 	}
115*49cdfc7eSAndroid Build Coastguard Worker 
116*49cdfc7eSAndroid Build Coastguard Worker 	/* SuSv3 does not define any error conditions for this function.  */
117*49cdfc7eSAndroid Build Coastguard Worker 	global_progname = basename(argv[0]);
118*49cdfc7eSAndroid Build Coastguard Worker 
119*49cdfc7eSAndroid Build Coastguard Worker 	/* For portability, parse command line options without getopt_long.  */
120*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 1; i < argc; i++) {
121*49cdfc7eSAndroid Build Coastguard Worker 		char *arg = argv[i];
122*49cdfc7eSAndroid Build Coastguard Worker 
123*49cdfc7eSAndroid Build Coastguard Worker 		if (strcmp(arg, "--help") == 0 || strcmp(arg, "-?") == 0) {
124*49cdfc7eSAndroid Build Coastguard Worker 			usage(0);
125*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--version") == 0) {
126*49cdfc7eSAndroid Build Coastguard Worker 			version(0);
127*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--verbose") == 0
128*49cdfc7eSAndroid Build Coastguard Worker 			   || strcmp(arg, "-v") == 0) {
129*49cdfc7eSAndroid Build Coastguard Worker 			global_debug = 3;
130*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--quiet") == 0
131*49cdfc7eSAndroid Build Coastguard Worker 			   || strcmp(arg, "-q") == 0) {
132*49cdfc7eSAndroid Build Coastguard Worker 			global_debug = 0;
133*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--dry-run") == 0
134*49cdfc7eSAndroid Build Coastguard Worker 			   || strcmp(arg, "-n") == 0) {
135*49cdfc7eSAndroid Build Coastguard Worker 			do_dryrun = 1;
136*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--no-retry") == 0) {
137*49cdfc7eSAndroid Build Coastguard Worker 			global_ignore = 0;
138*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout,
139*49cdfc7eSAndroid Build Coastguard Worker 			    "turning off ignore of non-critical errors");
140*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--retry-delay") == 0) {
141*49cdfc7eSAndroid Build Coastguard Worker 			assert_arg("--retry-delay");
142*49cdfc7eSAndroid Build Coastguard Worker 			global_retry = atoll(arg);
143*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "setting retry delay to %dus\n",
144*49cdfc7eSAndroid Build Coastguard Worker 			    global_retry);
145*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--backoff") == 0) {
146*49cdfc7eSAndroid Build Coastguard Worker 			assert_arg("--backoff");
147*49cdfc7eSAndroid Build Coastguard Worker 			global_backoff = atoll(arg);
148*49cdfc7eSAndroid Build Coastguard Worker 			if (global_backoff < 0) {
149*49cdfc7eSAndroid Build Coastguard Worker 				err(stderr, "invalid backoff factor: %i\n",
150*49cdfc7eSAndroid Build Coastguard Worker 				    global_backoff);
151*49cdfc7eSAndroid Build Coastguard Worker 				exit(1);
152*49cdfc7eSAndroid Build Coastguard Worker 			}
153*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "setting backoff coeffient to %dus\n",
154*49cdfc7eSAndroid Build Coastguard Worker 			    global_backoff);
155*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--timeout") == 0
156*49cdfc7eSAndroid Build Coastguard Worker 			   || strcmp(arg, "-t") == 0) {
157*49cdfc7eSAndroid Build Coastguard Worker 			do_timeout = 1;
158*49cdfc7eSAndroid Build Coastguard Worker 			assert_arg("--timeout");
159*49cdfc7eSAndroid Build Coastguard Worker 			global_timeout = atoll_s(arg);
160*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "setting timeout to %ds\n", global_timeout);
161*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--cpu") == 0 || strcmp(arg, "-c") == 0) {
162*49cdfc7eSAndroid Build Coastguard Worker 			do_cpu = 1;
163*49cdfc7eSAndroid Build Coastguard Worker 			assert_arg("--cpu");
164*49cdfc7eSAndroid Build Coastguard Worker 			do_cpu_forks = atoll_b(arg);
165*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--io") == 0 || strcmp(arg, "-i") == 0) {
166*49cdfc7eSAndroid Build Coastguard Worker 			do_io = 1;
167*49cdfc7eSAndroid Build Coastguard Worker 			assert_arg("--io");
168*49cdfc7eSAndroid Build Coastguard Worker 			do_io_forks = atoll_b(arg);
169*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--vm") == 0 || strcmp(arg, "-m") == 0) {
170*49cdfc7eSAndroid Build Coastguard Worker 			do_vm = 1;
171*49cdfc7eSAndroid Build Coastguard Worker 			assert_arg("--vm");
172*49cdfc7eSAndroid Build Coastguard Worker 			do_vm_forks = atoll_b(arg);
173*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--vm-chunks") == 0) {
174*49cdfc7eSAndroid Build Coastguard Worker 			assert_arg("--vm-chunks");
175*49cdfc7eSAndroid Build Coastguard Worker 			do_vm_chunks = atoll_b(arg);
176*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--vm-bytes") == 0) {
177*49cdfc7eSAndroid Build Coastguard Worker 			assert_arg("--vm-bytes");
178*49cdfc7eSAndroid Build Coastguard Worker 			do_vm_bytes = atoll_b(arg);
179*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--vm-hang") == 0) {
180*49cdfc7eSAndroid Build Coastguard Worker 			global_vmhang = 1;
181*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--hdd") == 0 || strcmp(arg, "-d") == 0) {
182*49cdfc7eSAndroid Build Coastguard Worker 			do_hdd = 1;
183*49cdfc7eSAndroid Build Coastguard Worker 			assert_arg("--hdd");
184*49cdfc7eSAndroid Build Coastguard Worker 			do_hdd_forks = atoll_b(arg);
185*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--hdd-noclean") == 0) {
186*49cdfc7eSAndroid Build Coastguard Worker 			do_hdd_clean = 2;
187*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--hdd-files") == 0) {
188*49cdfc7eSAndroid Build Coastguard Worker 			assert_arg("--hdd-files");
189*49cdfc7eSAndroid Build Coastguard Worker 			do_hdd_files = atoll_b(arg);
190*49cdfc7eSAndroid Build Coastguard Worker 		} else if (strcmp(arg, "--hdd-bytes") == 0) {
191*49cdfc7eSAndroid Build Coastguard Worker 			assert_arg("--hdd-bytes");
192*49cdfc7eSAndroid Build Coastguard Worker 			do_hdd_bytes = atoll_b(arg);
193*49cdfc7eSAndroid Build Coastguard Worker 		} else {
194*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr, "unrecognized option: %s\n", arg);
195*49cdfc7eSAndroid Build Coastguard Worker 			exit(1);
196*49cdfc7eSAndroid Build Coastguard Worker 		}
197*49cdfc7eSAndroid Build Coastguard Worker 	}
198*49cdfc7eSAndroid Build Coastguard Worker 
199*49cdfc7eSAndroid Build Coastguard Worker 	/* Hog CPU option.  */
200*49cdfc7eSAndroid Build Coastguard Worker 	if (do_cpu) {
201*49cdfc7eSAndroid Build Coastguard Worker 		out(stdout, "dispatching %lli hogcpu forks\n", do_cpu_forks);
202*49cdfc7eSAndroid Build Coastguard Worker 
203*49cdfc7eSAndroid Build Coastguard Worker 		switch (pid = fork()) {
204*49cdfc7eSAndroid Build Coastguard Worker 		case 0:	/* child */
205*49cdfc7eSAndroid Build Coastguard Worker 			if (do_dryrun)
206*49cdfc7eSAndroid Build Coastguard Worker 				exit(0);
207*49cdfc7eSAndroid Build Coastguard Worker 			exit(hogcpu(do_cpu_forks));
208*49cdfc7eSAndroid Build Coastguard Worker 		case -1:	/* error */
209*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr, "hogcpu dispatcher fork failed\n");
210*49cdfc7eSAndroid Build Coastguard Worker 			exit(1);
211*49cdfc7eSAndroid Build Coastguard Worker 		default:	/* parent */
212*49cdfc7eSAndroid Build Coastguard Worker 			children++;
213*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "--> hogcpu dispatcher forked (%i)\n", pid);
214*49cdfc7eSAndroid Build Coastguard Worker 		}
215*49cdfc7eSAndroid Build Coastguard Worker 	}
216*49cdfc7eSAndroid Build Coastguard Worker 
217*49cdfc7eSAndroid Build Coastguard Worker 	/* Hog I/O option.  */
218*49cdfc7eSAndroid Build Coastguard Worker 	if (do_io) {
219*49cdfc7eSAndroid Build Coastguard Worker 		out(stdout, "dispatching %lli hogio forks\n", do_io_forks);
220*49cdfc7eSAndroid Build Coastguard Worker 
221*49cdfc7eSAndroid Build Coastguard Worker 		switch (pid = fork()) {
222*49cdfc7eSAndroid Build Coastguard Worker 		case 0:	/* child */
223*49cdfc7eSAndroid Build Coastguard Worker 			if (do_dryrun)
224*49cdfc7eSAndroid Build Coastguard Worker 				exit(0);
225*49cdfc7eSAndroid Build Coastguard Worker 			exit(hogio(do_io_forks));
226*49cdfc7eSAndroid Build Coastguard Worker 		case -1:	/* error */
227*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr, "hogio dispatcher fork failed\n");
228*49cdfc7eSAndroid Build Coastguard Worker 			exit(1);
229*49cdfc7eSAndroid Build Coastguard Worker 		default:	/* parent */
230*49cdfc7eSAndroid Build Coastguard Worker 			children++;
231*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "--> hogio dispatcher forked (%i)\n", pid);
232*49cdfc7eSAndroid Build Coastguard Worker 		}
233*49cdfc7eSAndroid Build Coastguard Worker 	}
234*49cdfc7eSAndroid Build Coastguard Worker 
235*49cdfc7eSAndroid Build Coastguard Worker 	/* Hog VM option.  */
236*49cdfc7eSAndroid Build Coastguard Worker 	if (do_vm) {
237*49cdfc7eSAndroid Build Coastguard Worker 		out(stdout,
238*49cdfc7eSAndroid Build Coastguard Worker 		    "dispatching %lli hogvm forks, each %lli chunks of %lli bytes\n",
239*49cdfc7eSAndroid Build Coastguard Worker 		    do_vm_forks, do_vm_chunks, do_vm_bytes);
240*49cdfc7eSAndroid Build Coastguard Worker 
241*49cdfc7eSAndroid Build Coastguard Worker 		switch (pid = fork()) {
242*49cdfc7eSAndroid Build Coastguard Worker 		case 0:	/* child */
243*49cdfc7eSAndroid Build Coastguard Worker 			if (do_dryrun)
244*49cdfc7eSAndroid Build Coastguard Worker 				exit(0);
245*49cdfc7eSAndroid Build Coastguard Worker 			exit(hogvm(do_vm_forks, do_vm_chunks, do_vm_bytes));
246*49cdfc7eSAndroid Build Coastguard Worker 		case -1:	/* error */
247*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr, "hogvm dispatcher fork failed\n");
248*49cdfc7eSAndroid Build Coastguard Worker 			exit(1);
249*49cdfc7eSAndroid Build Coastguard Worker 		default:	/* parent */
250*49cdfc7eSAndroid Build Coastguard Worker 			children++;
251*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "--> hogvm dispatcher forked (%i)\n", pid);
252*49cdfc7eSAndroid Build Coastguard Worker 		}
253*49cdfc7eSAndroid Build Coastguard Worker 	}
254*49cdfc7eSAndroid Build Coastguard Worker 
255*49cdfc7eSAndroid Build Coastguard Worker 	/* Hog HDD option.  */
256*49cdfc7eSAndroid Build Coastguard Worker 	if (do_hdd) {
257*49cdfc7eSAndroid Build Coastguard Worker 		out(stdout, "dispatching %lli hoghdd forks, each %lli files of "
258*49cdfc7eSAndroid Build Coastguard Worker 		    "%lli bytes\n", do_hdd_forks, do_hdd_files, do_hdd_bytes);
259*49cdfc7eSAndroid Build Coastguard Worker 
260*49cdfc7eSAndroid Build Coastguard Worker 		switch (pid = fork()) {
261*49cdfc7eSAndroid Build Coastguard Worker 		case 0:	/* child */
262*49cdfc7eSAndroid Build Coastguard Worker 			if (do_dryrun)
263*49cdfc7eSAndroid Build Coastguard Worker 				exit(0);
264*49cdfc7eSAndroid Build Coastguard Worker 			exit(hoghdd
265*49cdfc7eSAndroid Build Coastguard Worker 			     (do_hdd_forks, do_hdd_clean, do_hdd_files,
266*49cdfc7eSAndroid Build Coastguard Worker 			      do_hdd_bytes));
267*49cdfc7eSAndroid Build Coastguard Worker 		case -1:	/* error */
268*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr, "hoghdd dispatcher fork failed\n");
269*49cdfc7eSAndroid Build Coastguard Worker 			exit(1);
270*49cdfc7eSAndroid Build Coastguard Worker 		default:	/* parent */
271*49cdfc7eSAndroid Build Coastguard Worker 			children++;
272*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "--> hoghdd dispatcher forked (%i)\n", pid);
273*49cdfc7eSAndroid Build Coastguard Worker 		}
274*49cdfc7eSAndroid Build Coastguard Worker 	}
275*49cdfc7eSAndroid Build Coastguard Worker 
276*49cdfc7eSAndroid Build Coastguard Worker 	/* We have no work to do, so bail out.  */
277*49cdfc7eSAndroid Build Coastguard Worker 	if (children == 0)
278*49cdfc7eSAndroid Build Coastguard Worker 		usage(0);
279*49cdfc7eSAndroid Build Coastguard Worker 
280*49cdfc7eSAndroid Build Coastguard Worker 	/* Wait for our children to exit.  */
281*49cdfc7eSAndroid Build Coastguard Worker 	while (children) {
282*49cdfc7eSAndroid Build Coastguard Worker 		int status, ret;
283*49cdfc7eSAndroid Build Coastguard Worker 
284*49cdfc7eSAndroid Build Coastguard Worker 		if ((pid = wait(&status)) > 0) {
285*49cdfc7eSAndroid Build Coastguard Worker 			if ((WIFEXITED(status)) != 0) {
286*49cdfc7eSAndroid Build Coastguard Worker 				if ((ret = WEXITSTATUS(status)) != 0) {
287*49cdfc7eSAndroid Build Coastguard Worker 					err(stderr,
288*49cdfc7eSAndroid Build Coastguard Worker 					    "dispatcher %i returned error %i\n",
289*49cdfc7eSAndroid Build Coastguard Worker 					    pid, ret);
290*49cdfc7eSAndroid Build Coastguard Worker 					retval += ret;
291*49cdfc7eSAndroid Build Coastguard Worker 				} else {
292*49cdfc7eSAndroid Build Coastguard Worker 					dbg(stdout,
293*49cdfc7eSAndroid Build Coastguard Worker 					    "<-- dispatcher return (%i)\n",
294*49cdfc7eSAndroid Build Coastguard Worker 					    pid);
295*49cdfc7eSAndroid Build Coastguard Worker 				}
296*49cdfc7eSAndroid Build Coastguard Worker 			} else {
297*49cdfc7eSAndroid Build Coastguard Worker 				err(stderr,
298*49cdfc7eSAndroid Build Coastguard Worker 				    "dispatcher did not exit normally\n");
299*49cdfc7eSAndroid Build Coastguard Worker 				++retval;
300*49cdfc7eSAndroid Build Coastguard Worker 			}
301*49cdfc7eSAndroid Build Coastguard Worker 
302*49cdfc7eSAndroid Build Coastguard Worker 			--children;
303*49cdfc7eSAndroid Build Coastguard Worker 		} else {
304*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "wait() returned error: %s\n",
305*49cdfc7eSAndroid Build Coastguard Worker 			    strerror(errno));
306*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr, "detected missing dispatcher children\n");
307*49cdfc7eSAndroid Build Coastguard Worker 			++retval;
308*49cdfc7eSAndroid Build Coastguard Worker 			break;
309*49cdfc7eSAndroid Build Coastguard Worker 		}
310*49cdfc7eSAndroid Build Coastguard Worker 	}
311*49cdfc7eSAndroid Build Coastguard Worker 
312*49cdfc7eSAndroid Build Coastguard Worker 	/* Record our stop time.  */
313*49cdfc7eSAndroid Build Coastguard Worker 	if ((stoptime = time(NULL)) == -1) {
314*49cdfc7eSAndroid Build Coastguard Worker 		err(stderr, "failed to acquire current time\n");
315*49cdfc7eSAndroid Build Coastguard Worker 		exit(1);
316*49cdfc7eSAndroid Build Coastguard Worker 	}
317*49cdfc7eSAndroid Build Coastguard Worker 
318*49cdfc7eSAndroid Build Coastguard Worker 	/* Calculate our runtime.  */
319*49cdfc7eSAndroid Build Coastguard Worker 	runtime = stoptime - starttime;
320*49cdfc7eSAndroid Build Coastguard Worker 
321*49cdfc7eSAndroid Build Coastguard Worker 	/* Print final status message.  */
322*49cdfc7eSAndroid Build Coastguard Worker 	if (retval) {
323*49cdfc7eSAndroid Build Coastguard Worker 		err(stderr, "failed run completed in %lis\n", runtime);
324*49cdfc7eSAndroid Build Coastguard Worker 	} else {
325*49cdfc7eSAndroid Build Coastguard Worker 		out(stdout, "successful run completed in %lis\n", runtime);
326*49cdfc7eSAndroid Build Coastguard Worker 	}
327*49cdfc7eSAndroid Build Coastguard Worker 
328*49cdfc7eSAndroid Build Coastguard Worker 	exit(retval);
329*49cdfc7eSAndroid Build Coastguard Worker }
330*49cdfc7eSAndroid Build Coastguard Worker 
usage(int status)331*49cdfc7eSAndroid Build Coastguard Worker int usage(int status)
332*49cdfc7eSAndroid Build Coastguard Worker {
333*49cdfc7eSAndroid Build Coastguard Worker 	char *mesg =
334*49cdfc7eSAndroid Build Coastguard Worker 	    "`%s' imposes certain types of compute stress on your system\n\n"
335*49cdfc7eSAndroid Build Coastguard Worker 	    "Usage: %s [OPTION [ARG]] ...\n\n"
336*49cdfc7eSAndroid Build Coastguard Worker 	    " -?, --help            show this help statement\n"
337*49cdfc7eSAndroid Build Coastguard Worker 	    "     --version         show version statement\n"
338*49cdfc7eSAndroid Build Coastguard Worker 	    " -v, --verbose         be verbose\n"
339*49cdfc7eSAndroid Build Coastguard Worker 	    " -q, --quiet           be quiet\n"
340*49cdfc7eSAndroid Build Coastguard Worker 	    " -n, --dry-run         show what would have been done\n"
341*49cdfc7eSAndroid Build Coastguard Worker 	    "     --no-retry        exit rather than retry non-critical errors\n"
342*49cdfc7eSAndroid Build Coastguard Worker 	    "     --retry-delay n   wait n us before continuing past error\n"
343*49cdfc7eSAndroid Build Coastguard Worker 	    " -t, --timeout n       timeout after n seconds\n"
344*49cdfc7eSAndroid Build Coastguard Worker 	    "     --backoff n       wait for factor of n us before starting work\n"
345*49cdfc7eSAndroid Build Coastguard Worker 	    " -c, --cpu n           spawn n procs spinning on sqrt()\n"
346*49cdfc7eSAndroid Build Coastguard Worker 	    " -i, --io n            spawn n procs spinning on sync()\n"
347*49cdfc7eSAndroid Build Coastguard Worker 	    " -m, --vm n            spawn n procs spinning on malloc()\n"
348*49cdfc7eSAndroid Build Coastguard Worker 	    "     --vm-chunks c     malloc c chunks (default is 1)\n"
349*49cdfc7eSAndroid Build Coastguard Worker 	    "     --vm-bytes b      malloc chunks of b bytes (default is 256MB)\n"
350*49cdfc7eSAndroid Build Coastguard Worker 	    "     --vm-hang         hang in a sleep loop after memory allocated\n"
351*49cdfc7eSAndroid Build Coastguard Worker 	    " -d, --hdd n           spawn n procs spinning on write()\n"
352*49cdfc7eSAndroid Build Coastguard Worker 	    "     --hdd-noclean     do not unlink file to which random data written\n"
353*49cdfc7eSAndroid Build Coastguard Worker 	    "     --hdd-files f     write to f files (default is 1)\n"
354*49cdfc7eSAndroid Build Coastguard Worker 	    "     --hdd-bytes b     write b bytes (default is 1GB)\n\n"
355*49cdfc7eSAndroid Build Coastguard Worker 	    "Infinity is denoted with 0.  For -m, -d: n=0 means infinite redo,\n"
356*49cdfc7eSAndroid Build Coastguard Worker 	    "n<0 means redo abs(n) times. Valid suffixes are m,h,d,y for time;\n"
357*49cdfc7eSAndroid Build Coastguard Worker 	    "k,m,g for size.\n\n";
358*49cdfc7eSAndroid Build Coastguard Worker 
359*49cdfc7eSAndroid Build Coastguard Worker 	fprintf(stdout, mesg, global_progname, global_progname);
360*49cdfc7eSAndroid Build Coastguard Worker 
361*49cdfc7eSAndroid Build Coastguard Worker 	if (status <= 0)
362*49cdfc7eSAndroid Build Coastguard Worker 		exit(-1 * status);
363*49cdfc7eSAndroid Build Coastguard Worker 
364*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
365*49cdfc7eSAndroid Build Coastguard Worker }
366*49cdfc7eSAndroid Build Coastguard Worker 
version(int status)367*49cdfc7eSAndroid Build Coastguard Worker int version(int status)
368*49cdfc7eSAndroid Build Coastguard Worker {
369*49cdfc7eSAndroid Build Coastguard Worker 	char *mesg = "%s %s\n";
370*49cdfc7eSAndroid Build Coastguard Worker 
371*49cdfc7eSAndroid Build Coastguard Worker 	fprintf(stdout, mesg, global_progname, VERSION);
372*49cdfc7eSAndroid Build Coastguard Worker 
373*49cdfc7eSAndroid Build Coastguard Worker 	if (status <= 0)
374*49cdfc7eSAndroid Build Coastguard Worker 		exit(-1 * status);
375*49cdfc7eSAndroid Build Coastguard Worker 
376*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
377*49cdfc7eSAndroid Build Coastguard Worker }
378*49cdfc7eSAndroid Build Coastguard Worker 
379*49cdfc7eSAndroid Build Coastguard Worker /* Convert a string representation of a number with an optional size suffix
380*49cdfc7eSAndroid Build Coastguard Worker  * to a long long.
381*49cdfc7eSAndroid Build Coastguard Worker  */
atoll_b(const char * nptr)382*49cdfc7eSAndroid Build Coastguard Worker long long atoll_b(const char *nptr)
383*49cdfc7eSAndroid Build Coastguard Worker {
384*49cdfc7eSAndroid Build Coastguard Worker 	int pos;
385*49cdfc7eSAndroid Build Coastguard Worker 	char suffix;
386*49cdfc7eSAndroid Build Coastguard Worker 	long long factor = 1;
387*49cdfc7eSAndroid Build Coastguard Worker 
388*49cdfc7eSAndroid Build Coastguard Worker 	if ((pos = strlen(nptr) - 1) < 0) {
389*49cdfc7eSAndroid Build Coastguard Worker 		err(stderr, "invalid string\n");
390*49cdfc7eSAndroid Build Coastguard Worker 		exit(1);
391*49cdfc7eSAndroid Build Coastguard Worker 	}
392*49cdfc7eSAndroid Build Coastguard Worker 
393*49cdfc7eSAndroid Build Coastguard Worker 	switch (suffix = nptr[pos]) {
394*49cdfc7eSAndroid Build Coastguard Worker 	case 'k':
395*49cdfc7eSAndroid Build Coastguard Worker 	case 'K':
396*49cdfc7eSAndroid Build Coastguard Worker 		factor = 1024;
397*49cdfc7eSAndroid Build Coastguard Worker 		break;
398*49cdfc7eSAndroid Build Coastguard Worker 	case 'm':
399*49cdfc7eSAndroid Build Coastguard Worker 	case 'M':
400*49cdfc7eSAndroid Build Coastguard Worker 		factor = 1024 * 1024;
401*49cdfc7eSAndroid Build Coastguard Worker 		break;
402*49cdfc7eSAndroid Build Coastguard Worker 	case 'g':
403*49cdfc7eSAndroid Build Coastguard Worker 	case 'G':
404*49cdfc7eSAndroid Build Coastguard Worker 		factor = 1024 * 1024 * 1024;
405*49cdfc7eSAndroid Build Coastguard Worker 		break;
406*49cdfc7eSAndroid Build Coastguard Worker 	default:
407*49cdfc7eSAndroid Build Coastguard Worker 		if (suffix < '0' || suffix > '9') {
408*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr, "unrecognized suffix: %c\n", suffix);
409*49cdfc7eSAndroid Build Coastguard Worker 			exit(1);
410*49cdfc7eSAndroid Build Coastguard Worker 		}
411*49cdfc7eSAndroid Build Coastguard Worker 	}
412*49cdfc7eSAndroid Build Coastguard Worker 
413*49cdfc7eSAndroid Build Coastguard Worker 	factor = atoll(nptr) * factor;
414*49cdfc7eSAndroid Build Coastguard Worker 
415*49cdfc7eSAndroid Build Coastguard Worker 	return factor;
416*49cdfc7eSAndroid Build Coastguard Worker }
417*49cdfc7eSAndroid Build Coastguard Worker 
418*49cdfc7eSAndroid Build Coastguard Worker /* Convert a string representation of a number with an optional time suffix
419*49cdfc7eSAndroid Build Coastguard Worker  * to a long long.
420*49cdfc7eSAndroid Build Coastguard Worker  */
atoll_s(const char * nptr)421*49cdfc7eSAndroid Build Coastguard Worker long long atoll_s(const char *nptr)
422*49cdfc7eSAndroid Build Coastguard Worker {
423*49cdfc7eSAndroid Build Coastguard Worker 	int pos;
424*49cdfc7eSAndroid Build Coastguard Worker 	char suffix;
425*49cdfc7eSAndroid Build Coastguard Worker 	long long factor = 1;
426*49cdfc7eSAndroid Build Coastguard Worker 
427*49cdfc7eSAndroid Build Coastguard Worker 	if ((pos = strlen(nptr) - 1) < 0) {
428*49cdfc7eSAndroid Build Coastguard Worker 		err(stderr, "invalid string\n");
429*49cdfc7eSAndroid Build Coastguard Worker 		exit(1);
430*49cdfc7eSAndroid Build Coastguard Worker 	}
431*49cdfc7eSAndroid Build Coastguard Worker 
432*49cdfc7eSAndroid Build Coastguard Worker 	switch (suffix = nptr[pos]) {
433*49cdfc7eSAndroid Build Coastguard Worker 	case 's':
434*49cdfc7eSAndroid Build Coastguard Worker 	case 'S':
435*49cdfc7eSAndroid Build Coastguard Worker 		factor = 1;
436*49cdfc7eSAndroid Build Coastguard Worker 		break;
437*49cdfc7eSAndroid Build Coastguard Worker 	case 'm':
438*49cdfc7eSAndroid Build Coastguard Worker 	case 'M':
439*49cdfc7eSAndroid Build Coastguard Worker 		factor = 60;
440*49cdfc7eSAndroid Build Coastguard Worker 		break;
441*49cdfc7eSAndroid Build Coastguard Worker 	case 'h':
442*49cdfc7eSAndroid Build Coastguard Worker 	case 'H':
443*49cdfc7eSAndroid Build Coastguard Worker 		factor = 60 * 60;
444*49cdfc7eSAndroid Build Coastguard Worker 		break;
445*49cdfc7eSAndroid Build Coastguard Worker 	case 'd':
446*49cdfc7eSAndroid Build Coastguard Worker 	case 'D':
447*49cdfc7eSAndroid Build Coastguard Worker 		factor = 60 * 60 * 24;
448*49cdfc7eSAndroid Build Coastguard Worker 		break;
449*49cdfc7eSAndroid Build Coastguard Worker 	case 'y':
450*49cdfc7eSAndroid Build Coastguard Worker 	case 'Y':
451*49cdfc7eSAndroid Build Coastguard Worker 		factor = 60 * 60 * 24 * 360;
452*49cdfc7eSAndroid Build Coastguard Worker 		break;
453*49cdfc7eSAndroid Build Coastguard Worker 	default:
454*49cdfc7eSAndroid Build Coastguard Worker 		if (suffix < '0' || suffix > '9') {
455*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr, "unrecognized suffix: %c\n", suffix);
456*49cdfc7eSAndroid Build Coastguard Worker 			exit(1);
457*49cdfc7eSAndroid Build Coastguard Worker 		}
458*49cdfc7eSAndroid Build Coastguard Worker 	}
459*49cdfc7eSAndroid Build Coastguard Worker 
460*49cdfc7eSAndroid Build Coastguard Worker 	factor = atoll(nptr) * factor;
461*49cdfc7eSAndroid Build Coastguard Worker 
462*49cdfc7eSAndroid Build Coastguard Worker 	return factor;
463*49cdfc7eSAndroid Build Coastguard Worker }
464*49cdfc7eSAndroid Build Coastguard Worker 
hogcpu(long long forks)465*49cdfc7eSAndroid Build Coastguard Worker int hogcpu(long long forks)
466*49cdfc7eSAndroid Build Coastguard Worker {
467*49cdfc7eSAndroid Build Coastguard Worker 	long long i;
468*49cdfc7eSAndroid Build Coastguard Worker 	double d;
469*49cdfc7eSAndroid Build Coastguard Worker 	int pid, retval = 0;
470*49cdfc7eSAndroid Build Coastguard Worker 
471*49cdfc7eSAndroid Build Coastguard Worker 	/* Make local copies of global variables.  */
472*49cdfc7eSAndroid Build Coastguard Worker 	int ignore = global_ignore;
473*49cdfc7eSAndroid Build Coastguard Worker 	int retry = global_retry;
474*49cdfc7eSAndroid Build Coastguard Worker 	int timeout = global_timeout;
475*49cdfc7eSAndroid Build Coastguard Worker 	long backoff = global_backoff * forks;
476*49cdfc7eSAndroid Build Coastguard Worker 
477*49cdfc7eSAndroid Build Coastguard Worker 	dbg(stdout, "using backoff sleep of %lius for hogcpu\n", backoff);
478*49cdfc7eSAndroid Build Coastguard Worker 
479*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; forks == 0 || i < forks; i++) {
480*49cdfc7eSAndroid Build Coastguard Worker 		switch (pid = fork()) {
481*49cdfc7eSAndroid Build Coastguard Worker 		case 0:	/* child */
482*49cdfc7eSAndroid Build Coastguard Worker 			alarm(timeout);
483*49cdfc7eSAndroid Build Coastguard Worker 
484*49cdfc7eSAndroid Build Coastguard Worker 			/* Use a backoff sleep to ensure we get good fork throughput.  */
485*49cdfc7eSAndroid Build Coastguard Worker 			usleep(backoff);
486*49cdfc7eSAndroid Build Coastguard Worker 
487*49cdfc7eSAndroid Build Coastguard Worker 			while (1)
488*49cdfc7eSAndroid Build Coastguard Worker 				d = sqrt(rand());
489*49cdfc7eSAndroid Build Coastguard Worker 
490*49cdfc7eSAndroid Build Coastguard Worker 			/* This case never falls through; alarm signal can cause exit.  */
491*49cdfc7eSAndroid Build Coastguard Worker 		case -1:	/* error */
492*49cdfc7eSAndroid Build Coastguard Worker 			if (ignore) {
493*49cdfc7eSAndroid Build Coastguard Worker 				++retval;
494*49cdfc7eSAndroid Build Coastguard Worker 				wrn(stderr,
495*49cdfc7eSAndroid Build Coastguard Worker 				    "hogcpu worker fork failed, continuing\n");
496*49cdfc7eSAndroid Build Coastguard Worker 				usleep(retry);
497*49cdfc7eSAndroid Build Coastguard Worker 				continue;
498*49cdfc7eSAndroid Build Coastguard Worker 			}
499*49cdfc7eSAndroid Build Coastguard Worker 
500*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr, "hogcpu worker fork failed\n");
501*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
502*49cdfc7eSAndroid Build Coastguard Worker 		default:	/* parent */
503*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "--> hogcpu worker forked (%i)\n", pid);
504*49cdfc7eSAndroid Build Coastguard Worker 		}
505*49cdfc7eSAndroid Build Coastguard Worker 	}
506*49cdfc7eSAndroid Build Coastguard Worker 
507*49cdfc7eSAndroid Build Coastguard Worker 	/* Wait for our children to exit.  */
508*49cdfc7eSAndroid Build Coastguard Worker 	while (i) {
509*49cdfc7eSAndroid Build Coastguard Worker 		int status, ret;
510*49cdfc7eSAndroid Build Coastguard Worker 
511*49cdfc7eSAndroid Build Coastguard Worker 		if ((pid = wait(&status)) > 0) {
512*49cdfc7eSAndroid Build Coastguard Worker 			if ((WIFEXITED(status)) != 0) {
513*49cdfc7eSAndroid Build Coastguard Worker 				if ((ret = WEXITSTATUS(status)) != 0) {
514*49cdfc7eSAndroid Build Coastguard Worker 					err(stderr,
515*49cdfc7eSAndroid Build Coastguard Worker 					    "hogcpu worker %i exited %i\n", pid,
516*49cdfc7eSAndroid Build Coastguard Worker 					    ret);
517*49cdfc7eSAndroid Build Coastguard Worker 					retval += ret;
518*49cdfc7eSAndroid Build Coastguard Worker 				} else {
519*49cdfc7eSAndroid Build Coastguard Worker 					dbg(stdout,
520*49cdfc7eSAndroid Build Coastguard Worker 					    "<-- hogcpu worker exited (%i)\n",
521*49cdfc7eSAndroid Build Coastguard Worker 					    pid);
522*49cdfc7eSAndroid Build Coastguard Worker 				}
523*49cdfc7eSAndroid Build Coastguard Worker 			} else {
524*49cdfc7eSAndroid Build Coastguard Worker 				dbg(stdout,
525*49cdfc7eSAndroid Build Coastguard Worker 				    "<-- hogcpu worker signalled (%i)\n", pid);
526*49cdfc7eSAndroid Build Coastguard Worker 			}
527*49cdfc7eSAndroid Build Coastguard Worker 
528*49cdfc7eSAndroid Build Coastguard Worker 			--i;
529*49cdfc7eSAndroid Build Coastguard Worker 		} else {
530*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "wait() returned error: %s\n",
531*49cdfc7eSAndroid Build Coastguard Worker 			    strerror(errno));
532*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr,
533*49cdfc7eSAndroid Build Coastguard Worker 			    "detected missing hogcpu worker children\n");
534*49cdfc7eSAndroid Build Coastguard Worker 			++retval;
535*49cdfc7eSAndroid Build Coastguard Worker 			break;
536*49cdfc7eSAndroid Build Coastguard Worker 		}
537*49cdfc7eSAndroid Build Coastguard Worker 	}
538*49cdfc7eSAndroid Build Coastguard Worker 
539*49cdfc7eSAndroid Build Coastguard Worker 	return retval;
540*49cdfc7eSAndroid Build Coastguard Worker }
541*49cdfc7eSAndroid Build Coastguard Worker 
hogio(long long forks)542*49cdfc7eSAndroid Build Coastguard Worker int hogio(long long forks)
543*49cdfc7eSAndroid Build Coastguard Worker {
544*49cdfc7eSAndroid Build Coastguard Worker 	long long i;
545*49cdfc7eSAndroid Build Coastguard Worker 	int pid, retval = 0;
546*49cdfc7eSAndroid Build Coastguard Worker 
547*49cdfc7eSAndroid Build Coastguard Worker 	/* Make local copies of global variables.  */
548*49cdfc7eSAndroid Build Coastguard Worker 	int ignore = global_ignore;
549*49cdfc7eSAndroid Build Coastguard Worker 	int retry = global_retry;
550*49cdfc7eSAndroid Build Coastguard Worker 	int timeout = global_timeout;
551*49cdfc7eSAndroid Build Coastguard Worker 	long backoff = global_backoff * forks;
552*49cdfc7eSAndroid Build Coastguard Worker 
553*49cdfc7eSAndroid Build Coastguard Worker 	dbg(stdout, "using backoff sleep of %lius for hogio\n", backoff);
554*49cdfc7eSAndroid Build Coastguard Worker 
555*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; forks == 0 || i < forks; i++) {
556*49cdfc7eSAndroid Build Coastguard Worker 		switch (pid = fork()) {
557*49cdfc7eSAndroid Build Coastguard Worker 		case 0:	/* child */
558*49cdfc7eSAndroid Build Coastguard Worker 			alarm(timeout);
559*49cdfc7eSAndroid Build Coastguard Worker 
560*49cdfc7eSAndroid Build Coastguard Worker 			/* Use a backoff sleep to ensure we get good fork throughput.  */
561*49cdfc7eSAndroid Build Coastguard Worker 			usleep(backoff);
562*49cdfc7eSAndroid Build Coastguard Worker 
563*49cdfc7eSAndroid Build Coastguard Worker 			while (1)
564*49cdfc7eSAndroid Build Coastguard Worker 				sync();
565*49cdfc7eSAndroid Build Coastguard Worker 
566*49cdfc7eSAndroid Build Coastguard Worker 			/* This case never falls through; alarm signal can cause exit.  */
567*49cdfc7eSAndroid Build Coastguard Worker 		case -1:	/* error */
568*49cdfc7eSAndroid Build Coastguard Worker 			if (ignore) {
569*49cdfc7eSAndroid Build Coastguard Worker 				++retval;
570*49cdfc7eSAndroid Build Coastguard Worker 				wrn(stderr,
571*49cdfc7eSAndroid Build Coastguard Worker 				    "hogio worker fork failed, continuing\n");
572*49cdfc7eSAndroid Build Coastguard Worker 				usleep(retry);
573*49cdfc7eSAndroid Build Coastguard Worker 				continue;
574*49cdfc7eSAndroid Build Coastguard Worker 			}
575*49cdfc7eSAndroid Build Coastguard Worker 
576*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr, "hogio worker fork failed\n");
577*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
578*49cdfc7eSAndroid Build Coastguard Worker 		default:	/* parent */
579*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "--> hogio worker forked (%i)\n", pid);
580*49cdfc7eSAndroid Build Coastguard Worker 		}
581*49cdfc7eSAndroid Build Coastguard Worker 	}
582*49cdfc7eSAndroid Build Coastguard Worker 
583*49cdfc7eSAndroid Build Coastguard Worker 	/* Wait for our children to exit.  */
584*49cdfc7eSAndroid Build Coastguard Worker 	while (i) {
585*49cdfc7eSAndroid Build Coastguard Worker 		int status, ret;
586*49cdfc7eSAndroid Build Coastguard Worker 
587*49cdfc7eSAndroid Build Coastguard Worker 		if ((pid = wait(&status)) > 0) {
588*49cdfc7eSAndroid Build Coastguard Worker 			if ((WIFEXITED(status)) != 0) {
589*49cdfc7eSAndroid Build Coastguard Worker 				if ((ret = WEXITSTATUS(status)) != 0) {
590*49cdfc7eSAndroid Build Coastguard Worker 					err(stderr,
591*49cdfc7eSAndroid Build Coastguard Worker 					    "hogio worker %i exited %i\n", pid,
592*49cdfc7eSAndroid Build Coastguard Worker 					    ret);
593*49cdfc7eSAndroid Build Coastguard Worker 					retval += ret;
594*49cdfc7eSAndroid Build Coastguard Worker 				} else {
595*49cdfc7eSAndroid Build Coastguard Worker 					dbg(stdout,
596*49cdfc7eSAndroid Build Coastguard Worker 					    "<-- hogio worker exited (%i)\n",
597*49cdfc7eSAndroid Build Coastguard Worker 					    pid);
598*49cdfc7eSAndroid Build Coastguard Worker 				}
599*49cdfc7eSAndroid Build Coastguard Worker 			} else {
600*49cdfc7eSAndroid Build Coastguard Worker 				dbg(stdout, "<-- hogio worker signalled (%i)\n",
601*49cdfc7eSAndroid Build Coastguard Worker 				    pid);
602*49cdfc7eSAndroid Build Coastguard Worker 			}
603*49cdfc7eSAndroid Build Coastguard Worker 
604*49cdfc7eSAndroid Build Coastguard Worker 			--i;
605*49cdfc7eSAndroid Build Coastguard Worker 		} else {
606*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "wait() returned error: %s\n",
607*49cdfc7eSAndroid Build Coastguard Worker 			    strerror(errno));
608*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr, "detected missing hogio worker children\n");
609*49cdfc7eSAndroid Build Coastguard Worker 			++retval;
610*49cdfc7eSAndroid Build Coastguard Worker 			break;
611*49cdfc7eSAndroid Build Coastguard Worker 		}
612*49cdfc7eSAndroid Build Coastguard Worker 	}
613*49cdfc7eSAndroid Build Coastguard Worker 
614*49cdfc7eSAndroid Build Coastguard Worker 	return retval;
615*49cdfc7eSAndroid Build Coastguard Worker }
616*49cdfc7eSAndroid Build Coastguard Worker 
hogvm(long long forks,long long chunks,long long bytes)617*49cdfc7eSAndroid Build Coastguard Worker int hogvm(long long forks, long long chunks, long long bytes)
618*49cdfc7eSAndroid Build Coastguard Worker {
619*49cdfc7eSAndroid Build Coastguard Worker 	long long i, j, k;
620*49cdfc7eSAndroid Build Coastguard Worker 	int pid, retval = 0;
621*49cdfc7eSAndroid Build Coastguard Worker 	char **ptr;
622*49cdfc7eSAndroid Build Coastguard Worker 
623*49cdfc7eSAndroid Build Coastguard Worker 	/* Make local copies of global variables.  */
624*49cdfc7eSAndroid Build Coastguard Worker 	int ignore = global_ignore;
625*49cdfc7eSAndroid Build Coastguard Worker 	int retry = global_retry;
626*49cdfc7eSAndroid Build Coastguard Worker 	int timeout = global_timeout;
627*49cdfc7eSAndroid Build Coastguard Worker 	long backoff = global_backoff * forks;
628*49cdfc7eSAndroid Build Coastguard Worker 
629*49cdfc7eSAndroid Build Coastguard Worker 	dbg(stdout, "using backoff sleep of %lius for hogvm\n", backoff);
630*49cdfc7eSAndroid Build Coastguard Worker 
631*49cdfc7eSAndroid Build Coastguard Worker 	if (bytes == 0) {
632*49cdfc7eSAndroid Build Coastguard Worker 		/* 512MB is guess at the largest value can than be malloced at once.  */
633*49cdfc7eSAndroid Build Coastguard Worker 		bytes = 512 * 1024 * 1024;
634*49cdfc7eSAndroid Build Coastguard Worker 	}
635*49cdfc7eSAndroid Build Coastguard Worker 
636*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; forks == 0 || i < forks; i++) {
637*49cdfc7eSAndroid Build Coastguard Worker 		switch (pid = fork()) {
638*49cdfc7eSAndroid Build Coastguard Worker 		case 0:	/* child */
639*49cdfc7eSAndroid Build Coastguard Worker 			alarm(timeout);
640*49cdfc7eSAndroid Build Coastguard Worker 
641*49cdfc7eSAndroid Build Coastguard Worker 			/* Use a backoff sleep to ensure we get good fork throughput.  */
642*49cdfc7eSAndroid Build Coastguard Worker 			usleep(backoff);
643*49cdfc7eSAndroid Build Coastguard Worker 
644*49cdfc7eSAndroid Build Coastguard Worker 			while (1) {
645*49cdfc7eSAndroid Build Coastguard Worker 				ptr = (char **)malloc(chunks * 2);
646*49cdfc7eSAndroid Build Coastguard Worker 				for (j = 0; chunks == 0 || j < chunks; j++) {
647*49cdfc7eSAndroid Build Coastguard Worker 					if ((ptr[j] =
648*49cdfc7eSAndroid Build Coastguard Worker 					     (char *)malloc(bytes *
649*49cdfc7eSAndroid Build Coastguard Worker 							    sizeof(char)))) {
650*49cdfc7eSAndroid Build Coastguard Worker 						for (k = 0; k < bytes; k++)
651*49cdfc7eSAndroid Build Coastguard Worker 							ptr[j][k] = 'Z';	/* Ensure that COW happens.  */
652*49cdfc7eSAndroid Build Coastguard Worker 						dbg(stdout,
653*49cdfc7eSAndroid Build Coastguard Worker 						    "hogvm worker malloced %lli bytes\n",
654*49cdfc7eSAndroid Build Coastguard Worker 						    k);
655*49cdfc7eSAndroid Build Coastguard Worker 					} else if (ignore) {
656*49cdfc7eSAndroid Build Coastguard Worker 						++retval;
657*49cdfc7eSAndroid Build Coastguard Worker 						wrn(stderr,
658*49cdfc7eSAndroid Build Coastguard Worker 						    "hogvm malloc failed, continuing\n");
659*49cdfc7eSAndroid Build Coastguard Worker 						usleep(retry);
660*49cdfc7eSAndroid Build Coastguard Worker 						continue;
661*49cdfc7eSAndroid Build Coastguard Worker 					} else {
662*49cdfc7eSAndroid Build Coastguard Worker 						++retval;
663*49cdfc7eSAndroid Build Coastguard Worker 						err(stderr,
664*49cdfc7eSAndroid Build Coastguard Worker 						    "hogvm malloc failed\n");
665*49cdfc7eSAndroid Build Coastguard Worker 						break;
666*49cdfc7eSAndroid Build Coastguard Worker 					}
667*49cdfc7eSAndroid Build Coastguard Worker 				}
668*49cdfc7eSAndroid Build Coastguard Worker 				if (global_vmhang && retval == 0) {
669*49cdfc7eSAndroid Build Coastguard Worker 					dbg(stdout,
670*49cdfc7eSAndroid Build Coastguard Worker 					    "sleeping forever with allocated memory\n");
671*49cdfc7eSAndroid Build Coastguard Worker 					while (1)
672*49cdfc7eSAndroid Build Coastguard Worker 						sleep(1024);
673*49cdfc7eSAndroid Build Coastguard Worker 				}
674*49cdfc7eSAndroid Build Coastguard Worker 				if (retval == 0) {
675*49cdfc7eSAndroid Build Coastguard Worker 					dbg(stdout,
676*49cdfc7eSAndroid Build Coastguard Worker 					    "hogvm worker freeing memory and starting over\n");
677*49cdfc7eSAndroid Build Coastguard Worker 					for (j = 0; chunks == 0 || j < chunks;
678*49cdfc7eSAndroid Build Coastguard Worker 					     j++) {
679*49cdfc7eSAndroid Build Coastguard Worker 						free(ptr[j]);
680*49cdfc7eSAndroid Build Coastguard Worker 					}
681*49cdfc7eSAndroid Build Coastguard Worker 					free(ptr);
682*49cdfc7eSAndroid Build Coastguard Worker 					continue;
683*49cdfc7eSAndroid Build Coastguard Worker 				}
684*49cdfc7eSAndroid Build Coastguard Worker 
685*49cdfc7eSAndroid Build Coastguard Worker 				exit(retval);
686*49cdfc7eSAndroid Build Coastguard Worker 			}
687*49cdfc7eSAndroid Build Coastguard Worker 
688*49cdfc7eSAndroid Build Coastguard Worker 			/* This case never falls through; alarm signal can cause exit.  */
689*49cdfc7eSAndroid Build Coastguard Worker 		case -1:	/* error */
690*49cdfc7eSAndroid Build Coastguard Worker 			if (ignore) {
691*49cdfc7eSAndroid Build Coastguard Worker 				++retval;
692*49cdfc7eSAndroid Build Coastguard Worker 				wrn(stderr,
693*49cdfc7eSAndroid Build Coastguard Worker 				    "hogvm worker fork failed, continuing\n");
694*49cdfc7eSAndroid Build Coastguard Worker 				usleep(retry);
695*49cdfc7eSAndroid Build Coastguard Worker 				continue;
696*49cdfc7eSAndroid Build Coastguard Worker 			}
697*49cdfc7eSAndroid Build Coastguard Worker 
698*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr, "hogvm worker fork failed\n");
699*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
700*49cdfc7eSAndroid Build Coastguard Worker 		default:	/* parent */
701*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "--> hogvm worker forked (%i)\n", pid);
702*49cdfc7eSAndroid Build Coastguard Worker 		}
703*49cdfc7eSAndroid Build Coastguard Worker 	}
704*49cdfc7eSAndroid Build Coastguard Worker 
705*49cdfc7eSAndroid Build Coastguard Worker 	/* Wait for our children to exit.  */
706*49cdfc7eSAndroid Build Coastguard Worker 	while (i) {
707*49cdfc7eSAndroid Build Coastguard Worker 		int status, ret;
708*49cdfc7eSAndroid Build Coastguard Worker 
709*49cdfc7eSAndroid Build Coastguard Worker 		if ((pid = wait(&status)) > 0) {
710*49cdfc7eSAndroid Build Coastguard Worker 			if ((WIFEXITED(status)) != 0) {
711*49cdfc7eSAndroid Build Coastguard Worker 				if ((ret = WEXITSTATUS(status)) != 0) {
712*49cdfc7eSAndroid Build Coastguard Worker 					err(stderr,
713*49cdfc7eSAndroid Build Coastguard Worker 					    "hogvm worker %i exited %i\n", pid,
714*49cdfc7eSAndroid Build Coastguard Worker 					    ret);
715*49cdfc7eSAndroid Build Coastguard Worker 					retval += ret;
716*49cdfc7eSAndroid Build Coastguard Worker 				} else {
717*49cdfc7eSAndroid Build Coastguard Worker 					dbg(stdout,
718*49cdfc7eSAndroid Build Coastguard Worker 					    "<-- hogvm worker exited (%i)\n",
719*49cdfc7eSAndroid Build Coastguard Worker 					    pid);
720*49cdfc7eSAndroid Build Coastguard Worker 				}
721*49cdfc7eSAndroid Build Coastguard Worker 			} else {
722*49cdfc7eSAndroid Build Coastguard Worker 				dbg(stdout, "<-- hogvm worker signalled (%i)\n",
723*49cdfc7eSAndroid Build Coastguard Worker 				    pid);
724*49cdfc7eSAndroid Build Coastguard Worker 			}
725*49cdfc7eSAndroid Build Coastguard Worker 
726*49cdfc7eSAndroid Build Coastguard Worker 			--i;
727*49cdfc7eSAndroid Build Coastguard Worker 		} else {
728*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "wait() returned error: %s\n",
729*49cdfc7eSAndroid Build Coastguard Worker 			    strerror(errno));
730*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr, "detected missing hogvm worker children\n");
731*49cdfc7eSAndroid Build Coastguard Worker 			++retval;
732*49cdfc7eSAndroid Build Coastguard Worker 			break;
733*49cdfc7eSAndroid Build Coastguard Worker 		}
734*49cdfc7eSAndroid Build Coastguard Worker 	}
735*49cdfc7eSAndroid Build Coastguard Worker 
736*49cdfc7eSAndroid Build Coastguard Worker 	return retval;
737*49cdfc7eSAndroid Build Coastguard Worker }
738*49cdfc7eSAndroid Build Coastguard Worker 
hoghdd(long long forks,int clean,long long files,long long bytes)739*49cdfc7eSAndroid Build Coastguard Worker int hoghdd(long long forks, int clean, long long files, long long bytes)
740*49cdfc7eSAndroid Build Coastguard Worker {
741*49cdfc7eSAndroid Build Coastguard Worker 	long long i, j;
742*49cdfc7eSAndroid Build Coastguard Worker 	int fd, pid, retval = 0;
743*49cdfc7eSAndroid Build Coastguard Worker 	int chunk = (1024 * 1024) - 1;	/* Minimize slow writing.  */
744*49cdfc7eSAndroid Build Coastguard Worker 	char buff[chunk];
745*49cdfc7eSAndroid Build Coastguard Worker 
746*49cdfc7eSAndroid Build Coastguard Worker 	/* Make local copies of global variables.  */
747*49cdfc7eSAndroid Build Coastguard Worker 	int ignore = global_ignore;
748*49cdfc7eSAndroid Build Coastguard Worker 	int retry = global_retry;
749*49cdfc7eSAndroid Build Coastguard Worker 	int timeout = global_timeout;
750*49cdfc7eSAndroid Build Coastguard Worker 	long backoff = global_backoff * forks;
751*49cdfc7eSAndroid Build Coastguard Worker 
752*49cdfc7eSAndroid Build Coastguard Worker 	/* Initialize buffer with some random ASCII data.  */
753*49cdfc7eSAndroid Build Coastguard Worker 	dbg(stdout, "seeding buffer with random data\n");
754*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < chunk - 1; i++) {
755*49cdfc7eSAndroid Build Coastguard Worker 		j = rand();
756*49cdfc7eSAndroid Build Coastguard Worker 		j = (j < 0) ? -j : j;
757*49cdfc7eSAndroid Build Coastguard Worker 		j %= 95;
758*49cdfc7eSAndroid Build Coastguard Worker 		j += 32;
759*49cdfc7eSAndroid Build Coastguard Worker 		buff[i] = j;
760*49cdfc7eSAndroid Build Coastguard Worker 	}
761*49cdfc7eSAndroid Build Coastguard Worker 	buff[i] = '\n';
762*49cdfc7eSAndroid Build Coastguard Worker 
763*49cdfc7eSAndroid Build Coastguard Worker 	dbg(stdout, "using backoff sleep of %lius for hoghdd\n", backoff);
764*49cdfc7eSAndroid Build Coastguard Worker 
765*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; forks == 0 || i < forks; i++) {
766*49cdfc7eSAndroid Build Coastguard Worker 		switch (pid = fork()) {
767*49cdfc7eSAndroid Build Coastguard Worker 		case 0:	/* child */
768*49cdfc7eSAndroid Build Coastguard Worker 			alarm(timeout);
769*49cdfc7eSAndroid Build Coastguard Worker 
770*49cdfc7eSAndroid Build Coastguard Worker 			/* Use a backoff sleep to ensure we get good fork throughput.  */
771*49cdfc7eSAndroid Build Coastguard Worker 			usleep(backoff);
772*49cdfc7eSAndroid Build Coastguard Worker 
773*49cdfc7eSAndroid Build Coastguard Worker 			while (1) {
774*49cdfc7eSAndroid Build Coastguard Worker 				for (i = 0; i < files; i++) {
775*49cdfc7eSAndroid Build Coastguard Worker 					char name[] = "./stress.XXXXXX";
776*49cdfc7eSAndroid Build Coastguard Worker 
777*49cdfc7eSAndroid Build Coastguard Worker 					if ((fd = mkstemp(name)) < 0) {
778*49cdfc7eSAndroid Build Coastguard Worker 						perror("mkstemp");
779*49cdfc7eSAndroid Build Coastguard Worker 						err(stderr, "mkstemp failed\n");
780*49cdfc7eSAndroid Build Coastguard Worker 						exit(1);
781*49cdfc7eSAndroid Build Coastguard Worker 					}
782*49cdfc7eSAndroid Build Coastguard Worker 
783*49cdfc7eSAndroid Build Coastguard Worker 					if (clean == 0) {
784*49cdfc7eSAndroid Build Coastguard Worker 						dbg(stdout, "unlinking %s\n",
785*49cdfc7eSAndroid Build Coastguard Worker 						    name);
786*49cdfc7eSAndroid Build Coastguard Worker 						if (unlink(name)) {
787*49cdfc7eSAndroid Build Coastguard Worker 							err(stderr,
788*49cdfc7eSAndroid Build Coastguard Worker 							    "unlink failed\n");
789*49cdfc7eSAndroid Build Coastguard Worker 							exit(1);
790*49cdfc7eSAndroid Build Coastguard Worker 						}
791*49cdfc7eSAndroid Build Coastguard Worker 					}
792*49cdfc7eSAndroid Build Coastguard Worker 
793*49cdfc7eSAndroid Build Coastguard Worker 					dbg(stdout, "fast writing to %s\n",
794*49cdfc7eSAndroid Build Coastguard Worker 					    name);
795*49cdfc7eSAndroid Build Coastguard Worker 					for (j = 0;
796*49cdfc7eSAndroid Build Coastguard Worker 					     bytes == 0 || j + chunk < bytes;
797*49cdfc7eSAndroid Build Coastguard Worker 					     j += chunk) {
798*49cdfc7eSAndroid Build Coastguard Worker 						if (write(fd, buff, chunk) !=
799*49cdfc7eSAndroid Build Coastguard Worker 						    chunk) {
800*49cdfc7eSAndroid Build Coastguard Worker 							err(stderr,
801*49cdfc7eSAndroid Build Coastguard Worker 							    "write failed\n");
802*49cdfc7eSAndroid Build Coastguard Worker 							exit(1);
803*49cdfc7eSAndroid Build Coastguard Worker 						}
804*49cdfc7eSAndroid Build Coastguard Worker 					}
805*49cdfc7eSAndroid Build Coastguard Worker 
806*49cdfc7eSAndroid Build Coastguard Worker 					dbg(stdout, "slow writing to %s\n",
807*49cdfc7eSAndroid Build Coastguard Worker 					    name);
808*49cdfc7eSAndroid Build Coastguard Worker 					for (; bytes == 0 || j < bytes - 1; j++) {
809*49cdfc7eSAndroid Build Coastguard Worker 						if (write(fd, "Z", 1) != 1) {
810*49cdfc7eSAndroid Build Coastguard Worker 							err(stderr,
811*49cdfc7eSAndroid Build Coastguard Worker 							    "write failed\n");
812*49cdfc7eSAndroid Build Coastguard Worker 							exit(1);
813*49cdfc7eSAndroid Build Coastguard Worker 						}
814*49cdfc7eSAndroid Build Coastguard Worker 					}
815*49cdfc7eSAndroid Build Coastguard Worker 					if (write(fd, "\n", 1) != 1) {
816*49cdfc7eSAndroid Build Coastguard Worker 						err(stderr, "write failed\n");
817*49cdfc7eSAndroid Build Coastguard Worker 						exit(1);
818*49cdfc7eSAndroid Build Coastguard Worker 					}
819*49cdfc7eSAndroid Build Coastguard Worker 					++j;
820*49cdfc7eSAndroid Build Coastguard Worker 
821*49cdfc7eSAndroid Build Coastguard Worker 					dbg(stdout,
822*49cdfc7eSAndroid Build Coastguard Worker 					    "closing %s after writing %lli bytes\n",
823*49cdfc7eSAndroid Build Coastguard Worker 					    name, j);
824*49cdfc7eSAndroid Build Coastguard Worker 					close(fd);
825*49cdfc7eSAndroid Build Coastguard Worker 
826*49cdfc7eSAndroid Build Coastguard Worker 					if (clean == 1) {
827*49cdfc7eSAndroid Build Coastguard Worker 						if (unlink(name)) {
828*49cdfc7eSAndroid Build Coastguard Worker 							err(stderr,
829*49cdfc7eSAndroid Build Coastguard Worker 							    "unlink failed\n");
830*49cdfc7eSAndroid Build Coastguard Worker 							exit(1);
831*49cdfc7eSAndroid Build Coastguard Worker 						}
832*49cdfc7eSAndroid Build Coastguard Worker 					}
833*49cdfc7eSAndroid Build Coastguard Worker 				}
834*49cdfc7eSAndroid Build Coastguard Worker 				if (retval == 0) {
835*49cdfc7eSAndroid Build Coastguard Worker 					dbg(stdout,
836*49cdfc7eSAndroid Build Coastguard Worker 					    "hoghdd worker starting over\n");
837*49cdfc7eSAndroid Build Coastguard Worker 					continue;
838*49cdfc7eSAndroid Build Coastguard Worker 				}
839*49cdfc7eSAndroid Build Coastguard Worker 
840*49cdfc7eSAndroid Build Coastguard Worker 				exit(retval);
841*49cdfc7eSAndroid Build Coastguard Worker 			}
842*49cdfc7eSAndroid Build Coastguard Worker 
843*49cdfc7eSAndroid Build Coastguard Worker 			/* This case never falls through; alarm signal can cause exit.  */
844*49cdfc7eSAndroid Build Coastguard Worker 		case -1:	/* error */
845*49cdfc7eSAndroid Build Coastguard Worker 			if (ignore) {
846*49cdfc7eSAndroid Build Coastguard Worker 				++retval;
847*49cdfc7eSAndroid Build Coastguard Worker 				wrn(stderr,
848*49cdfc7eSAndroid Build Coastguard Worker 				    "hoghdd worker fork failed, continuing\n");
849*49cdfc7eSAndroid Build Coastguard Worker 				usleep(retry);
850*49cdfc7eSAndroid Build Coastguard Worker 				continue;
851*49cdfc7eSAndroid Build Coastguard Worker 			}
852*49cdfc7eSAndroid Build Coastguard Worker 
853*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr, "hoghdd worker fork failed\n");
854*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
855*49cdfc7eSAndroid Build Coastguard Worker 		default:	/* parent */
856*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "--> hoghdd worker forked (%i)\n", pid);
857*49cdfc7eSAndroid Build Coastguard Worker 		}
858*49cdfc7eSAndroid Build Coastguard Worker 	}
859*49cdfc7eSAndroid Build Coastguard Worker 
860*49cdfc7eSAndroid Build Coastguard Worker 	/* Wait for our children to exit.  */
861*49cdfc7eSAndroid Build Coastguard Worker 	while (i) {
862*49cdfc7eSAndroid Build Coastguard Worker 		int status, ret;
863*49cdfc7eSAndroid Build Coastguard Worker 
864*49cdfc7eSAndroid Build Coastguard Worker 		if ((pid = wait(&status)) > 0) {
865*49cdfc7eSAndroid Build Coastguard Worker 			if ((WIFEXITED(status)) != 0) {
866*49cdfc7eSAndroid Build Coastguard Worker 				if ((ret = WEXITSTATUS(status)) != 0) {
867*49cdfc7eSAndroid Build Coastguard Worker 					err(stderr,
868*49cdfc7eSAndroid Build Coastguard Worker 					    "hoghdd worker %i exited %i\n", pid,
869*49cdfc7eSAndroid Build Coastguard Worker 					    ret);
870*49cdfc7eSAndroid Build Coastguard Worker 					retval += ret;
871*49cdfc7eSAndroid Build Coastguard Worker 				} else {
872*49cdfc7eSAndroid Build Coastguard Worker 					dbg(stdout,
873*49cdfc7eSAndroid Build Coastguard Worker 					    "<-- hoghdd worker exited (%i)\n",
874*49cdfc7eSAndroid Build Coastguard Worker 					    pid);
875*49cdfc7eSAndroid Build Coastguard Worker 				}
876*49cdfc7eSAndroid Build Coastguard Worker 			} else {
877*49cdfc7eSAndroid Build Coastguard Worker 				dbg(stdout,
878*49cdfc7eSAndroid Build Coastguard Worker 				    "<-- hoghdd worker signalled (%i)\n", pid);
879*49cdfc7eSAndroid Build Coastguard Worker 			}
880*49cdfc7eSAndroid Build Coastguard Worker 
881*49cdfc7eSAndroid Build Coastguard Worker 			--i;
882*49cdfc7eSAndroid Build Coastguard Worker 		} else {
883*49cdfc7eSAndroid Build Coastguard Worker 			dbg(stdout, "wait() returned error: %s\n",
884*49cdfc7eSAndroid Build Coastguard Worker 			    strerror(errno));
885*49cdfc7eSAndroid Build Coastguard Worker 			err(stderr,
886*49cdfc7eSAndroid Build Coastguard Worker 			    "detected missing hoghdd worker children\n");
887*49cdfc7eSAndroid Build Coastguard Worker 			++retval;
888*49cdfc7eSAndroid Build Coastguard Worker 			break;
889*49cdfc7eSAndroid Build Coastguard Worker 		}
890*49cdfc7eSAndroid Build Coastguard Worker 	}
891*49cdfc7eSAndroid Build Coastguard Worker 
892*49cdfc7eSAndroid Build Coastguard Worker 	return retval;
893*49cdfc7eSAndroid Build Coastguard Worker }
894