Whamcloud - gitweb
i=eeb:
[fs/lustre-release.git] / lustre / tests / createdestroy.c
index 93ecb11..b5b7c2b 100644 (file)
@@ -1,3 +1,6 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/wait.h>
+#include <time.h>
+#include <sys/time.h>
+
+int thread;
+
+#define BAD_VERBOSE (-999999999)
+
+#define difftime(a, b)                                          \
+        ((double)(a)->tv_sec - (b)->tv_sec +                    \
+         ((double)((a)->tv_usec - (b)->tv_usec) / 1000000))
+
+static char *cmdname(char *func)
+{
+        static char buf[512];
+
+        if (thread) {
+                sprintf(buf, "%s-%d", func, thread);
+                return buf;
+        }
+
+        return func;
+}
+
+static int be_verbose(int verbose, struct timeval *next_time,
+                      unsigned long num, unsigned long *next_num, int num_total)
+{
+        struct timeval now;
+
+        if (!verbose)
+                return 0;
+
+        if (next_time != NULL)
+                gettimeofday(&now, NULL);
+
+        /* A positive verbosity means to print every X iterations */
+        if (verbose > 0 && (num >= *next_num || num >= num_total)) {
+                *next_num += verbose;
+                if (next_time) {
+                        next_time->tv_sec = now.tv_sec - verbose;
+                        next_time->tv_usec = now.tv_usec;
+                }
+                return 1;
+        }
+
+        /* A negative verbosity means to print at most each X seconds */
+        if (verbose < 0 && next_time != NULL && difftime(&now, next_time) >= 0){
+                next_time->tv_sec = now.tv_sec - verbose;
+                next_time->tv_usec = now.tv_usec;
+                *next_num = num;
+                return 1;
+        }
+
+        return 0;
+}
+
+static int get_verbose(char *func, const char *arg)
+{
+        int verbose;
+        char *end;
+
+        if (!arg || arg[0] == 'v')
+                verbose = 1;
+        else if (arg[0] == 's' || arg[0] == 'q')
+                verbose = 0;
+        else {
+                verbose = (int)strtoul(arg, &end, 0);
+                if (*end) {
+                        fprintf(stderr, "%s: error: bad verbose option '%s'\n",
+                                func, arg);
+                        return BAD_VERBOSE;
+                }
+        }
+
+        if (verbose < 0)
+                printf("Print status every %d seconds\n", -verbose);
+        else if (verbose == 1)
+                printf("Print status every operation\n");
+        else if (verbose > 1)
+                printf("Print status every %d operations\n", verbose);
+
+        return verbose;
+}
 
 int main(int argc, char *argv[])
 {
         char filename[1024];
+        int verbose = 0;
         unsigned long count, i;
-       int thread = 0;
-       int threads = 0;
-       int rc;
+        int threads = 0;
+        char *end;
+        int rc = 0;
 
-        if (argc < 3 || argc > 4) {
-                fprintf(stderr, "usage: %s <filename> <iterations> [threads]\n",
-                       argv[0]);
+        if (argc < 3 || argc > 5) {
+                fprintf(stderr,
+                        "usage: %s <filename> <count> [verbose [threads]]\n",
+                        argv[0]);
                 exit(1);
         }
 
-        count = strtoul(argv[2], NULL, 0);
-       if (argc == 4)
-               threads = strtoul(argv[3], NULL, 0);
+        count = strtoul(argv[2], &end, 0);
+        if (*end) {
+                fprintf(stderr, "%s: error: bad iteration count '%s'\n",
+                        argv[0], argv[1]);
+                exit(2);
+        }
+        if (argc == 4) {
+                verbose = get_verbose(argv[0], argv[3]);
+                if (verbose == BAD_VERBOSE)
+                        exit(2);
+        }
+        if (argc == 5) {
+                threads = strtoul(argv[4], &end, 0);
+                if (*end) {
+                        fprintf(stderr, "%s: error: bad thread count '%s'\n",
+                                argv[0], argv[1]);
+                        exit(2);
+                }
+        }
 
         for (i = 1; i <= threads; i++) {
                 rc = fork();
                 if (rc < 0) {
-                        fprintf(stderr, "error: %s: #%ld - %s\n", argv[0], i,
-                                strerror(rc = errno));
+                        fprintf(stderr, "%s: error: #%ld - %s\n",
+                                cmdname(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);
+                               cmdname(argv[0]), i, rc);
                 rc = 0;
         }
 
-        if (threads && thread == 0) {  /* parent process */
+        if (threads && thread == 0) {   /* parent process */
                 int live_threads = threads;
 
                 while (live_threads > 0) {
@@ -55,7 +157,7 @@ int main(int argc, char *argv[])
                         }
 
                         if (ret < 0) {
-                                fprintf(stderr, "error: %s: wait - %s\n",
+                                fprintf(stderr, "%s: error: wait - %s\n",
                                         argv[0], strerror(errno));
                                 if (!rc)
                                         rc = errno;
@@ -69,7 +171,7 @@ int main(int argc, char *argv[])
                                 int err = WEXITSTATUS(status);
                                 if (err || WIFSIGNALED(status))
                                         fprintf(stderr,
-                                                "%s: PID %d had rc=%d\n",
+                                                "%s: error: PID %d had rc=%d\n",
                                                 argv[0], ret, err);
                                 if (!rc)
                                         rc = err;
@@ -77,32 +179,47 @@ int main(int argc, char *argv[])
                                 live_threads--;
                         }
                 }
-       } else {
-               for (i = 0; i < count; i++) {
-                       if (threads)
-                               sprintf(filename, "%s-%d-%ld",
-                                       argv[1], thread, i);
-                       else
-                               sprintf(filename, "%s-%ld", argv[1], i);
-
-                       rc = mknod(filename, S_IFREG, 0);
-                       if (rc < 0) {
-                               fprintf(stderr, "mknod(%s): %s\n",
-                                       filename, strerror(errno));
-                               rc = errno;
-                               break;
-                       }
-                       if (unlink(filename) < 0) {
-                               fprintf(stderr, "unlink(%s): %s\n",
-                                       filename, strerror(errno));
-                               rc = errno;
-                               break;
-                       }
-               }
-               if (threads)
-                       printf("Thread %d done: rc = %d\n", thread, rc);
-               else
-                       printf("Done: rc = %d\n", rc);
-       }
+        } else {
+                struct timeval start, end, next_time;
+                unsigned long next_count;
+                double diff;
+
+                gettimeofday(&start, NULL);
+                next_time.tv_sec = start.tv_sec - verbose;
+                next_time.tv_usec = start.tv_usec;
+
+                for (i = 0, next_count = verbose; i < count; i++) {
+                        if (threads)
+                                sprintf(filename, "%s-%d-%ld",
+                                        argv[1], thread, i);
+                        else
+                                sprintf(filename, "%s-%ld", argv[1], i);
+
+                        rc = mknod(filename, S_IFREG, 0);
+                        if (rc < 0) {
+                                fprintf(stderr, "%s: error: mknod(%s): %s\n",
+                                        cmdname(argv[0]), filename,
+                                        strerror(errno));
+                                rc = errno;
+                                break;
+                        }
+                        if (unlink(filename) < 0) {
+                                fprintf(stderr, "%s: error: unlink(%s): %s\n",
+                                        cmdname(argv[0]), filename,
+                                        strerror(errno));
+                                rc = errno;
+                                break;
+                        }
+                        if (be_verbose(verbose, &next_time,i,&next_count,count))
+                                printf("%s: number %ld\n", cmdname(argv[0]), i);
+                }
+
+                gettimeofday(&end, NULL);
+                diff = difftime(&end, &start);
+
+                printf("%s: %ldx2 files in %.4gs (%.4g ops/s): rc = %d: %s",
+                       cmdname(argv[0]), i, diff, (double)i * 2 / diff,
+                       rc, ctime(&end.tv_sec));
+        }
         return rc;
 }