Whamcloud - gitweb
8bcb5551163505f4c3eb6d496ec9da4cdc62ee55
[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) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2014, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  *
32  * lustre/tests/lp_utils.c
33  *
34  * Author: You Feng <youfeng@clusterfs.com>
35  */
36
37 #include <mpi.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <time.h>
41 #include <sys/time.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <unistd.h>
45 #include <sys/ioctl.h>
46 #include <fcntl.h>
47 #include <errno.h>
48 #include "lp_utils.h"
49
50 #define MAX_PROCESSES 8
51
52 int verbose;
53 int debug;
54
55 char hostname[1024];
56
57 struct timeval t1, t2;
58
59 char *timestamp()
60 {
61         static char datestring[80];
62         time_t timestamp;
63
64         fflush(stdout);
65         timestamp = time(NULL);
66         strftime(datestring, 80, "%T", localtime(&timestamp));
67
68         return datestring;
69 }
70
71 void begin(char *str)
72 {
73         if (verbose > 0 && rank == 0) {
74                 gettimeofday(&t1, NULL);
75                 printf("%s:\tBeginning %s\n", timestamp(), str);
76                 fflush(stdout);
77         }
78 }
79
80 void end(char *str)
81 {
82         float elapsed;
83
84         MPI_Barrier(MPI_COMM_WORLD);
85         if (verbose > 0 && rank == 0) {
86                 gettimeofday(&t2, NULL);
87                 elapsed = (t2.tv_sec + ((float)t2.tv_usec / 1000000)) -
88                         (t1.tv_sec + ((float)t1.tv_usec / 1000000));
89                 if (elapsed >= 60) {
90                         printf("%s:\tFinished %-15s(%.2f min)\n", timestamp(),
91                                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 /*
154  * This function does not FAIL if the requested "name" does not exit.
155  * This is just to clean up any files or directories left over from
156  * previous runs
157  */
158 void remove_file_or_dir(char *name)
159 {
160         struct stat statbuf;
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                                 FAILF("unlink of %s", name);
167                 }
168                 if (S_ISDIR(statbuf.st_mode)) {
169                         printf("stale directory found\n");
170                         if (rmdir(name) == -1)
171                                 FAILF("rmdir of %s", name);
172                 }
173         }
174 }
175
176 void create_file(char *name, long filesize, int fill)
177 {
178         static char filename[MAX_FILENAME_LEN];
179         char buf[1024 * 8];
180         char c = 'A' + size;
181         int fd, rc;
182         short zero = 0;
183         long left = filesize;
184
185         /* Process 0 creates the test file(s) */
186         if (rank == 0) {
187                 sprintf(filename, "%s/%s", testdir, name);
188                 remove_file_or_dir(filename);
189                 fd = creat(filename, FILEMODE);
190                 if (fd < 0)
191                         FAILF("create of file %s", filename);
192
193                 if (filesize > 0) {
194                         if (lseek(fd, filesize - 1, SEEK_SET) == -1) {
195                                 close(fd);
196                                 FAILF("lseek of file %s", filename);
197                         }
198                         if (write(fd, &zero, 1) == -1) {
199                                 close(fd);
200                                 FAILF("write of file %s", filename);
201                         }
202                 }
203                 if (filesize > 0 && fill) {
204                         if (lseek(fd, 0, SEEK_SET) == -1) {
205                                 close(fd);
206                                 FAILF("lseek of file %s", filename);
207                         }
208                         memset(buf, c, 1024);
209                         while (left > 0) {
210                                 rc = write(fd, buf, MAX(left, 8192));
211                                 if (rc < 0) {
212                                         close(fd);
213                                         FAILF("write of file %s", filename);
214                                 }
215                                 left -= rc;
216                         }
217                 }
218                 if (close(fd) == -1)
219                         FAILF("close of file %s", filename);
220         }
221 }
222
223 void check_stat(char *filename, struct stat *state, struct stat *old_state)
224 {
225         if (stat(filename, state) == -1)
226                 FAILF("stat of file %s", filename);
227
228         if (memcmp(state, old_state, sizeof(struct stat)) != 0) {
229                 errno = 0;
230                 FAILF(LP_STAT_FMT, LP_STAT_ARGS);
231         }
232 }
233
234 void remove_file(char *name)
235 {
236         char filename[MAX_FILENAME_LEN];
237
238         /* Process 0 remove the file(s) */
239         if (rank == 0) {
240                 sprintf(filename, "%s/%s", testdir, name);
241                 if (unlink(filename) == -1)
242                         FAILF("unlink of file %s", filename);
243         }
244 }
245
246 void fill_stride(char *buf, int buf_size, long long rank, long long _off)
247 {
248         char *p = buf;
249         long long off, data[2];
250         int cp, left = buf_size;
251
252         data[0] = rank;
253         off = _off;
254         while (left > 0) {
255                 data[1] = off;
256                 cp = left > sizeof(data) ? sizeof(data) : left;
257                 memcpy(p, data, cp);
258                 off += cp;
259                 p += cp;
260                 left -= cp;
261         }
262 }