1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
40 #include <sys/types.h>
51 #define BAD_VERBOSE (-999999999)
53 #define difftime(a, b) \
54 ((double)(a)->tv_sec - (b)->tv_sec + \
55 ((double)((a)->tv_usec - (b)->tv_usec) / 1000000))
57 static char *cmdname(char *func)
62 sprintf(buf, "%s-%d", func, thread);
69 static int be_verbose(int verbose, struct timeval *next_time,
70 unsigned long num, unsigned long *next_num, int num_total)
77 if (next_time != NULL)
78 gettimeofday(&now, NULL);
80 /* A positive verbosity means to print every X iterations */
81 if (verbose > 0 && (num >= *next_num || num >= num_total)) {
84 next_time->tv_sec = now.tv_sec - verbose;
85 next_time->tv_usec = now.tv_usec;
90 /* A negative verbosity means to print at most each X seconds */
91 if (verbose < 0 && next_time != NULL && difftime(&now, next_time) >= 0){
92 next_time->tv_sec = now.tv_sec - verbose;
93 next_time->tv_usec = now.tv_usec;
101 static int get_verbose(char *func, const char *arg)
106 if (!arg || arg[0] == 'v')
108 else if (arg[0] == 's' || arg[0] == 'q')
111 verbose = (int)strtoul(arg, &end, 0);
113 fprintf(stderr, "%s: error: bad verbose option '%s'\n",
120 printf("Print status every %d seconds\n", -verbose);
121 else if (verbose == 1)
122 printf("Print status every operation\n");
123 else if (verbose > 1)
124 printf("Print status every %d operations\n", verbose);
129 int main(int argc, char *argv[])
133 unsigned long count, i;
138 if (argc < 3 || argc > 5) {
140 "usage: %s <filename> <count> [verbose [threads]]\n",
145 count = strtoul(argv[2], &end, 0);
147 fprintf(stderr, "%s: error: bad iteration count '%s'\n",
152 verbose = get_verbose(argv[0], argv[3]);
153 if (verbose == BAD_VERBOSE)
157 threads = strtoul(argv[4], &end, 0);
159 fprintf(stderr, "%s: error: bad thread count '%s'\n",
165 for (i = 1; i <= threads; i++) {
168 fprintf(stderr, "%s: error: #%ld - %s\n",
169 cmdname(argv[0]), i, strerror(rc = errno));
171 } else if (rc == 0) {
175 printf("%s: thread #%ld (PID %d) started\n",
176 cmdname(argv[0]), i, rc);
180 if (threads && thread == 0) { /* parent process */
181 int live_threads = threads;
183 while (live_threads > 0) {
187 ret = waitpid(0, &status, 0);
193 fprintf(stderr, "%s: error: wait - %s\n",
194 argv[0], strerror(errno));
199 * This is a hack. We _should_ be able to use
200 * WIFEXITED(status) to see if there was an
201 * error, but it appears to be broken and it
202 * always returns 1 (OK). See wait(2).
204 int err = WEXITSTATUS(status);
205 if (err || WIFSIGNALED(status))
207 "%s: error: PID %d had rc=%d\n",
216 struct timeval start, end, next_time;
217 unsigned long next_count;
220 gettimeofday(&start, NULL);
221 next_time.tv_sec = start.tv_sec - verbose;
222 next_time.tv_usec = start.tv_usec;
224 for (i = 0, next_count = verbose; i < count; i++) {
226 sprintf(filename, "%s-%d-%ld",
229 sprintf(filename, "%s-%ld", argv[1], i);
231 rc = mknod(filename, S_IFREG, 0);
233 fprintf(stderr, "%s: error: mknod(%s): %s\n",
234 cmdname(argv[0]), filename,
239 if (unlink(filename) < 0) {
240 fprintf(stderr, "%s: error: unlink(%s): %s\n",
241 cmdname(argv[0]), filename,
246 if (be_verbose(verbose, &next_time,i,&next_count,count))
247 printf("%s: number %ld\n", cmdname(argv[0]), i);
250 gettimeofday(&end, NULL);
251 diff = difftime(&end, &start);
253 printf("%s: %ldx2 files in %.4gs (%.4g ops/s): rc = %d: %s",
254 cmdname(argv[0]), i, diff, (double)i * 2 / diff,
255 rc, ctime(&end.tv_sec));