Whamcloud - gitweb
smash the HEAD with the contents of b_cmd. HEAD_PRE_CMD_SMASH and
[fs/lustre-release.git] / lustre / liblustre / tests / sanity.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Lustre Light user test program
5  *
6  *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
7  *
8  *   This file is part of Lustre, http://www.lustre.org.
9  *
10  *   Lustre is free software; you can redistribute it and/or
11  *   modify it under the terms of version 2 of the GNU General Public
12  *   License as published by the Free Software Foundation.
13  *
14  *   Lustre is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *   GNU General Public License for more details.
18  *
19  *   You should have received a copy of the GNU General Public License
20  *   along with Lustre; if not, write to the Free Software
21  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #define _BSD_SOURCE
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <getopt.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <sys/queue.h>
35 #include <signal.h>
36
37 #include <sysio.h>
38 #include <mount.h>
39
40 #include "test_common.h"
41
42 #define ENTRY(str)                                                      \
43         do {                                                            \
44                 char buf[100];                                          \
45                 int len;                                                \
46                 sprintf(buf, "===== START: %s ", (str));                \
47                 len = strlen(buf);                                      \
48                 if (len < 79) {                                         \
49                         memset(buf+len, '=', 100-len);                  \
50                         buf[79] = '\n';                                 \
51                         buf[80] = 0;                                    \
52                 }                                                       \
53                 printf("%s", buf);                                      \
54         } while (0)
55
56 #define LEAVE()                                                         \
57         do {                                                            \
58                 printf("----- END TEST successfully ---");              \
59                 printf("-----------------------------");                \
60                 printf("-------------------\n");                        \
61         } while (0)
62
63 void t1()
64 {
65         char *path="/mnt/lustre/test_t1";
66         ENTRY("create/delete");
67
68         t_touch(path);
69         t_unlink(path);
70         LEAVE();
71 }
72
73 void t2()
74 {
75         char *path="/mnt/lustre/test_t2";
76         ENTRY("mkdir/rmdir");
77
78         t_mkdir(path);
79         t_rmdir(path);
80         LEAVE();
81 }
82
83 void t3()
84 {
85         char *path="/mnt/lustre/test_t3";
86         ENTRY("regular stat");
87
88         t_touch(path);
89         t_check_stat(path, NULL);
90         t_unlink(path);
91         LEAVE();
92 }
93
94 void t4()
95 {
96         char *path="/mnt/lustre/test_t4";
97         ENTRY("dir stat");
98
99         t_mkdir(path);
100         t_check_stat(path, NULL);
101         t_rmdir(path);
102         LEAVE();
103 }
104
105 #define PAGE_SIZE (4096)
106 #define _npages (2048)
107
108 static int _buffer[_npages][PAGE_SIZE/sizeof(int)];
109
110 /* pos:   i/o start from
111  * xfer:  npages per transfer
112  */
113 static void pages_io(int xfer, loff_t pos)
114 {
115         char *path="/mnt/lustre/test_t5";
116         int check_sum[_npages] = {0,};
117         int fd, rc, i, j;
118
119         memset(_buffer, 0, sizeof(_buffer));
120
121         /* create sample data */
122         for (i = 0; i < _npages; i++) {
123                 for (j = 0; j < PAGE_SIZE/sizeof(int); j++) {
124                         _buffer[i][j] = rand();
125                 }
126         }
127
128         /* compute checksum */
129         for (i = 0; i < _npages; i++) {
130                 for (j = 0; j < PAGE_SIZE/sizeof(int); j++) {
131                         check_sum[i] += _buffer[i][j];
132                 }
133         }
134
135         t_touch(path);
136
137         fd = t_open(path);
138
139         /* write */
140         lseek(fd, pos, SEEK_SET);
141         for (i = 0; i < _npages; i += xfer) {
142                 rc = write(fd, _buffer[i], PAGE_SIZE * xfer);
143                 if (rc != PAGE_SIZE * xfer) {
144                         printf("write error %d (i = %d)\n", rc, i);
145                         exit(1);
146                 }
147         }
148         printf("succefully write %d pages(%d per xfer)\n", _npages, xfer);
149         memset(_buffer, 0, sizeof(_buffer));
150
151         /* read */
152         lseek(fd, pos, SEEK_SET);
153         for (i = 0; i < _npages; i += xfer) {
154                 rc = read(fd, _buffer[i], PAGE_SIZE * xfer);
155                 if (rc != PAGE_SIZE * xfer) {
156                         printf("read error %d (i = %d)\n", rc, i);
157                         exit(1);
158                 }
159         }
160         printf("succefully read %d pages(%d per xfer)\n", _npages, xfer);
161
162         /* compute checksum */
163         for (i = 0; i < _npages; i++) {
164                 int sum = 0;
165                 for (j = 0; j < PAGE_SIZE/sizeof(int); j++) {
166                         sum += _buffer[i][j];
167                 }
168                 if (sum != check_sum[i]) {
169                         printf("chunk %d checksum error: expected 0x%x, get 0x%x\n",
170                                 i, check_sum[i], sum);
171                 }
172         }
173         printf("checksum verified OK!\n");
174
175         t_close(fd);
176         t_unlink(path);
177 }
178
179 void t5()
180 {
181         char text[256];
182         loff_t off_array[] = {1, 4, 17, 255, 258, 4095, 4097, 8191, 1024*1024*1024};
183         int np = 1, i;
184         loff_t offset = 0;
185
186         while (np <= _npages) {
187                 sprintf(text, "pages_io: %d per transfer, offset %lld",
188                         np, offset);
189                 ENTRY(text);
190                 pages_io(np, offset);
191                 LEAVE();
192                 np += np;
193         }
194
195         for (i = 0; i < sizeof(off_array)/sizeof(loff_t); i++) {
196                 offset = off_array[i];
197                 sprintf(text, "pages_io: 16 per transfer, offset %lld",
198                         offset);
199                 ENTRY(text);
200                 pages_io(16, offset);
201                 LEAVE();
202         }
203 }
204
205 void t6()
206 {
207         char *path="/mnt/lustre/test_t6";
208         char *path2="/mnt/lustre/test_t6_link";
209         ENTRY("symlink");
210
211         t_touch(path);
212         t_symlink(path, path2);
213         t_check_stat(path2, NULL);
214         t_unlink(path2);
215         t_unlink(path);
216         LEAVE();
217 }
218
219 void t7()
220 {
221         char *path="/mnt/lustre/test_t7";
222         ENTRY("mknod");
223
224         t_mknod(path, S_IFCHR | 0644, 5, 4);
225         t_check_stat(path, NULL);
226         t_unlink(path);
227         LEAVE();
228 }
229
230 void t8()
231 {
232         char *path="/mnt/lustre/test_t8";
233         ENTRY("chmod");
234
235         t_touch(path);
236         t_chmod_raw(path, 0700);
237         t_check_stat(path, NULL);
238         t_unlink(path);
239         LEAVE();
240 }
241
242 void t9()
243 {
244         char *path="/mnt/lustre/test_t9";
245         char *path2="/mnt/lustre/test_t9_link";
246         ENTRY("hard link");
247
248         t_touch(path);
249         t_link(path, path2);
250         t_check_stat(path, NULL);
251         t_check_stat(path2, NULL);
252         t_unlink(path);
253         t_unlink(path2);
254         LEAVE();
255 }
256
257 void t10()
258 {
259         char *dir1="/mnt/lustre/test_t10_dir1";
260         char *dir2="/mnt/lustre/test_t10_dir2";
261         char *path1="/mnt/lustre/test_t10_reg1";
262         char *path2="/mnt/lustre/test_t10_reg2";
263         char *rename1="/mnt/lustre/test_t10_dir1/rename1";
264         char *rename2="/mnt/lustre/test_t10_dir2/rename2";
265         char *rename3="/mnt/lustre/test_t10_dir2/rename3";
266         ENTRY("rename");
267
268         t_mkdir(dir1);
269         t_mkdir(dir2);
270         t_touch(path1);
271         t_touch(path2);
272         t_rename(path1, rename1);
273         t_rename(path2, rename2);
274         t_rename(rename1, rename2);
275         t_rename(dir1, rename3);
276         t_unlink(rename2);
277         t_rmdir(rename3);
278         t_rmdir(dir2);
279         LEAVE();
280 }
281
282 void t11()
283 {
284         char *base="/mnt/lustre";
285         char path[4096], path2[4096];
286         int i, j, level = 5, nreg = 5;
287         ENTRY("deep tree");
288
289         strcpy(path, base);
290
291         for (i = 0; i < level; i++) {
292                 for (j = 0; j < nreg; j++) {
293                         sprintf(path2, "%s/file%d", path, j);
294                         t_touch(path2);
295                 }
296
297                 strcat(path, "/dir");
298                 t_mkdir(path);
299         }
300
301         for (i = level; i > 0; i--) {
302                 strcpy(path, base);
303                 for (j = 1; j < i; j++)
304                         strcat(path, "/dir");
305                 
306                 for (j = 0; j < nreg; j++) {
307                         sprintf(path2, "%s/file%d", path, j);
308                         t_unlink(path2);
309                 }
310
311                 strcat(path, "/dir");
312                 t_rmdir(path);
313         }
314
315         LEAVE();
316 }
317
318 void t12()
319 {
320         char *dir="/mnt/lustre/test_t12_dir";
321         char buf[1024*128];
322         int fd;
323         ENTRY("empty directory readdir");
324
325         t_mkdir(dir);
326         fd = t_opendir(dir);
327         t_ls(fd, buf, sizeof(buf));
328         t_close(fd);
329         t_rmdir(dir);
330         LEAVE();
331 }
332
333 void t13()
334 {
335         char *dir="/mnt/lustre/test_t13_dir/";
336         char name[1024];
337         char buf[1024];
338         const int nfiles = 20;
339         char *prefix = "test13_filename_prefix_";
340         int fd, i;
341         ENTRY("multiple entries directory readdir");
342
343         t_mkdir(dir);
344         printf("Creating %d files...\n", nfiles);
345         for (i = 0; i < nfiles; i++) {
346                 sprintf(name, "%s%s%05d", dir, prefix, i);
347                 t_touch(name);
348         }
349         fd = t_opendir(dir);
350         t_ls(fd, buf, sizeof(buf));
351         t_close(fd);
352         printf("Cleanup...\n");
353         for (i = 0; i < nfiles; i++) {
354                 sprintf(name, "%s%s%05d", dir, prefix, i);
355                 t_unlink(name);
356         }
357         t_rmdir(dir);
358         LEAVE();
359 }
360
361 void t14()
362 {
363         char *dir="/mnt/lustre/test_t14_dir/";
364         char name[1024];
365         char buf[1024];
366         const int nfiles = 256;
367         char *prefix = "test14_filename_long_prefix_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA___";
368         int fd, i;
369         ENTRY(">1 block(4k) directory readdir");
370
371         t_mkdir(dir);
372         printf("Creating %d files...\n", nfiles);
373         for (i = 0; i < nfiles; i++) {
374                 sprintf(name, "%s%s%05d", dir, prefix, i);
375                 t_touch(name);
376         }
377         fd = t_opendir(dir);
378         t_ls(fd, buf, sizeof(buf));
379         t_close(fd);
380         printf("Cleanup...\n");
381         for (i = 0; i < nfiles; i++) {
382                 sprintf(name, "%s%s%05d", dir, prefix, i);
383                 t_unlink(name);
384         }
385         t_rmdir(dir);
386         LEAVE();
387 }
388
389 void t15()
390 {
391         char *file = "/mnt/lustre/test_t15_file";
392         int fd;
393         ENTRY("open-stat-close");
394
395         t_touch(file);
396         fd = t_open(file);
397         t_check_stat(file, NULL);
398         t_close(fd);
399         t_unlink(file);
400         LEAVE();
401 }
402
403 extern void __liblustre_setup_(void);
404 extern void __liblustre_cleanup_(void);
405
406 void usage(char *cmd)
407 {
408         printf("Usage: \t%s --target mdsnid:/mdsname/profile\n", cmd);
409         printf("       \t%s --dumpfile dumpfile\n", cmd);
410         exit(-1);
411 }
412
413 int main(int argc, char * const argv[])
414 {
415         int opt_index, c;
416         static struct option long_opts[] = {
417                 {"target", 1, 0, 0},
418                 {"dumpfile", 1, 0, 0},
419                 {0, 0, 0, 0}
420         };
421
422         if (argc <= 1)
423                 usage(argv[0]);
424
425         while ((c = getopt_long(argc, argv, "", long_opts, &opt_index)) != -1) {
426                 switch (c) {
427                 case 0: {
428                         if (!optarg[0])
429                                 usage(argv[0]);
430
431                         if (!strcmp(long_opts[opt_index].name, "target")) {
432                                 setenv(ENV_LUSTRE_MNTTGT, optarg, 1);
433                         } else if (!strcmp(long_opts[opt_index].name, "dumpfile")) {
434                                 setenv(ENV_LUSTRE_DUMPFILE, optarg, 1);
435                         } else
436                                 usage(argv[0]);
437                         break;
438                 }
439                 default:
440                         usage(argv[0]);
441                 }
442         }
443
444         if (optind != argc)
445                 usage(argv[0]);
446
447         __liblustre_setup_();
448
449 #ifndef __CYGWIN__
450         t1();
451         t2();
452         t3();
453         t4();
454         t5();
455         t6();
456         t7();
457         t8();
458         t9();
459         t10();
460         t11();
461         t12();
462         t13();
463         t14();
464         t15();
465 #endif
466
467         printf("liblustre is about shutdown\n");
468         __liblustre_cleanup_();
469
470         printf("complete successfully\n");
471         return 0;
472 }