diff --git a/lustre/tests/openclose.c b/lustre/tests/openclose.c index 5c1a9ad4bf2371742710d135e09fed530249e0ad..4fbae4771ce62bbcc47182a36be353924cb96975 100644 --- a/lustre/tests/openclose.c +++ b/lustre/tests/openclose.c @@ -6,6 +6,7 @@ #include <fcntl.h> #include <errno.h> #include <string.h> +#include <sys/wait.h> #ifndef O_DIRECT #define O_DIRECT 040000 /* direct disk access hint */ @@ -13,45 +14,117 @@ int main(int argc, char *argv[]) { - char *filename; + char filename[1024]; unsigned long count, i; + int thread = 0; + int threads = 0; + int rc; int fd; - if (argc != 3) { - fprintf(stderr, "usage: %s <filename> <iterations>\n", argv[0]); + if (argc < 3 || argc > 4) { + fprintf(stderr, "usage: %s <filename> <iterations> [threads]\n", + argv[0]); exit(1); } - filename = argv[1]; count = strtoul(argv[2], NULL, 0); + if (argc == 4) + threads = strtoul(argv[3], NULL, 0); - fd = open(filename, O_RDWR|O_CREAT, 0644); - if (fd < 0) { - fprintf(stderr, "open(%s, O_CREAT): %s\n", filename, - strerror(errno)); - exit(1); - } - if (close(fd) < 0) { - fprintf(stderr, "close(): %s\n", strerror(errno)); - exit(1); + for (i = 1; i <= threads; i++) { + rc = fork(); + if (rc < 0) { + fprintf(stderr, "error: %s: #%ld - %s\n", argv[0], i, + strerror(rc = errno)); + break; + } else if (rc == 0) { + thread = i; + argv[2] = "--device"; + break; + } else + printf("%s: thread #%ld (PID %d) started\n", + argv[0], i, rc); + rc = 0; } - for (i = 0; i < count; i++) { - fd = open(filename, O_RDONLY|O_LARGEFILE|O_DIRECT); - if (fd < 0) { - fprintf(stderr, "open(%s, O_RDONLY): %s\n", filename, - strerror(errno)); - exit(1); - } - if (close(fd) < 0) { - fprintf(stderr, "close(): %s\n", strerror(errno)); - exit(1); + if (threads && thread == 0) { /* parent process */ + int live_threads = threads; + + while (live_threads > 0) { + int status; + pid_t ret; + + ret = waitpid(0, &status, 0); + if (ret == 0) { + continue; + } + + if (ret < 0) { + fprintf(stderr, "error: %s: wait - %s\n", + argv[0], strerror(errno)); + if (!rc) + rc = errno; + } else { + /* + * This is a hack. We _should_ be able to use + * WIFEXITED(status) to see if there was an + * error, but it appears to be broken and it + * always returns 1 (OK). See wait(2). + */ + int err = WEXITSTATUS(status); + if (err || WIFSIGNALED(status)) + fprintf(stderr, + "%s: PID %d had rc=%d\n", + argv[0], ret, err); + if (!rc) + rc = err; + + live_threads--; + } } - } - if (unlink(filename) < 0) { - fprintf(stderr, "unlink(%s): %s\n", filename, strerror(errno)); - exit(1); - } - printf("Done.\n"); - return 0; + } else { + if (threads) + sprintf(filename, "%s-%d", argv[1], thread); + else + strcpy(filename, argv[1]); + + fd = open(filename, O_RDWR|O_CREAT, 0644); + if (fd < 0) { + fprintf(stderr, "open(%s, O_CREAT): %s\n", filename, + strerror(errno)); + exit(errno); + } + if (close(fd) < 0) { + fprintf(stderr, "close(): %s\n", strerror(errno)); + rc = errno; + goto unlink; + } + + for (i = 0; i < count; i++) { + fd = open(filename, O_RDWR|O_LARGEFILE|O_DIRECT); + if (fd < 0) { + fprintf(stderr, "open(%s, O_RDWR): %s\n", + filename, strerror(errno)); + rc = errno; + break; + } + if (close(fd) < 0) { + fprintf(stderr, "close(): %s\n", + strerror(errno)); + rc = errno; + break; + } + } + unlink: + if (unlink(filename) < 0) { + fprintf(stderr, "unlink(%s): %s\n", filename, + strerror(errno)); + rc = errno; + } + if (threads) + printf("Thread %d done: rc = %d\n", thread, rc); + else + printf("Done: rc = %d\n", rc); + } + return rc; }