Whamcloud - gitweb
b64d207677cc7f1639a5e5522bde31a0035f2d6a
[fs/lustre-release.git] / lustre / tests / mpi / lp_utils.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  */
26 /*
27  * This file is part of Lustre, http://www.lustre.org/
28  * Lustre is a trademark of Sun Microsystems, Inc.
29  *
30  * lustre/tests/lp_utils.c
31  *
32  * Author: You Feng <youfeng@clusterfs.com>
33  */
34 #include <limits.h>
35 #include <mpi.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <time.h>
39 #include <sys/time.h>
40 #include <sys/types.h>
41 #include <asm/types.h>
42 #include <sys/stat.h>
43 #include <unistd.h>
44 #include <sys/ioctl.h>
45 #include <fcntl.h>
46 #include <errno.h>
47 #include "lp_utils.h"
48
49 #define MAX_PROCESSES 8
50
51 int verbose;
52 int debug;
53
54 char hostname[1024];
55
56 struct timeval t1, t2;
57
58 char *timestamp()
59 {
60         static char datestring[80];
61         time_t timestamp;
62
63         fflush(stdout);
64         timestamp = time(NULL);
65         strftime(datestring, 80, "%T", localtime(&timestamp));
66
67         return datestring;
68 }
69
70 void begin(char *str)
71 {
72         if (verbose > 0 && rank == 0) {
73                 gettimeofday(&t1, NULL);
74                 printf("%s:\tBeginning %s\n", timestamp(), str);
75                 fflush(stdout);
76         }
77 }
78
79 void end(char *str)
80 {
81         float elapsed;
82
83         MPI_Barrier(MPI_COMM_WORLD);
84         if (verbose > 0 && rank == 0) {
85                 gettimeofday(&t2, NULL);
86
87                 elapsed = t2.tv_sec - t1.tv_sec +
88                         (float)(t2.tv_usec - t1.tv_usec) / 1000000;
89                 if (elapsed >= 60) {
90                         printf("%s:\tFinished %-15s(%.2f min)\n",
91                                timestamp(), str, elapsed / 60);
92                 } else {
93                         printf("%s:\tFinished %-15s(%.3f sec)\n",
94                                timestamp(), str, elapsed);
95                 }
96                 fflush(stdout);
97         }
98 }
99
100 void dump_diff(char *orig_buf, char *buf, int size, long _off)
101 {
102         int i, diff, off;
103         char *p, *end;
104
105         printf("commpared buf size %d, at offset %lu\n\n", size, _off);
106
107         if (orig_buf) {
108                 printf("original buf:\n");
109                 p = orig_buf;
110                 end = orig_buf + size;
111                 i = 1;
112                 while (p < end) {
113                         printf(" %8lx", *(long *)p);
114                         p += sizeof(long);
115                         if (i++ % 8 == 0)
116                                 printf("\n");
117                 }
118                 if (i % 8)
119                         printf("\n\n");
120                 else
121                         printf("\n");
122         }
123
124         if (buf) {
125                 printf("different data: diff_data(orig_data)\n");
126                 diff = 0;
127                 off = 0;
128                 i = 1;
129                 p = buf;
130                 end = buf + size;
131                 while (p < end) {
132                         if (memcmp(p, orig_buf + off, sizeof(long)) != 0) {
133                                 printf("\toff: %5d,\tdata: %8lx (%8lx)\n", off,
134                                        *(unsigned long *)p,
135                                        *(unsigned long *)(orig_buf + off));
136                                 diff++;
137                         }
138                         off += sizeof(long);
139                         p += sizeof(long);
140                 }
141                 printf("\n %d total differents found\n\n", diff);
142         }
143 }
144
145 void lp_gethostname(void)
146 {
147         if (gethostname(hostname, 1024) == -1) {
148                 fprintf(stderr, "gethostname: (%d)%s", errno, strerror(errno));
149                 MPI_Abort(MPI_COMM_WORLD, 2);
150         }
151 }
152
153 /* This function does not FAIL if the requested "name" does not exit.
154  * This is just to clean up any files or directories left over from
155  * previous runs
156  */
157 void remove_file_or_dir(char *name)
158 {
159         struct stat statbuf;
160         char errmsg[MAX_FILENAME_LEN + 20];
161
162         if (stat(name, &statbuf) != -1) {
163                 if (S_ISREG(statbuf.st_mode)) {
164                         printf("stale file found\n");
165                         if (unlink(name) == -1) {
166                                 sprintf(errmsg, "unlink of %s", name);
167                                 FAIL(errmsg);
168                         }
169                 }
170                 if (S_ISDIR(statbuf.st_mode)) {
171                         printf("stale directory found\n");
172                         if (rmdir(name) == -1) {
173                                 sprintf(errmsg, "rmdir of %s", name);
174                                 FAIL(errmsg);
175                         }
176                 }
177         }
178 }
179
180 void create_file(char *name, long filesize, int fill)
181 {
182         static char filename[MAX_FILENAME_LEN];
183         char errmsg[MAX_FILENAME_LEN + 20];
184         char buf[1024 * 8];
185         char c = 'A' + size;
186         int fd, rc;
187         short zero = 0;
188         long left = filesize;
189
190         /* Process 0 creates the test file(s) */
191         if (rank == 0) {
192                 sprintf(filename, "%s/%s", testdir, name);
193                 remove_file_or_dir(filename);
194                 if ((fd = creat(filename, FILEMODE)) == -1) {
195                         sprintf(errmsg, "create of file %s", filename);
196                         FAIL(errmsg);
197                 }
198                 if (filesize > 0) {
199                         if (lseek(fd, filesize - 1, SEEK_SET) == -1) {
200                                 close(fd);
201                                 sprintf(errmsg, "lseek of file %s", filename);
202                                 FAIL(errmsg);
203                         }
204                         if (write(fd, &zero, 1) == -1) {
205                                 close(fd);
206                                 sprintf(errmsg, "write of file %s", filename);
207                                 FAIL(errmsg);
208                         }
209                 }
210                 if (filesize > 0 && fill) {
211                         if (lseek(fd, 0, SEEK_SET) == -1) {
212                                 close(fd);
213                                 sprintf(errmsg, "lseek of file %s", filename);
214                                 FAIL(errmsg);
215                         }
216                         memset(buf, c, 1024);
217                         while (left > 0) {
218                                 if ((rc = write(fd, buf,
219                                                 left > (1024 * 8) ? (1024 * 8) : left)) == -1) {
220                                         close(fd);
221                                         sprintf(errmsg, "write of file %s",
222                                                 filename);
223                                         FAIL(errmsg);
224                                 }
225                                 left -= rc;
226                         }
227                 }
228                 if (close(fd) == -1) {
229                         sprintf(errmsg, "close of file %s", filename);
230                         FAIL(errmsg);
231                 }
232         }
233 }
234
235 void check_stat(char *filename, struct stat *state, struct stat *old_state)
236 {
237         char errmsg[MAX_FILENAME_LEN + 20];
238
239         if (stat(filename, state) == -1) {
240                 sprintf(errmsg, "stat of file %s", filename);
241                 FAIL(errmsg);
242         }
243
244         if (memcmp(state, old_state, sizeof(struct stat)) != 0) {
245                 errno = 0;
246                 sprintf(errmsg, LP_STAT_FMT, LP_STAT_ARGS);
247                 FAIL(errmsg);
248         }
249 }
250
251 void remove_file(char *name)
252 {
253         char filename[MAX_FILENAME_LEN];
254         char errmsg[MAX_FILENAME_LEN + 20];
255
256         /* Process 0 remove the file(s) */
257         if (rank == 0) {
258                 sprintf(filename, "%s/%s", testdir, name);
259                 if (unlink(filename) == -1) {
260                         sprintf(errmsg, "unlink of file %s", filename);
261                         FAIL(errmsg);
262                 }
263         }
264 }
265
266 void fill_stride(char *buf, int buf_size, long long rank, long long _off)
267 {
268         char *p = buf;
269         long long off, data[2];
270         int cp, left = buf_size;
271
272         data[0] = rank;
273         off = _off;
274         while (left > 0) {
275                 data[1] = off;
276                 cp = left > sizeof(data) ? sizeof(data) : left;
277                 memcpy(p, data, cp);
278                 off += cp;
279                 p += cp;
280                 left -= cp;
281         }
282 }