Whamcloud - gitweb
LU-13773 tests: subscript failure propagation
[fs/lustre-release.git] / lustre / tests / mpi / write_disjoint.c
index f5b3454..7848412 100644 (file)
@@ -1,6 +1,4 @@
-/* -*- 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.
  *
  * 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.
+ * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * GPL HEADER END
  */
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 #include <errno.h>
 #include <unistd.h>
 #include <stdarg.h>
+#include <time.h>
 #include "mpi.h"
 
-#define CHUNK_MAX_SIZE 123456
+/* Chosen arbitrarily.  Actually running this large will take a long time.*/
+#define CHUNK_MAX_SIZE (1024 * 1024 * 16)
 
 void rprintf(int rank, int loop, const char *fmt, ...)
 {
-        va_list       ap;
+       va_list ap;
 
-        printf("rank %d, loop %d: ", rank, loop);
+       printf("rank %d, loop %d: ", rank, loop);
 
-        va_start(ap, fmt);
+       va_start(ap, fmt);
 
-        vprintf(fmt, ap);
+       vprintf(fmt, ap);
 
-        MPI_Abort(MPI_COMM_WORLD, -1); /* This will exit() according to man */
+       MPI_Abort(MPI_COMM_WORLD, -1); /* This will exit() according to man */
 }
 
 #define CHUNK_SIZE(n) chunk_size[(n) % 2]
 
