Whamcloud - gitweb
LU-4961 lustre: remove liblustre.h and obd.h from userspace
[fs/lustre-release.git] / lustre / tests / mpi / mdsrate.c
index 097d4a8..beca2ff 100644 (file)
@@ -1,6 +1,4 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
  * 2003, Copyright, Hewlett-Packard Development Compnay, LP.
  *
  * Developed under the sponsorship of the U.S. Government
@@ -8,8 +6,10 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, 2013, Intel Corporation.
  */
 
 #include <stdio.h>
@@ -32,8 +32,7 @@
 #include "mpi.h"
 
 /* lustre */
-#include <liblustre.h>
-#include <lustre/liblustreapi.h>        /* for O_LOV_DELAY_CREATE */
+#include <lustre/lustreapi.h>        /* for O_LOV_DELAY_CREATE */
 
 #define CHECK_COUNT 10000
 #define DISPLAY_COUNT (CHECK_COUNT * 10)
@@ -64,6 +63,9 @@ enum {
         VERBOSE  = 'V',
         DEBUG    = 'v',
         HELP     = 'h',
+       MNT      = 'M',
+       MNTCOUNT = 'N',
+       MDTCOUNT = 'T',
 };
 
 struct option longOpts[] = {
@@ -91,7 +93,10 @@ struct option longOpts[] = {
         {"verbose",       0, NULL, VERBOSE    },
         {"debug",         0, NULL, DEBUG      },
         {"help",          0, NULL, HELP       },
-        { 0,              0, NULL, 0          }
+       {"mdtcount",      1, NULL, MDTCOUNT   },
+       {"mntcount",      1, NULL, MNTCOUNT   },
+       {"mntfmt",        1, NULL, MNT        },
+       { 0,              0, NULL, 0          }
 };
 
 int foo1, foo2;
@@ -115,6 +120,7 @@ struct dirent *dir_entry;
 int    nfiles;
 char   filefmt[PATH_MAX];
 char   filename[PATH_MAX];
+char   path[PATH_MAX];
 int    stripes = -1;
 int    begin;
 int    beginsave;
@@ -130,19 +136,20 @@ int    ignore;
 int    verbose;
 int    debug;
 struct stat statbuf;
+int    mnt_count = -1;
+int    mdt_count = 1;
+char  *mntfmt;
 
 #define dmesg if (debug) printf
 
 #define DISPLAY_PROGRESS() {                                                \
-        if ((++nops % CHECK_COUNT) == 0 && verbose) {                       \
-                curTime = time(0);                                          \
+        if (verbose && (nops % CHECK_COUNT == 0)) {                         \
+                curTime = MPI_Wtime();                                      \
                 interval = curTime - lastTime;                              \
                 if (interval > DISPLAY_TIME || nops % DISPLAY_COUNT == 0) { \
-                        rate = (float)(nops - lastOps);                     \
-                        if (interval > 1)                                   \
-                                rate /= (float)interval;                    \
-                        printf("Rank %d: %.2f %ss/sec %lu secs "            \
-                               "(total: %d %ss %lu secs)\n",                \
+                        rate = (double)(nops - lastOps)/interval;           \
+                        printf("Rank %d: %.2f %ss/sec %.2f secs "           \
+                               "(total: %d %ss %.2f secs)\n",               \
                                myrank, rate, cmd, interval,                 \
                                nops, cmd, curTime - startTime);             \
                         lastOps = nops;                                     \
@@ -160,7 +167,8 @@ char *usage_msg = "usage: %s\n"
                   "    [ --dirfmt <str> ] [ --ndirs  <num> ]\n"
                   "    [ --filefmt <str> ] [ --stripes <num> ]\n"
                   "    [ --random_order [--seed <num> | --seedfile <file>] ]\n"
-                  "    [ --readdir_order ]\n";
+                 "    [ --readdir_order ] [ --mntfmt <str> ]\n"
+                 "    [ --mntcount <num> ] [ --mdtcount <num> ]\n";
 
 static void
 usage(FILE *stream, char *fmt, ...)
@@ -212,8 +220,8 @@ sigalrm_handler(int signum)
 #define HAVE_MDC_LOOKUP
 #elif defined(USE_MDC_LOOKUP)
 #include <config.h>
-#include <liblustre.h>
-#include <linux/lustre_lib.h>
+#include <libcfs/libcfs.h>
+#include <lustre_ioctl.h>
 
 int llapi_file_lookup(int dirfd, const char *name)
 {
@@ -244,7 +252,7 @@ int llapi_file_lookup(int dirfd, const char *name)
 static void
 process_args(int argc, char *argv[])
 {
-        char   c, *cp, *endptr;
+        char   *cp, *endptr;
         int    i, index, offset, tmpend, rc;
         char   tmp[16];
         FILE * seed_file;
@@ -263,8 +271,8 @@ process_args(int argc, char *argv[])
                         *++cp = ':';
         }
 
-        while ((c = getopt_long(argc,argv, shortOpts, longOpts,&index)) != -1) {
-                switch (c) {
+        while ((rc = getopt_long(argc,argv, shortOpts, longOpts,&index)) != -1) {
+                switch (rc) {
                 case OPEN:
                         openflags &= ~(O_CREAT|O_EXCL);
                 case CREATE:
@@ -279,7 +287,7 @@ process_args(int argc, char *argv[])
                                            "specified: --%s\n",
                                         longOpts[index].name);
                         }
-                        mode = c;
+                        mode = rc;
                         cmd = (char *)longOpts[index].name;
                         break;
                 case NOEXCL:
@@ -307,9 +315,9 @@ process_args(int argc, char *argv[])
                         if ((*endptr != 0) || (iters <= 0)) {
                                 fatal(0, "Invalid --iters value.\n");
                         }
-                        if (mode != LOOKUP && mode != OPEN && mode != STAT) {
+                        if (mode != LOOKUP && mode != OPEN) {
                                 usage(stderr, "--iters only makes sense with "
-                                              "--lookup, --open, or --stat.\n");
+                                              "--lookup or --open.\n");
                         }
                         break;
                 case TIME:
@@ -399,12 +407,12 @@ process_args(int argc, char *argv[])
                         break;
                 case RANDOM:
                 case READDIR:
-                        if (mode != LOOKUP && mode != OPEN && mode != STAT)  {
+                        if (mode != LOOKUP && mode != OPEN)  {
                                 fatal(0, "--%s can only be specified with "
-                                         "--lookup, --open, or --stat.\n",
+                                         "--lookup, or --open.\n",
                                       (char *)longOpts[index].name);
                         }
-                        order = c;
+                        order = rc;
                         break;
                 case IGNORE:
                         ++ignore;
@@ -416,6 +424,26 @@ process_args(int argc, char *argv[])
                         break;
                 case HELP:
                         usage(stdout, NULL);
+                       break;
+               case MNT:
+                       if (strlen(optarg) > (PATH_MAX - 16))
+                               fatal(0, "--mnt too long\n");
+                       mntfmt = optarg;
+                       break;
+               case MNTCOUNT:
+                       mnt_count = strtol(optarg, &endptr, 0);
+                       if ((*endptr != 0) || (mnt_count <= 0)) {
+                               fatal(0, "Invalid --mnt_count value %s.\n",
+                                     optarg);
+                       }
+                       break;
+               case MDTCOUNT:
+                       mdt_count = strtol(optarg, &endptr, 0);
+                       if ((*endptr != 0) || (mdt_count <= 0)) {
+                               fatal(0, "Invalid --mdt_count value %s.\n",
+                                     optarg);
+                       }
+                       break;
                 default:
                         usage(stderr, "unrecognized option: '%c'.\n", optopt);
                 }
@@ -425,7 +453,13 @@ process_args(int argc, char *argv[])
                 usage(stderr, "too many arguments %d >= %d.\n", optind, argc);
         }
 
-        if (mode == CREATE || mode == MKNOD || mode == UNLINK) {
+       if ((mnt_count != -1 && mntfmt == NULL) ||
+           (mnt_count == -1 && mntfmt != NULL)) {
+               usage(stderr, "mnt_count and mntfmt must be specified at the "
+                            "same time\n");
+       }
+
+        if (mode == CREATE || mode == MKNOD || mode == UNLINK || mode == STAT) {
                 if (seconds != 0) {
                         if (nfiles == 0)
                                 nfiles = INT_MAX;
@@ -433,7 +467,7 @@ process_args(int argc, char *argv[])
                         usage(stderr, "--nfiles or --time must be specified "
                                       "with %s.\n", cmd);
                 }
-        } else if (mode == LOOKUP || mode == OPEN || mode == STAT) {
+        } else if (mode == LOOKUP || mode == OPEN) {
                 if (seconds != 0) {
                         if (iters == 0)
                                 iters = INT_MAX;
@@ -488,6 +522,11 @@ process_args(int argc, char *argv[])
         if ((end > tmpend) || (end <= 0))
                 end -= dirthreads;
 
+       /* make sure mnt_count <= nthreads, otherwise it might div 0 in
+        * the following test */
+       if (mnt_count > nthreads)
+               mnt_count = nthreads;
+
         begin += offset;
         if (begin < 0)
                 begin = INT_MAX;
@@ -500,17 +539,38 @@ process_args(int argc, char *argv[])
         if (dirfmt == NULL) {
                 strcpy(dir, ".");
         } else {
-                sprintf(dir, dirfmt, dirnum);
-
-                sprintf(mkdir_cmd, "/bin/mkdir -p %s", dir);
-                #ifdef _LIGHTWEIGHT_KERNEL
-                        printf("NOTICE: not running system(%s)\n", mkdir_cmd);
-                #else
-                        rc = system(mkdir_cmd);
-                        if (rc) {
-                                fatal(myrank, "'%s' failed.\n", mkdir_cmd);
-                        }
-                #endif
+               int dir_len = 0;
+
+               if (mntfmt != NULL) {
+                       sprintf(dir, mntfmt, (myrank / (nthreads/mnt_count)));
+                       strcat(dir, "/");
+                       dir_len = strlen(dir);
+               }
+               sprintf(dir + dir_len, dirfmt, dirnum);
+
+               if (mdt_count > 1) {
+                       struct stat sb;
+                       if (stat(dir, &sb) == 0) {
+                               if (!S_ISDIR(sb.st_mode))
+                                       fatal(myrank, "'%s' is not dir\n", dir);
+                       } else if (errno == ENOENT) {
+                               sprintf(mkdir_cmd, "lfs mkdir -i %d %s",
+                                       myrank % mdt_count, dir);
+                       } else {
+                               fatal(myrank, "'%s' stat failed\n", dir);
+                       }
+               } else {
+                       sprintf(mkdir_cmd, "mkdir -p %s", dir);
+               }
+
+               dmesg("%d: %s\n", myrank, mkdir_cmd);
+#ifdef _LIGHTWEIGHT_KERNEL
+               printf("NOTICE: not running system(%s)\n", mkdir_cmd);
+#else
+               rc = system(mkdir_cmd);
+               if (rc)
+                       fatal(myrank, "'%s' failed.\n", mkdir_cmd);
+#endif
 
                 rc = chdir(dir);
                 if (rc) {
@@ -546,9 +606,13 @@ static inline char *next_file()
 int
 main(int argc, char *argv[])
 {
-        int    i, j, fd, rc, nops, lastOps, ag_ops;
-        float  rate, ag_rate;
-        time_t startTime, lastTime, curTime, interval;
+        int    i, j, fd, rc, nops, lastOps;
+        int ag_ops = 0;
+        double ag_interval = 0;
+        double ag_rate = 0;
+        double rate, avg_rate, effective_rate;
+        double startTime, curTime, lastTime, interval;
+        time_t timestamp;
         char * file;
 
         rc = MPI_Init(&argc, &argv);
@@ -565,15 +629,16 @@ main(int argc, char *argv[])
 
         process_args(argc, argv);
 
-        startTime = time(0);
+        timestamp = time(0);
         if ((myrank == 0) || debug) {
                printf("%d: %s starting at %s",
-                      myrank, hostname, ctime(&startTime));
+                      myrank, hostname, ctime(&timestamp));
        }
 
         /* if we're not measuring creation rates then precreate
          * the files we're operating on. */
-        if ((mode != CREATE) && (mode != MKNOD) && !ignore) {
+        if ((mode != CREATE) && (mode != MKNOD) && !ignore &&
+            (mode != UNLINK || recreate)) {
                 /* create the files in reverse order. When we encounter
                  * a file that already exists, assume the remainder of 
                  * the files exist to save time. The timed performance
@@ -606,10 +671,10 @@ main(int argc, char *argv[])
                               dir, strerror(rc));
                 }
 
-                startTime = time(0);
+                timestamp = time(0);
                 j = random() % nfiles;
                 dmesg("%d: %s initializing dir offset %u: %s",
-                      myrank, hostname, j, ctime(&startTime));
+                      myrank, hostname, j, ctime(&timestamp));
 
                 for (i = 0; i <= j; i++) {
                         if ((dir_entry = readdir(directory)) == NULL) {
@@ -618,17 +683,13 @@ main(int argc, char *argv[])
                         }
                 }
 
-                lastTime = time(0);
+                timestamp = time(0);
                 dmesg("%d: index %d, filename %s, offset %ld: "
                       "%s initialization complete: %s",
                       myrank, i, dir_entry->d_name, telldir(directory),
-                      hostname, ctime(&lastTime));
+                      hostname, ctime(&timestamp));
         }
 
-        rc = MPI_Barrier(MPI_COMM_WORLD);
-        if (rc != MPI_SUCCESS)
-                fatal(myrank, "prep MPI_Barrier failed: %d\n", rc);
-
         if (seconds) {
                 act.sa_handler = sigalrm_handler;
                 (void)sigemptyset(&act.sa_mask);
@@ -637,7 +698,11 @@ main(int argc, char *argv[])
                 alarm(seconds);
         }
 
-        startTime = lastTime = time(0);
+        rc = MPI_Barrier(MPI_COMM_WORLD);
+        if (rc != MPI_SUCCESS)
+                fatal(myrank, "prep MPI_Barrier failed: %d\n", rc);
+
+        startTime = lastTime = MPI_Wtime();
         nops = lastOps = 0;
 
         switch (mode) {
@@ -652,6 +717,7 @@ main(int argc, char *argv[])
                         }
 
                         close(fd);
+                        nops++;
                         DISPLAY_PROGRESS();
                 }
 
@@ -676,6 +742,7 @@ main(int argc, char *argv[])
                                       "error: %s\n", filename, strerror(rc));
                         }
 
+                        nops++;
                         DISPLAY_PROGRESS();
                 }
                 break;
@@ -691,6 +758,7 @@ main(int argc, char *argv[])
                                       filename, strerror(rc));
                         }
 
+                        nops++;
                         DISPLAY_PROGRESS();
                 }
                 break;
@@ -706,19 +774,24 @@ main(int argc, char *argv[])
 
                         close(fd);
 
+                        nops++;
                         DISPLAY_PROGRESS();
                 }
                 break;
         case STAT:
-                for (; nops < iters && !alarm_caught;) {
-                        rc = stat(file = next_file(), &statbuf);
+                for (; begin <= end && !alarm_caught; begin += dirthreads) {
+                        sprintf(filename, filefmt, begin);
+                        rc = stat(filename, &statbuf);
                         if (rc) {
                                 if (((rc = errno) == EINTR) && alarm_caught)
                                         break;
+                                if (((rc = errno) == ENOENT) && ignore)
+                                        continue;
                                 fatal(myrank, "stat(%s) error: %s\n",
-                                      file, strerror(rc));
+                                      filename, strerror(rc));
                         }
 
+                        nops++;
                         DISPLAY_PROGRESS();
                 }
                 break;
@@ -729,22 +802,28 @@ main(int argc, char *argv[])
                         if (rc) {
                                 if (((rc = errno) == EINTR) && alarm_caught)
                                         break;
-                                if (((rc = errno) == ENOENT) && ignore)
-                                        continue;
+                                if ((rc = errno) == ENOENT) {
+                                        if (ignore)
+                                                continue;
+                                        /* no more files to unlink */
+                                        break;
+                                }
                                 fatal(myrank, "unlink(%s) error: %s\n",
                                       filename, strerror(rc));
                         }
 
+                        nops++;
                         DISPLAY_PROGRESS();
                 }
                 break;
         }
 
-        curTime = time(0);
+        rc = MPI_Barrier(MPI_COMM_WORLD);
+        if (rc != MPI_SUCCESS)
+               fatal(myrank, "prep MPI_Barrier failed: %d\n", rc);
+        curTime = MPI_Wtime();
         interval = curTime - startTime;
-        rate = (float)(nops);
-        if (interval != 0)
-                rate /= (float)interval;
+        rate = (double) (nops) / interval;
 
         rc = MPI_Reduce(&nops, &ag_ops, 1, MPI_INT, MPI_SUM, 0,
                         MPI_COMM_WORLD);
@@ -752,15 +831,32 @@ main(int argc, char *argv[])
                 fatal(myrank, "Failure in MPI_Reduce of total ops.\n");
         }
 
-        rc = MPI_Reduce(&rate, &ag_rate, 1, MPI_FLOAT, MPI_SUM, 0,
+        rc = MPI_Reduce(&interval, &ag_interval, 1, MPI_DOUBLE, MPI_SUM, 0,
+                        MPI_COMM_WORLD);
+        if (rc != MPI_SUCCESS) {
+                fatal(myrank, "Failure in MPI_Reduce of total interval.\n");
+        }
+
+        rc = MPI_Reduce(&rate, &ag_rate, 1, MPI_DOUBLE, MPI_SUM, 0,
                         MPI_COMM_WORLD);
         if (rc != MPI_SUCCESS) {
                 fatal(myrank, "Failure in MPI_Reduce of aggregated rate.\n");
         }
 
         if (myrank == 0) {
-                printf("Rate: %.2f %ss/sec (total: %d threads %d %ss %lu secs)"
-                       "\n", ag_rate, cmd, nthreads, ag_ops, cmd, interval);
+
+                curTime = MPI_Wtime();
+                interval = curTime - startTime;
+                effective_rate = (double) ag_ops / interval;
+                avg_rate = (double) ag_ops / ag_interval;
+
+                printf("Rate: %.2f eff %.2f aggr %.2f avg client %ss/sec "
+                       "(total: %d threads %d %ss %d dirs %d threads/dir %.2f secs)\n",
+                       effective_rate, ag_rate, avg_rate, cmd, nthreads, ag_ops,
+                       cmd, ndirs, dirthreads, interval);
+                if (mode == UNLINK && !recreate && !ignore && ag_ops != nfiles)
+                        printf("Warning: only unlinked %d files instead of %d"
+                               "\n", ag_ops, nfiles);
         }
 
         if (recreate) {
@@ -778,10 +874,10 @@ main(int argc, char *argv[])
                 }
         }
 
-        curTime = time(0);
+        timestamp = time(0);
         if ((myrank == 0) || debug) {
                printf("%d: %s finished at %s",
-                      myrank, hostname, ctime(&curTime));
+                      myrank, hostname, ctime(&timestamp));
        }
 
         MPI_Finalize();