Whamcloud - gitweb
LU-14264 tests: make PARALLEL available to all suites
[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  *
31  * lustre/tests/lp_utils.c
32  *
33  * Author: You Feng <youfeng@clusterfs.com>
34  */
35
36 #include <mpi.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <time.h>
40 #include <sys/time.h>
41 #include <sys/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                 elapsed = (t2.tv_sec + ((float)t2.tv_usec / 1000000)) -
87                         (t1.tv_sec + ((float)t1.tv_usec / 1000000));
88                 if (elapsed >= 60) {
89                         printf("%s:\tFinished %-15s(%.2f min)\n", timestamp(),
90                                str, elapsed / 60);
91                 } else {
92                         printf("%s:\tFinished %-15s(%.3f sec)\n",
93                                timestamp(), str, elapsed);
94                 }
95                 fflush(stdout);
96         }
97 }
98
99 void dump_diff(char *orig_buf, char *buf, int size, long _off)
100 {
101         int i, diff, off;
102         char *p, *end;
103
104         printf("commpared buf size %d, at offset %lu\n\n", size, _off);
105
106         if (orig_buf) {
107                 printf("original buf:\n");
108                 p = orig_buf;
109                 end = orig_buf + size;
110                 i = 1;
111                 while (p < end) {
112                         printf(" %8lx", *(long *)p);
113                         p += sizeof(long);
114                         if (i++ % 8 == 0)
115                                 printf("\n");
116                 }
117                 if (i % 8)
118                         printf("\n\n");
119                 else
120                         printf("\n");
121         }
122
123         if (buf) {
124                 printf("different data: diff_data(orig_data)\n");
125                 diff = 0;
126                 off = 0;
127                 i = 1;
128                 p = buf;
129                 end = buf + size;
130                 while (p < end) {
131                         if (memcmp(p, orig_buf + off, sizeof(long)) != 0) {
132                                 printf("\toff: %5d,\tdata: %8lx (%8lx)\n", off,
133                                        *(unsigned long *)p,
134                                        *(unsigned long *)(orig_buf + off));
135                                 diff++;
136                         }
137                         off += sizeof(long);
138                         p += sizeof(long);
139                 }
140                 printf("\n %d total differents found\n\n", diff);
141         }
142 }
143
144 void lp_gethostname(void)
145 {
146         if (gethostname(hostname, 1024) == -1) {
147                 fprintf(stderr, "gethostname: (%d)%s", errno, strerror(errno));
148                 MPI_Abort(MPI_COMM_WORLD, 2);
149         }
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
161         if (stat(name, &statbuf) != -1) {
162                 if (S_ISREG(statbuf.st_mode)) {
163                         printf("stale file found\n");
164                         if (unlink(name) == -1)
165                                 FAILF("unlink of %s", name);
166                 }
167                 if (S_ISDIR(statbuf.st_mode)) {
168                         printf("stale directory found\n");
169                         if (rmdir(name) == -1)
170                                 FAILF("rmdir of %s", name);
171                 }
172         }
173 }
174
175 void create_file(char *name, long filesize, int fill)
176 {
177         static char filename[MAX_FILENAME_LEN];
178         char buf[1024 * 8];
179         char c = 'A' + size;
180         int fd, rc;
181         short zero = 0;
182         long left = filesize;
183
184         /* Process 0 creates the test file(s) */
185         if (rank == 0) {
186                 sprintf(filename, "%s/%s", testdir, name);
187                 remove_file_or_dir(filename);
188                 fd = creat(filename, FILEMODE);
189                 if (fd < 0)
190                         FAILF("create of file %s", filename);
191
192                 if (filesize > 0) {
193                         if (lseek(fd, filesize - 1, SEEK_SET) == -1) {
194                                 close(fd);
195                                 FAILF("lseek of file %s", filename);
196                         }
197                         if (write(fd, &zero, 1) == -1) {
198                                 close(fd);
199                                 FAILF("write of file %s", filename);
200                         }
201                 }
202                 if (filesize > 0 && fill) {
203                         if (lseek(fd, 0, SEEK_SET) == -1) {
204                                 close(fd);
205                                 FAILF("lseek of file %s", filename);
206                         }
207                         memset(buf, c, 1024);
208                         while (left > 0) {
209                                 rc = write(fd, buf, MAX(left, 8192));
210                                 if (rc < 0) {
211                                         close(fd);
212                                         FAILF("write of file %s", filename);
213                                 }
214                                 left -= rc;
215                         }
216                 }
217                 if (close(fd) == -1)
218                         FAILF("close of file %s", filename);
219         }
220 }
221
222 void check_stat(char *filename, struct stat *state, struct stat *old_state)
223 {
224         if (stat(filename, state) == -1)
225                 FAILF("stat of file %s", filename);
226
227         if (memcmp(state, old_state, sizeof(struct stat)) != 0) {
228                 errno = 0;
229                 FAILF(LP_STAT_FMT, LP_STAT_ARGS);
230         }
231 }
232
233 void remove_file(char *name)
234 {
235         char filename[MAX_FILENAME_LEN];
236
237         /* Process 0 remove the file(s) */
238         if (rank == 0) {
239                 sprintf(filename, "%s/%s", testdir, name);
240                 if (unlink(filename) == -1)
241                         FAILF("unlink of file %s", filename);
242         }
243 }
244
245 void fill_stride(char *buf, int buf_size, long long rank, long long _off)
246 {
247         char *p = buf;
248         long long off, data[2];
249         int cp, left = buf_size;
250
251         data[0] = rank;
252         off = _off;
253         while (left > 0) {
254                 data[1] = off;
255                 cp = left > sizeof(data) ? sizeof(data) : left;
256                 memcpy(p, data, cp);
257                 off += cp;
258                 p += cp;
259                 left -= cp;
260         }
261 }