-int main (int argc, char *argv[]) {
-        int i, n, fd, c;
-        unsigned long chunk_size[2];
-        int rank, noProcessors, done;
-        int error;
-        off_t offset;
-        char **chunk_buf;
-        char *read_buf;
-        struct stat stat_buf;
-        ssize_t ret;
-        char *filename = "/mnt/lustre/write_disjoint";
-        int numloops = 1000;
-        int random = 0;
-
-        error = MPI_Init(&argc, &argv);
-        if (error != MPI_SUCCESS)
-                rprintf(-1, -1, "MPI_Init failed: %d\n", error);
-        /* Parse command line options */
-        while ((c = getopt(argc, argv, "f:n:")) != EOF) {
-                switch (c) {
-                case 'f':
-                        filename = optarg;
-                        break;
-                case 'n':
-                        numloops = strtoul(optarg, NULL, 0);
-                        break;
-                }
-        }
-
-        MPI_Comm_size(MPI_COMM_WORLD, &noProcessors);
-        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-
-        chunk_buf = malloc(noProcessors * sizeof(chunk_buf[0]));
-        for (i=0; i < noProcessors; i++) {
-                chunk_buf[i] = malloc(CHUNK_MAX_SIZE);
-                memset(chunk_buf[i], 'A'+ i, CHUNK_MAX_SIZE);
-        }
-        read_buf = malloc(noProcessors * CHUNK_MAX_SIZE);
-
-        if (rank == 0) {
-                fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
-                if (fd < 0)
-                        rprintf(rank, -1, "open() returned %s\n",
-                                strerror(errno));
-        }
-        MPI_Barrier(MPI_COMM_WORLD);
-
-        fd = open(filename, O_RDWR);
-        if (fd < 0)
-                rprintf(rank, -1, "open() returned %s\n", strerror(errno));
-
-        for (n = 0; n < numloops; n++) {
-                /* reset the environment */
-                if (rank == 0) {
-                        ret = truncate(filename, 0);
-                        if (ret != 0)
-                                rprintf(rank, n, "truncate() returned %s\n",
-                                        strerror(errno) );
-                        random = rand();
-                }
-                MPI_Bcast(&random, 1, MPI_INT, 0, MPI_COMM_WORLD);
-                CHUNK_SIZE(n) = random % CHUNK_MAX_SIZE;
-
-                if (n % 1000 == 0 && rank == 0)
-                        printf("loop %d: chunk_size %lu\n", n, CHUNK_SIZE(n));
-
-                if (stat(filename, &stat_buf) < 0)
-                        rprintf(rank, n, "error stating %s: %s\n",
-                                filename, strerror(errno));
-
-                if (stat_buf.st_size != 0)
-                        rprintf(rank, n, "filesize = %lu. "
-                                "Should be zero after truncate\n",
-                                stat_buf.st_size);
-
-                MPI_Barrier(MPI_COMM_WORLD);
-
-                /* Do the race */
-                offset = rank * CHUNK_SIZE(n);
-                lseek(fd, offset, SEEK_SET);
-
-                done = 0;
-                do {
-                        ret = write(fd, chunk_buf[rank] + done,
-                                    CHUNK_SIZE(n) - done);
-                        if (ret < 0 && errno != EINTR)
-                                rprintf(rank, n, "write() returned %s\n",
-                                        strerror(errno));
-                        if (ret > 0)
-                                done += ret;
-                } while (done != CHUNK_SIZE(n));
-
-                MPI_Barrier(MPI_COMM_WORLD);
-
-                /* Check the result */
-                if (stat(filename, &stat_buf) < 0)
-                        rprintf(rank, n, "error stating %s: %s\n",
-                                filename, strerror(errno));
-
-                if (stat_buf.st_size != CHUNK_SIZE(n) * noProcessors) {
-                        if (n > 0)
-                                printf("loop %d: chunk_size %lu, "
-                                       "file size was %lu\n",
-                                       n - 1, CHUNK_SIZE(n - 1),
-                                       CHUNK_SIZE(n - 1) *noProcessors);
-                        rprintf(rank, n, "invalid file size %lu"
-                                " instead of %lu = %lu * %u\n",
-                                (unsigned long)stat_buf.st_size,
-                                CHUNK_SIZE(n) * noProcessors,
-                                CHUNK_SIZE(n), noProcessors);
-                }
-
-                if (rank == 0) {
-                        if (lseek(fd, 0, SEEK_SET) < 0)
-                                rprintf(rank, n, "error seeking to 0: %s\n",
-                                        strerror(errno));
-
-                        done = 0;
-                        do {
-                                ret = read(fd, read_buf + done,
-                                           CHUNK_SIZE(n) * noProcessors - done);
-                                if (ret < 0)
-                                        rprintf(rank, n, "read returned %s\n",
-                                                strerror(errno));
-
-                                done += ret;
-                        } while (done != CHUNK_SIZE(n) * noProcessors);
-
-                        for (i = 0; i < noProcessors; i++) {
-                                char command[4096];
-                                int j, rc;
-                                if (!memcmp(read_buf + (i * CHUNK_SIZE(n)),
-                                            chunk_buf[i], CHUNK_SIZE(n)))
-                                        continue;
-
-                                /* print out previous chunk sizes */
-                                if (n > 0)
-                                        printf("loop %d: chunk_size %lu\n",
-                                               n - 1, CHUNK_SIZE(n - 1));
-
-                                printf("loop %d: chunk %d corrupted "
-                                       "with chunk_size %lu, page_size %d\n",
-                                       n, i, CHUNK_SIZE(n), getpagesize());
-                                printf("ranks:\tpage boundry\tchunk boundry\t"
-                                       "page boundry\n");
-                                for (j = 1 ; j < noProcessors; j++) {
-                                        int b = j * CHUNK_SIZE(n);
-                                        printf("%c -> %c:\t%d\t%d\t%d\n",
-                                               'A' + j - 1, 'A' + j,
-                                               b & ~(getpagesize()-1), b,
-                                               (b + getpagesize()) &
-                                               ~(getpagesize()-1));
-                                }
-
-                                sprintf(command, "od -Ad -a %s", filename);
-                                rc = system(command);
-                                rprintf(0, n, "data check error - exiting\n");
-                        }
-                }
-                MPI_Barrier(MPI_COMM_WORLD);
-        }
-
-        printf("Finished after %d loops\n", n);
-        MPI_Finalize();
-        return 0;
+int main(int argc, char *argv[])
+{
+       int i, n, fd, c;
+       unsigned long chunk_size[2];
+       int rank, noProcessors, done;
+       int error;
+       off_t offset;
+       char **chunk_buf;
+       char *read_buf;
+       struct stat stat_buf;
+       ssize_t ret;
+       char *filename = "/mnt/lustre/write_disjoint";
+       int numloops = 1000;
+       int max_size = CHUNK_MAX_SIZE;
+       int random = 0;
+       unsigned int seed = 0;
+       int seed_provided = 0;
+
+       error = MPI_Init(&argc, &argv);
+       if (error != MPI_SUCCESS)
+               rprintf(-1, -1, "MPI_Init failed: %d\n", error);
+       /* Parse command line options */
+       while ((c = getopt(argc, argv, "f:n:m:s:")) != EOF) {
+               errno = 0;
+               switch (c) {
+               case 'f':
+                       filename = optarg;
+                       break;
+               case 'n':
+                       numloops = strtoul(optarg, NULL, 0);
+                       break;
+               case 'm':
+                       max_size = strtoul(optarg, NULL, 0);
+                       if (max_size > CHUNK_MAX_SIZE)
+                               rprintf(-1, -1, "Chunk size larger than %d.\n",
+                                       CHUNK_MAX_SIZE);
+                       break;
+               case 's':
+                       seed = strtoul(optarg, NULL, 0);
+                       seed_provided = 1;
+                       break;
+               }
+       }
+
+       MPI_Comm_size(MPI_COMM_WORLD, &noProcessors);
+       MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+       chunk_buf = malloc(noProcessors * sizeof(chunk_buf[0]));
+       for (i = 0; i < noProcessors; i++) {
+               chunk_buf[i] = malloc(max_size);
+               memset(chunk_buf[i], 'A' + i, max_size);
+       }
+       read_buf = malloc(noProcessors * max_size);
+
+       if (rank == 0) {
+               fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+               if (fd < 0)
+                       rprintf(rank, -1, "open() returned %s\n",
+                               strerror(errno));
+       }
+       MPI_Barrier(MPI_COMM_WORLD);
+
+       fd = open(filename, O_RDWR);
+       if (fd < 0)
+               rprintf(rank, -1, "open() returned %s\n", strerror(errno));
+
+       if (rank == 0) {
+               if (!seed_provided)
+                       seed = (unsigned int)time(NULL);
+               printf("random seed: %d\n", seed);
+               srand(seed);
+       }
+
+       for (n = 0; n < numloops; n++) {
+               /* reset the environment */
+               if (rank == 0) {
+                       ret = truncate(filename, 0);
+                       if (ret != 0)
+                               rprintf(rank, n, "truncate() returned %s\n",
+                                       strerror(errno));
+
+                       random = rand();
+               }
+               MPI_Bcast(&random, 1, MPI_INT, 0, MPI_COMM_WORLD);
+               CHUNK_SIZE(n) = random % max_size;
+
+               if (n % 1000 == 0 && rank == 0)
+                       printf("loop %d: chunk_size %lu\n", n, CHUNK_SIZE(n));
+
+               if (stat(filename, &stat_buf) < 0)
+                       rprintf(rank, n, "error stating %s: %s\n",
+                               filename, strerror(errno));
+
+               if (stat_buf.st_size != 0)
+                       rprintf(rank, n,
+                               "filesize = %lu. Should be zero after truncate\n",
+                               stat_buf.st_size);
+
+               MPI_Barrier(MPI_COMM_WORLD);
+
+               /* Do the race */
+               offset = rank * CHUNK_SIZE(n);
+               lseek(fd, offset, SEEK_SET);
+
+               done = 0;
+               do {
+                       ret = write(fd, chunk_buf[rank] + done,
+                                   CHUNK_SIZE(n) - done);
+                       if (ret < 0 && errno != EINTR)
+                               rprintf(rank, n, "write() returned %s\n",
+                                       strerror(errno));
+                       if (ret > 0)
+                               done += ret;
+               } while (done != CHUNK_SIZE(n));
+
+               MPI_Barrier(MPI_COMM_WORLD);
+
+               /* Check the result */
+               if (stat(filename, &stat_buf) < 0)
+                       rprintf(rank, n, "error stating %s: %s\n",
+                               filename, strerror(errno));
+
+               if (stat_buf.st_size != CHUNK_SIZE(n) * noProcessors) {
+                       if (n > 0)
+                               printf("loop %d: chunk_size %lu, file size was %lu\n",
+                                      n - 1, CHUNK_SIZE(n - 1),
+                                      CHUNK_SIZE(n - 1) * noProcessors);
+                       rprintf(rank, n,
+                               "invalid file size %lu instead of %lu = %lu * %u\n",
+                               (unsigned long)stat_buf.st_size,
+                               CHUNK_SIZE(n) * noProcessors,
+                               CHUNK_SIZE(n), noProcessors);
+               }
+
+               if (rank == 0) {
+                       if (lseek(fd, 0, SEEK_SET) < 0)
+                               rprintf(rank, n, "error seeking to 0: %s\n",
+                                       strerror(errno));
+
+                       done = 0;
+                       do {
+                               ret = read(fd, read_buf + done,
+                                          CHUNK_SIZE(n) * noProcessors - done);
+                               if (ret < 0)
+                                       rprintf(rank, n, "read returned %s\n",
+                                               strerror(errno));
+
+                               done += ret;
+                       } while (done != CHUNK_SIZE(n) * noProcessors);
+
+                       for (i = 0; i < noProcessors; i++) {
+                               char command[4096];
+                               int j;
+
+                               if (!memcmp(read_buf + (i * CHUNK_SIZE(n)),
+                                           chunk_buf[i], CHUNK_SIZE(n)))
+                                       continue;
+
+                               /* print out previous chunk sizes */
+                               if (n > 0)
+                                       printf("loop %d: chunk_size %lu\n",
+                                              n - 1, CHUNK_SIZE(n - 1));
+
+                               printf("loop %d: chunk %d corrupted with chunk_size %lu, page_size %d\n",
+                                      n, i, CHUNK_SIZE(n), getpagesize());
+                               printf("ranks:\tpage boundry\tchunk boundry\tpage boundry\n");
+                               for (j = 1 ; j < noProcessors; j++) {
+                                       int b = j * CHUNK_SIZE(n);
+
+                                       printf("%c -> %c:\t%d\t%d\t%d\n",
+                                              'A' + j - 1, 'A' + j,
+                                              b & ~(getpagesize() - 1), b,
+                                              (b + getpagesize()) &
+                                              ~(getpagesize() - 1));
+                               }
+
+                               sprintf(command, "od -Ad -a %s", filename);
+                               ret = system(command);
+                               rprintf(0, n, "data check error - exiting\n");
+                       }
+               }
+               MPI_Barrier(MPI_COMM_WORLD);
+       }
+
+       printf("Finished after %d loops\n", n);
+       MPI_Finalize();
+       return 0;
 }