X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Ftests%2Fwritemany.c;h=707ab8d4bacf74e018bebb66e62162909bffc9e3;hb=f0b4b681649a25199186e9aa415045716345222e;hp=5d4e42efa01860c1961a2dd23f208f657e0d1575;hpb=46d4b6b414ef0829ada755daf18d8bd45c16dfaf;p=fs%2Flustre-release.git diff --git a/lustre/tests/writemany.c b/lustre/tests/writemany.c index 5d4e42e..707ab8d 100644 --- a/lustre/tests/writemany.c +++ b/lustre/tests/writemany.c @@ -1,6 +1,39 @@ /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: + * + * GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * GPL HEADER END */ +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Use is subject to license terms. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + */ + #include #include #include @@ -25,6 +58,16 @@ char cmdname[512]; int o_abort = 0; int o_quiet = 0; +void usage(char *name) +{ + fprintf(stderr, "usage: %s [opts] \n", + name); + fprintf(stderr, " -q quiet\n"); + fprintf(stderr, " -a abort other children on first err\n"); + exit(1); +} + + struct kid_list_t { pid_t kid; struct kid_list_t *next; @@ -32,13 +75,17 @@ struct kid_list_t { struct kid_list_t *head = NULL; -void push_kid(pid_t kid) +int push_kid(pid_t kid) { struct kid_list_t *new; new = (struct kid_list_t *)malloc(sizeof(struct kid_list_t)); + if (new == NULL) + return 1; + new->kid = kid; new->next = head; head = new; + return 0; } void kill_kids(void) @@ -49,19 +96,26 @@ void kill_kids(void) } } +static int usr1_received; +void usr1_handler(int unused) +{ + usr1_received = 1; + kill_kids(); +} + int wait_for_threads(int live_threads) { int rc = 0; - + while (live_threads > 0) { int status; pid_t ret; - + ret = waitpid(0, &status, 0); if (ret == 0) { continue; } - + if (ret < 0) { fprintf(stderr, "%s: error: wait - %s\n", cmdname, strerror(errno)); @@ -75,7 +129,7 @@ int wait_for_threads(int live_threads) * always returns 1 (OK). See wait(2). */ int err = WEXITSTATUS(status); - if (err || WIFSIGNALED(status)) + if (err) fprintf(stderr, "%s: error: PID %d had rc=%d\n", cmdname, ret, err); @@ -100,7 +154,7 @@ int wait_for_threads(int live_threads) void print_err(char *op, char *filename, struct timeval *time, int err) { fprintf(stderr, "%s: %d.%.06d error: %s(%s): %s\n", - cmdname, (int)(time->tv_sec), (int)(time->tv_usec), op, + cmdname, (int)(time->tv_sec), (int)(time->tv_usec), op, filename, strerror(errno)); } @@ -113,33 +167,39 @@ int run_one_child(char *file, int thread, int seconds) int fd, rc = 0, rand, maxrand, len; long nfiles = 0, nbytes = 0; - if (!o_quiet) + if (!o_quiet) printf("%s: running thread #%d\n", cmdname, thread); - + srandom(thread); - /* Higher thread numbers will produce bigger random files. + /* Higher thread numbers will produce bigger random files. Thread 1 will produce only 0-len files. */ maxrand = 1; rand = thread; while (--rand) maxrand *= 10; gettimeofday(&start, NULL); + cur = start; while(!rc) { - gettimeofday(&cur, NULL); - if (cur.tv_sec > (start.tv_sec + seconds)) + if (usr1_received) break; - sprintf(filename, "%s-%d-%ld", file, thread, nfiles); + gettimeofday(&cur, NULL); + if (seconds) { + if (cur.tv_sec > (start.tv_sec + seconds)) + break; + } + sprintf(filename, "%s-%d-%ld", file, thread, nfiles); + fd = open(filename, O_RDWR | O_CREAT, 0666); if (fd < 0) { print_err("open", filename, &cur, errno); rc = errno; break; } - - sprintf(buf, "%s %010ld %.19s.%012d\n", cmdname, + + sprintf(buf, "%s %010ld %.19s.%012d\n", cmdname, nfiles++, ctime(&cur.tv_sec), (int)cur.tv_usec); len = strlen(buf); @@ -149,10 +209,10 @@ int run_one_child(char *file, int thread, int seconds) print_err("write", filename, &cur, errno); rc = errno; break; - } + } nbytes += len; - } - + } + if (close(fd) < 0) { print_err("close", filename, &cur, errno); rc = errno; @@ -160,32 +220,27 @@ int run_one_child(char *file, int thread, int seconds) } if (unlink(filename) < 0) { print_err("unlink", filename, &cur, errno); - rc = errno; - break; + if (errno == ENOENT) { + printf("Ignoring known bug 6082\n"); + } else { + rc = errno; + break; + } } } - + diff = difftime(&cur, &start); - if (!o_quiet) - printf("%s: %7ld files, %4ld MB in %.2fs (%7.2f files/s, " + if (!o_quiet) + printf("%s: %7ld files, %4ld MB in %.2fs (%7.2f files/s, " "%5.2f MB/s): rc = %d\n", cmdname, nfiles, nbytes >> 20, diff, - (double)nfiles / diff, (double)nbytes/1024/1024 / diff, + diff == 0 ? (double)0 : (double)nfiles / diff, + diff == 0 ? (double)0 : (double)nbytes/1024/1024 / diff, rc); return rc; } -void usage(char *name) -{ - fprintf(stderr, - "usage: %s [opts] \n", - name); - fprintf(stderr, " -q quiet\n"); - fprintf(stderr, " -a abort other children on first err\n"); - exit(1); -} - int main(int argc, char *argv[]) { unsigned long duration; @@ -194,7 +249,7 @@ int main(int argc, char *argv[]) char *directory; int i = 1, rc = 0; - sprintf(cmdname, "%s", argv[0]); + sprintf(cmdname, "%s", argv[0]); while((i < argc) && (argv[i][0] == '-')) { switch (argv[i][1]) { @@ -226,6 +281,8 @@ int main(int argc, char *argv[]) exit(2); } + signal(SIGUSR1, usr1_handler); + for (i = 1; i <= threads; i++) { rc = fork(); if (rc < 0) { @@ -240,11 +297,15 @@ int main(int argc, char *argv[]) return (run_one_child(directory, i, duration)); } else { /* parent */ - push_kid(rc); + rc = push_kid(rc); + if (rc != 0) { + kill_kids(); + exit(3); + } } } /* parent process */ - if (!o_quiet) + if (!o_quiet) printf("%s will run for %ld minutes\n", cmdname, duration/60); return (wait_for_threads(threads)); }