Whamcloud - gitweb
f9ebea3eaf02fc826d10eeec076c4dfbc29462d3
[fs/lustre-release.git] / lustre / tests / 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.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2014, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/tests/lp_utils.c
37  *
38  * Author: You Feng <youfeng@clusterfs.com>
39  */
40
41 #include <mpi.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <time.h>
45 #include <sys/time.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <unistd.h>
49 #include <sys/ioctl.h>
50 #include <fcntl.h>
51 #include <errno.h>
52 #include "lustre/lustre_user.h"
53 #include "lustre/tests/lp_utils.h"
54
55 #define MAX_PROCESSES 8
56
57 int verbose = 0;
58 int debug = 0;
59
60 char hostname[1024];
61
62 struct timeval t1, t2;
63
64 char *timestamp() {
65         static char datestring[80];
66         time_t timestamp;
67
68         fflush(stdout);
69         timestamp = time(NULL);
70         strftime(datestring, 80, "%T", localtime(&timestamp));
71
72         return datestring;
73 }
74
75 inline void begin(char *str) {
76         if (verbose > 0 && rank == 0) {
77                 gettimeofday(&t1, NULL);
78                 printf("%s:\tBeginning %s\n", timestamp(), str);
79                 fflush(stdout);
80         }
81 }
82
83 inline void end(char *str) {
84         float elapsed;
85
86         MPI_Barrier(MPI_COMM_WORLD);
87         if (verbose > 0 && rank == 0) {
88                 gettimeofday(&t2, NULL);
89                 elapsed = (t2.tv_sec + ((float)t2.tv_usec/1000000))
90                           - (t1.tv_sec + ((float)t1.tv_usec/1000000));
91                 if (elapsed >= 60) {
92                         printf("%s:\tFinished %-15s(%.2f min)\n",
93                                timestamp(), str, elapsed / 60);
94                 } else {
95                         printf("%s:\tFinished %-15s(%.3f sec)\n",
96                                timestamp(), str, elapsed);
97
98                 }
99                 fflush(stdout);
100         }
101 }
102
103 void dump_diff(char *orig_buf, char *buf, int size, long _off)
104 {
105         int i, diff, off;
106         char *p, *end;
107
108         printf("commpared buf size %d, at offset %lu\n\n", size, _off);
109
110         if (orig_buf) {
111                 printf("original buf:\n");
112                 p = orig_buf;
113                 end = orig_buf + size;
114                 i = 1;
115                 while (p < end) {
116                         printf(" %8lx", *(long *)p);
117                         p += sizeof(long);
118                         if (i++%8 == 0)
119                                 printf("\n");
120                 }
121                 if (i%8) printf("\n\n");
122                 else printf("\n");
123         }
124
125         if (buf) {
126                 printf("different data: diff_data(orig_data)\n");
127                 diff = 0;
128                 off = 0;
129                 i = 1;
130                 p = buf;
131                 end = buf + size;
132                 while (p < end) {
133                         if (memcmp(p, orig_buf + off, sizeof(long)) != 0) {
134                                 printf("\toff: %5d,\tdata: %8lx (%8lx)\n", off,
135                                        *(unsigned long *)p,
136                                        *(unsigned long *)(orig_buf + off));
137                                 diff++;
138                         }
139                         off += sizeof(long);
140                         p += sizeof(long);
141                 }
142                 printf("\n %d total differents found\n\n", diff);
143         }
144 }
145
146 void lp_gethostname(void)
147 {
148         if (gethostname(hostname, 1024) == -1) {
149                 fprintf(stderr, "gethostname: (%d)%s", errno, strerror(errno));
150                 MPI_Abort(MPI_COMM_WORLD, 2);
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         char errmsg[MAX_FILENAME_LEN + 20];
162
163         if (stat(name, &statbuf) != -1) {
164                 if (S_ISREG(statbuf.st_mode)) {
165                         printf("stale file found\n");
166                         if (unlink(name) == -1) {
167                                 sprintf(errmsg, "unlink of %s", name);
168                                 FAIL(errmsg);
169                         }
170                 }
171                 if (S_ISDIR(statbuf.st_mode)) {
172                         printf("stale directory found\n");
173                         if (rmdir(name) == -1) {
174                                 sprintf(errmsg, "rmdir of %s", name);
175                                 FAIL(errmsg);
176                         }
177                 }
178         }
179 }
180
181 void create_file(char *name, long filesize, int fill)
182 {
183         static char filename[MAX_FILENAME_LEN];
184         char errmsg[MAX_FILENAME_LEN + 20];
185         char buf[1024 * 8];
186         char c = 'A' + size;
187         int fd, rc;
188         short zero = 0;
189         long left = filesize;
190
191         /* Process 0 creates the test file(s) */
192         if (rank == 0) {
193                 sprintf(filename, "%s/%s", testdir, name);
194                 remove_file_or_dir(filename);
195                 if ((fd = creat(filename, FILEMODE)) == -1) {
196                         sprintf(errmsg, "create of file %s", filename);
197                         FAIL(errmsg);
198                 }
199                 if (filesize > 0) {
200                         if (lseek(fd, filesize - 1, SEEK_SET) == -1) {
201                                 close(fd);
202                                 sprintf(errmsg, "lseek of file %s", filename);
203                                 FAIL(errmsg);
204                         }
205                         if (write(fd, &zero, 1) == -1) {
206                                 close(fd);
207                                 sprintf(errmsg, "write of file %s", filename);
208                                 FAIL(errmsg);
209                         }
210                 }
211                 if (filesize > 0 && fill) {
212                         if (lseek(fd, 0, SEEK_SET) == -1) {
213                                 close(fd);
214                                 sprintf(errmsg, "lseek of file %s", filename);
215                                 FAIL(errmsg);
216                         }
217                         memset(buf, c, 1024);
218                         while (left > 0) {
219                                 if ((rc = write(fd, buf,
220                                                 left > (1024 * 8) ? (1024 * 8) : left))
221                                     == -1) {
222                                         close(fd);
223                                         sprintf(errmsg, "write of file %s", filename);
224                                         FAIL(errmsg);
225                                 }
226                                 left -= rc;
227                         }
228                 }
229                 if (close(fd) == -1) {
230                         sprintf(errmsg, "close of file %s", filename);
231                         FAIL(errmsg);
232                 }
233         }
234 }
235
236 void check_stat(char *filename, struct stat *state, struct stat *old_state)
237 {
238         char errmsg[MAX_FILENAME_LEN+20];
239
240         if (stat(filename, state) == -1) {
241                 sprintf(errmsg, "stat of file %s", filename);
242                 FAIL(errmsg);
243         }
244
245         if (memcmp(state, old_state, sizeof(struct stat)) != 0) {
246                 errno = 0;
247                 sprintf(errmsg, LP_STAT_FMT, LP_STAT_ARGS);
248                 FAIL(errmsg);
249         }
250 }
251
252 void remove_file(char *name)
253 {
254         char filename[MAX_FILENAME_LEN];
255         char errmsg[MAX_FILENAME_LEN + 20];
256
257         /* Process 0 remove the file(s) */
258         if (rank == 0) {
259                 sprintf(filename, "%s/%s", testdir, name);
260                 if (unlink(filename) == -1) {
261                         sprintf(errmsg, "unlink of file %s", filename);
262                         FAIL(errmsg);
263                 }
264         }
265 }
266
267 void fill_stride(char *buf, int buf_size, long long rank, long long _off)
268 {
269         char *p = buf;
270         long long off, data[2];
271         int cp, left = buf_size;
272
273         data[0] = rank;
274         off = _off;
275         while (left > 0) {
276                 data[1] = off;
277                 cp = left > sizeof(data) ? sizeof(data) : left;
278                 memcpy(p, data, cp);
279                 off += cp;
280                 p += cp;
281                 left -= cp;
282         }
283 }