Whamcloud - gitweb
LU-10657 utils: fd leak in mirror_split()
[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.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 "lustre/lustre_user.h"
49 #include "lustre/tests/lp_utils.h"
50
51 #define MAX_PROCESSES 8
52
53 int verbose = 0;
54 int debug = 0;
55
56 char hostname[1024];
57
58 struct timeval t1, t2;
59
60 char *timestamp() {
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         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         float elapsed;
81
82         MPI_Barrier(MPI_COMM_WORLD);
83         if (verbose > 0 && rank == 0) {
84                 gettimeofday(&t2, NULL);
85                 elapsed = (t2.tv_sec + ((float)t2.tv_usec/1000000))
86                           - (t1.tv_sec + ((float)t1.tv_usec/1000000));
87                 if (elapsed >= 60) {
88                         printf("%s:\tFinished %-15s(%.2f min)\n",
89                                timestamp(), str, elapsed / 60);
90                 } else {
91                         printf("%s:\tFinished %-15s(%.3f sec)\n",
92                                timestamp(), str, elapsed);
93
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) printf("\n\n");
118                 else printf("\n");
119         }
120
121         if (buf) {
122                 printf("different data: diff_data(orig_data)\n");
123                 diff = 0;
124                 off = 0;
125                 i = 1;
126                 p = buf;
127                 end = buf + size;
128                 while (p < end) {
129                         if (memcmp(p, orig_buf + off, sizeof(long)) != 0) {
130                                 printf("\toff: %5d,\tdata: %8lx (%8lx)\n", off,
131                                        *(unsigned long *)p,
132                                        *(unsigned long *)(orig_buf + off));
133                                 diff++;
134                         }
135                         off += sizeof(long);
136                         p += sizeof(long);
137                 }
138                 printf("\n %d total differents found\n\n", diff);
139         }
140 }
141
142 void lp_gethostname(void)
143 {
144         if (gethostname(hostname, 1024) == -1) {
145                 fprintf(stderr, "gethostname: (%d)%s", errno, strerror(errno));
146                 MPI_Abort(MPI_COMM_WORLD, 2);
147         }
148 }
149
150 /* This function does not FAIL if the requested "name" does not exit.
151  * This is just to clean up any files or directories left over from
152  * previous runs
153  */
154 void remove_file_or_dir(char *name)
155 {
156         struct stat statbuf;
157         char errmsg[MAX_FILENAME_LEN + 20];
158
159         if (stat(name, &statbuf) != -1) {
160                 if (S_ISREG(statbuf.st_mode)) {
161                         printf("stale file found\n");
162                         if (unlink(name) == -1) {
163                                 sprintf(errmsg, "unlink of %s", name);
164                                 FAIL(errmsg);
165                         }
166                 }
167                 if (S_ISDIR(statbuf.st_mode)) {
168                         printf("stale directory found\n");
169                         if (rmdir(name) == -1) {
170                                 sprintf(errmsg, "rmdir of %s", name);
171                                 FAIL(errmsg);
172                         }
173                 }
174         }
175 }
176
177 void create_file(char *name, long filesize, int fill)
178 {
179         static char filename[MAX_FILENAME_LEN];
180         char errmsg[MAX_FILENAME_LEN + 20];
181         char buf[1024 * 8];
182         char c = 'A' + size;
183         int fd, rc;
184         short zero = 0;
185         long left = filesize;
186
187         /* Process 0 creates the test file(s) */
188         if (rank == 0) {
189                 sprintf(filename, "%s/%s", testdir, name);
190                 remove_file_or_dir(filename);
191                 if ((fd = creat(filename, FILEMODE)) == -1) {
192                         sprintf(errmsg, "create of file %s", filename);
193                         FAIL(errmsg);
194                 }
195                 if (filesize > 0) {
196                         if (lseek(fd, filesize - 1, SEEK_SET) == -1) {
197                                 close(fd);
198                                 sprintf(errmsg, "lseek of file %s", filename);
199                                 FAIL(errmsg);
200                         }
201                         if (write(fd, &zero, 1) == -1) {
202                                 close(fd);
203                                 sprintf(errmsg, "write of file %s", filename);
204                                 FAIL(errmsg);
205                         }
206                 }
207                 if (filesize > 0 && fill) {
208                         if (lseek(fd, 0, SEEK_SET) == -1) {
209                                 close(fd);
210                                 sprintf(errmsg, "lseek of file %s", filename);
211                                 FAIL(errmsg);
212                         }
213                         memset(buf, c, 1024);
214                         while (left > 0) {
215                                 if ((rc = write(fd, buf,
216                                                 left > (1024 * 8) ? (1024 * 8) : left))
217                                     == -1) {
218                                         close(fd);
219                                         sprintf(errmsg, "write of file %s", filename);
220                                         FAIL(errmsg);
221                                 }
222                                 left -= rc;
223                         }
224                 }
225                 if (close(fd) == -1) {
226                         sprintf(errmsg, "close of file %s", filename);
227                         FAIL(errmsg);
228                 }
229         }
230 }
231
232 void check_stat(char *filename, struct stat *state, struct stat *old_state)
233 {
234         char errmsg[MAX_FILENAME_LEN+20];
235
236         if (stat(filename, state) == -1) {
237                 sprintf(errmsg, "stat of file %s", filename);
238                 FAIL(errmsg);
239         }
240
241         if (memcmp(state, old_state, sizeof(struct stat)) != 0) {
242                 errno = 0;
243                 sprintf(errmsg, LP_STAT_FMT, LP_STAT_ARGS);
244                 FAIL(errmsg);
245         }
246 }
247
248 void remove_file(char *name)
249 {
250         char filename[MAX_FILENAME_LEN];
251         char errmsg[MAX_FILENAME_LEN + 20];
252
253         /* Process 0 remove the file(s) */
254         if (rank == 0) {
255                 sprintf(filename, "%s/%s", testdir, name);
256                 if (unlink(filename) == -1) {
257                         sprintf(errmsg, "unlink of file %s", filename);
258                         FAIL(errmsg);
259                 }
260         }
261 }
262
263 void fill_stride(char *buf, int buf_size, long long rank, long long _off)
264 {
265         char *p = buf;
266         long long off, data[2];
267         int cp, left = buf_size;
268
269         data[0] = rank;
270         off = _off;
271         while (left > 0) {
272                 data[1] = off;
273                 cp = left > sizeof(data) ? sizeof(data) : left;
274                 memcpy(p, data, cp);
275                 off += cp;
276                 p += cp;
277                 left -= cp;
278         }
279 }