Whamcloud - gitweb
LU-2093 lod: fall back to RR allocation when QoS fails
[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 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  *
34  * lustre/tests/lp_utils.c
35  *
36  * Author: You Feng <youfeng@clusterfs.com>
37  */
38
39 #include <mpi.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <time.h>
43 #include <sys/time.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <unistd.h>
47 #include <sys/ioctl.h>
48 #include <fcntl.h>
49 #include <errno.h>
50 #include <liblustre.h>
51 #include "lustre/lustre_user.h"
52 #include "lustre/tests/lp_utils.h"
53
54 #define MAX_PROCESSES 8
55
56 int verbose = 0;
57 int debug = 0;
58
59 char hostname[1024];
60
61 struct timeval t1, t2;
62
63 char *timestamp() {
64         static char datestring[80];
65         time_t timestamp;
66
67         fflush(stdout);
68         timestamp = time(NULL);
69         strftime(datestring, 80, "%T", localtime(&timestamp));
70
71         return datestring;
72 }
73
74 inline void begin(char *str) {
75         if (verbose > 0 && rank == 0) {
76                 gettimeofday(&t1, NULL);
77                 printf("%s:\tBeginning %s\n", timestamp(), str);
78                 fflush(stdout);
79         }
80 }
81
82 inline void end(char *str) {
83         float elapsed;
84
85         MPI_Barrier(MPI_COMM_WORLD);
86         if (verbose > 0 && rank == 0) {
87                 gettimeofday(&t2, NULL);
88                 elapsed = (t2.tv_sec + ((float)t2.tv_usec/1000000))
89                           - (t1.tv_sec + ((float)t1.tv_usec/1000000));
90                 if (elapsed >= 60) {
91                         printf("%s:\tFinished %-15s(%.2f min)\n",
92                                timestamp(), str, elapsed / 60);
93                 } else {
94                         printf("%s:\tFinished %-15s(%.3f sec)\n",
95                                timestamp(), str, elapsed);
96
97                 }
98                 fflush(stdout);
99         }
100 }
101
102 void dump_diff(char *orig_buf, char *buf, int size, long _off)
103 {
104         int i, diff, off;
105         char *p, *end;
106
107         printf("commpared buf size %d, at offset %lu\n\n", size, _off);
108
109         if (orig_buf) {
110                 printf("original buf:\n");
111                 p = orig_buf;
112                 end = orig_buf + size;
113                 i = 1;
114                 while (p < end) {
115                         printf(" %8lx", *(long *)p);
116                         p += sizeof(long);
117                         if (i++%8 == 0)
118                                 printf("\n");
119                 }
120                 if (i%8) printf("\n\n");
121                 else 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))
220                                     == -1) {
221                                         close(fd);
222                                         sprintf(errmsg, "write of file %s", 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 }