2 * Copyright (c) 2008 Peter Holm <pho@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49 printf("Error in \"%s\"\n", where);
50 fprintf(stderr, "Usage: %s [-t | -l | -i | -d | -h | -k | -v]\n", getprogname());
51 help = " t <number><s|m|h|d> : time to run test\n"
52 " l <pct> : load factor 0 - 100%\n"
53 " i <number> : max # of parallel incarnations\n"
54 " d <path> : working directory\n"
55 " h : hog resources\n"
56 " k : terminate with SIGHUP + SIGKILL\n"
57 " n : no startup delay\n"
64 time2sec(const char *string)
68 r = sscanf(string, "%d%c", &s, &modifier);
72 case 'm': s = s * 60; break;
73 case 'h': s = s * 60 * 60; break;
74 case 'd': s = s * 60 * 60 * 24; break;
83 static char *gete(char *name)
88 snprintf(help, sizeof(help), "%s%s", getprogname(), name);
100 if ((cp = gete("INCARNATIONS")) != NULL) {
101 if (sscanf(cp, "%d", &op->incarnations) != 1)
102 usage("INCARNATIONS");
104 if ((cp = gete("LOAD")) != NULL) {
105 if (sscanf(cp, "%d", &op->load) != 1)
108 if ((cp = gete("RUNTIME")) != NULL) {
109 op->run_time = time2sec(cp);
111 if ((cp = gete("RUNDIR")) != NULL) {
114 if ((cp = gete("CTRLDIR")) != NULL) {
117 if ((cp = gete("HOG")) != NULL) {
120 if ((cp = gete("KILL")) != NULL) {
123 if ((cp = gete("NODELAY")) != NULL) {
126 if ((cp = gete("VERBOSE")) != NULL) {
127 if (sscanf(cp, "%d", &op->verbose) != 1)
130 if ((cp = gete("KBLOCKS")) != NULL) {
131 if (sscanf(cp, "%d", &op->kblocks) != 1)
134 if ((cp = gete("INODES")) != NULL) {
135 if (sscanf(cp, "%d", &op->inodes) != 1)
141 options(int argc, char **argv)
149 op->wd = "/tmp/stressX";
150 op->cd = "/tmp/stressX.control";
151 op->incarnations = 1;
161 while ((ch = getopt(argc, argv, "t:l:i:d:hknv")) != -1)
163 case 't': /* run time */
164 op->run_time = time2sec(optarg);
166 case 'l': /* load factor in pct */
167 if (sscanf(optarg, "%d", &op->load) != 1)
170 case 'i': /* max incarnations */
171 if (sscanf(optarg, "%d", &op->incarnations) != 1)
174 case 'd': /* working directory */
175 op->wd = strdup(optarg);
177 case 'h': /* hog flag */
180 case 'k': /* kill flag */
183 case 'n': /* no delay flag */
186 case 'v': /* verbose flag */
192 op->argc = argc -= optind;
193 op->argv = argv += optind;
195 if (op->incarnations < 1)
196 op->incarnations = 1;
198 op->incarnations = random_int(1, op->incarnations);
199 if (op->run_time < 15)
201 if (op->load < 0 || op->load > 100)
212 if (op->verbose > 0) {
214 days = t / (60 * 60 * 24);
215 t = t % (60 * 60 * 24);
216 strftime(buf, sizeof(buf), "%T", gmtime(&t));
217 printf("%8s: run time %2d+%s, incarnations %3d, load %3d, verbose %d\n",
218 getprogname(), days, buf, op->incarnations, op->load,
226 if (snprintf(path, sizeof(path), "%s/%s.conf", op->cd, getprogname()) < 0)
227 err(1, "snprintf path");
232 putval(unsigned long v)
237 snprintf(buf, sizeof(buf), "%lu", v);
238 if (symlink(buf, path) < 0)
239 err(1, "symlink(%s, %s)", path, buf);
249 if ((n = readlink(path, buf, sizeof(buf) -1)) < 0) {
250 for (i = 0; i < 60; i++) {
252 if ((n = readlink(path, buf, sizeof(buf) -1)) > 0)
256 err(1, "readlink(%s). %s:%d", path, __FILE__, __LINE__);
259 if (sscanf(buf, "%ld", &val) != 1)
260 err(1, "sscanf(%s)", buf);