Whamcloud - gitweb
smash the HEAD with the contents of b_cmd. HEAD_PRE_CMD_SMASH and
[fs/lustre-release.git] / lustre / tests / write_disjoint.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Each loop does 3 things:
5  *   - rank 0 truncates to 0
6  *   - all ranks agree on a random chunk size
7  *   - all ranks race to write their pattern to their chunk of the file
8  *   - rank 0 makes sure that the resulting file size is ranks * chunk size
9  *   - rank 0 makes sure that everyone's patterns went to the right place
10  *
11  * compile: mpicc -g -Wall -o write_disjoint write_disjoint.c
12  * run:     mpirun -np N -machlist <hostlist file> write_disjoint
13  *  or:     pdsh -w <N hosts> write_disjoint 
14  *  or:     prun -n N [-N M] write_disjoint
15  */
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <unistd.h>
24 #include <stdarg.h>
25 #include "mpi.h"
26
27
28 #define FILENAME "/mnt/lustre/write_disjoint"
29 #define CHUNK_MAX_SIZE 123456
30
31 int rprintf(int rank, int loop, const char *fmt, ...)
32 {
33         va_list       ap;
34  
35         printf("rank %d, loop %d: ", rank, loop);
36  
37         va_start(ap, fmt);
38  
39         vprintf(fmt, ap);
40  
41         MPI_Finalize();
42         exit(1);
43 }
44
45 int main (int argc, char *argv[]) {
46          int i, n, fd, chunk_size, file_size;
47          int rank, noProcessors, done;
48          off_t offset;
49          char **chunk_buf;
50          char *read_buf;
51          struct stat stat_buf;
52          ssize_t ret;
53
54          MPI_Init(&argc, &argv);
55          MPI_Comm_size(MPI_COMM_WORLD, &noProcessors);
56          MPI_Comm_rank(MPI_COMM_WORLD, &rank);
57                          
58          chunk_buf = malloc(noProcessors * sizeof(chunk_buf[0]));
59          for (i=0; i < noProcessors; i++) {
60                 chunk_buf[i] = malloc(CHUNK_MAX_SIZE);
61                 memset(chunk_buf[i], 'A'+ i, CHUNK_MAX_SIZE);
62          }
63          read_buf = malloc(noProcessors * CHUNK_MAX_SIZE);
64          
65          if (rank == 0) {
66                 fd = open(FILENAME, O_WRONLY|O_CREAT|O_TRUNC, 0666);
67                 if (fd < 0) 
68                         rprintf(rank, -1, "open() returned %s\n", 
69                                 strerror(errno));
70          }
71          MPI_Barrier(MPI_COMM_WORLD);
72
73          fd = open(FILENAME, O_RDWR);
74          if (fd < 0)
75                  rprintf(rank, -1, "open() returned %s\n", strerror(errno));
76          
77          for (n=0; n < 1000 ; n++) {
78                  /* reset the environment */
79                  if (rank == 0) {
80                          ret = truncate(FILENAME, 0);
81                          if (ret != 0)
82                                  rprintf(rank, n, "truncate() returned %s\n", 
83                                          strerror(errno) );
84                  }
85                  chunk_size = rand() % CHUNK_MAX_SIZE;
86
87                  if (n % 1000 == 0 && rank == 0)
88                          printf("loop %d: chunk_size %d\n", n, chunk_size);
89
90                  MPI_Barrier(MPI_COMM_WORLD);
91                  
92                  /* Do the race */
93                  offset = rank * chunk_size;
94                  lseek(fd, offset, SEEK_SET);
95
96                  done = 0;
97                  do {
98                         ret = write(fd, chunk_buf[rank]+done, chunk_size-done);
99                         if (ret < 0) 
100                                  rprintf(rank, n, "write() returned %s\n", 
101                                          strerror(errno));
102                         done += ret;
103                  } while (done != chunk_size);
104
105                  MPI_Barrier(MPI_COMM_WORLD);
106
107                  /* Check the result */
108                  if (rank == 0) {
109                          lseek(fd, 0, SEEK_SET);
110                          
111                          /* quick check */
112                          stat(FILENAME, &stat_buf);
113                          file_size = stat_buf.st_size;
114                          if (file_size != chunk_size * noProcessors)
115                                   rprintf(rank, n, "invalid file size %d"
116                                           " instead of %d\n", file_size, 
117                                           chunk_size * noProcessors);
118
119                         done = 0;
120                         do {
121                                 ret = read(fd, read_buf + done, 
122                                            (chunk_size * noProcessors) - done);
123                                 if (ret < 0) 
124                                         rprintf(rank, n, "read returned %s\n",
125                                                 strerror(errno));
126
127                                 done += ret;
128                         } while (done != chunk_size * noProcessors);
129
130                         for (i = 0; i < noProcessors; i++) {
131                                 char command[4096]; 
132                                 int j;
133                                 if (!memcmp(read_buf + (i * chunk_size), 
134                                            chunk_buf[i], chunk_size))
135                                         continue;
136
137                                 printf("rank %d, loop %d: chunk %d corrupted "
138                                        "with chunk_size %d\n", rank, n, i, 
139                                        chunk_size);
140                                 printf("(ranks: page boundry, chunk boundry, "
141                                        "page boundry)\n");
142                                 for (j = 1 ; j < noProcessors; j++) {
143                                         int b = j * chunk_size;
144                                         printf("\t%c -> %c: %d %d %d\n", 
145                                                'A' + j - 1, 'A' + j, 
146                                                b & ~(4096-1), b, 
147                                                (b + 4096) & ~(4096-1));
148                                 }
149
150                                 sprintf(command, "od -Ad -a %s", FILENAME);
151                                 system(command);
152                                 MPI_Finalize();
153                                 exit(1);
154                         }
155                 }
156         }
157
158         printf("Finished after %d loops\n", n);
159         MPI_Finalize();
160         return 0;
161 }