Whamcloud - gitweb
land b_eq on HEAD
[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 (512)
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\n", _npages);
149
150         memset(_buffer, 0, sizeof(_buffer));
151
152         /* read */
153         lseek(fd, pos, SEEK_SET);
154         for (i = 0; i < _npages; i += xfer) {
155                 rc = read(fd, _buffer[i], PAGE_SIZE * xfer);
156                 if (rc != PAGE_SIZE * xfer) {
157                         printf("read error %d (i = %d)\n", rc, i);
158                         exit(1);
159                 }
160         }
161         printf("succefully read %d pages\n", _npages);
162
163         /* compute checksum */
164         for (i = 0; i < _npages; i++) {
165                 int sum = 0;
166                 for (j = 0; j < PAGE_SIZE/sizeof(int); j++) {
167                         sum += _buffer[i][j];
168                 }
169                 if (sum != check_sum[i]) {
170                         printf("chunk %d checksum error: expected 0x%x, get 0x%x\n",
171                                 i, check_sum[i], sum);
172                 }
173         }
174         printf("checksum verified OK!\n");
175
176         t_close(fd);
177         t_unlink(path);
178 }
179
180 void t5()
181 {
182         char text[256];
183         loff_t off_array[] = {1, 4, 17, 255, 258, 4095, 4097, 8191, 1024*1024*1024};
184         int np = 1, i;
185         loff_t offset = 0;
186
187         while (np <= _npages) {
188                 sprintf(text, "pages_io: %d per transfer, offset %lld",
189                         np, offset);
190                 ENTRY(text);
191                 pages_io(np, offset);
192                 LEAVE();
193                 np += np;
194         }
195
196         for (i = 0; i < sizeof(off_array)/sizeof(loff_t); i++) {
197                 offset = off_array[i];
198                 sprintf(text, "pages_io: 16 per transfer, offset %lld",
199                         offset);
200                 ENTRY(text);
201                 pages_io(16, offset);
202                 LEAVE();
203         }
204 }
205
206 void t6()
207 {
208         char *path="/mnt/lustre/test_t6";
209         char *path2="/mnt/lustre/test_t6_link";
210         ENTRY("symlink");
211
212         t_touch(path);
213         t_symlink(path, path2);
214         t_check_stat(path2, NULL);
215         t_unlink(path2);
216         t_unlink(path);
217         LEAVE();
218 }
219
220 void t7()
221 {
222         char *path="/mnt/lustre/test_t7";
223         ENTRY("mknod");
224
225         t_mknod(path, S_IFCHR | 0644, 5, 4);
226         t_check_stat(path, NULL);
227         t_unlink(path);
228         LEAVE();
229 }
230
231 void t8()
232 {
233         char *path="/mnt/lustre/test_t8";
234         ENTRY("chmod");
235
236         t_touch(path);
237         t_chmod_raw(path, 0700);
238         t_check_stat(path, NULL);
239         t_unlink(path);
240         LEAVE();
241 }
242
243 void t9()
244 {
245         char *path="/mnt/lustre/test_t9";
246         char *path2="/mnt/lustre/test_t9_link";
247         ENTRY("hard link");
248
249         t_touch(path);
250         t_link(path, path2);
251         t_check_stat(path, NULL);
252         t_check_stat(path2, NULL);
253         t_unlink(path);
254         t_unlink(path2);
255         LEAVE();
256 }
257
258 void t10()
259 {
260         char *dir1="/mnt/lustre/test_t10_dir1";
261         char *dir2="/mnt/lustre/test_t10_dir2";
262         char *path1="/mnt/lustre/test_t10_reg1";
263         char *path2="/mnt/lustre/test_t10_reg2";
264         char *rename1="/mnt/lustre/test_t10_dir1/rename1";
265         char *rename2="/mnt/lustre/test_t10_dir2/rename2";
266         char *rename3="/mnt/lustre/test_t10_dir2/rename3";
267         ENTRY("rename");
268
269         t_mkdir(dir1);
270         t_mkdir(dir2);
271         t_touch(path1);
272         t_touch(path2);
273         t_rename(path1, rename1);
274         t_rename(path2, rename2);
275         t_rename(rename1, rename2);
276         t_rename(dir1, rename3);
277         t_unlink(rename2);
278         t_rmdir(rename3);
279         t_rmdir(dir2);
280         LEAVE();
281 }
282
283 void t11()
284 {
285         char *base="/mnt/lustre";
286         char path[4096], path2[4096];
287         int i, j, level = 5, nreg = 5;
288         ENTRY("deep tree");
289
290         strcpy(path, base);
291
292         for (i = 0; i < level; i++) {
293                 for (j = 0; j < nreg; j++) {
294                         sprintf(path2, "%s/file%d", path, j);
295                         t_touch(path2);
296                 }
297
298                 strcat(path, "/dir");
299                 t_mkdir(path);
300         }
301
302         for (i = level; i > 0; i--) {
303                 strcpy(path, base);
304                 for (j = 1; j < i; j++)
305                         strcat(path, "/dir");
306                 
307                 for (j = 0; j < nreg; j++) {
308                         sprintf(path2, "%s/file%d", path, j);
309                         t_unlink(path2);
310                 }
311
312                 strcat(path, "/dir");
313                 t_rmdir(path);
314         }
315
316         LEAVE();
317 }
318
319 void t12()
320 {
321         char *dir="/mnt/lustre/test_t12_dir";
322         char buf[1024*128];
323         int fd;
324         ENTRY("empty directory readdir");
325
326         t_mkdir(dir);
327         fd = t_open(dir);
328         t_ls(fd, buf, sizeof(buf));
329         t_close(fd);
330         t_rmdir(dir);
331         LEAVE();
332 }
333
334 void t13()
335 {
336         char *dir="/mnt/lustre/test_t13_dir/";
337         char name[1024];
338         char buf[1024];
339         const int nfiles = 20;
340         char *prefix = "test13_filename_prefix_";
341         int fd, i;
342         ENTRY("multiple entries directory readdir");
343
344         t_mkdir(dir);
345         printf("Creating %d files...\n", nfiles);
346         for (i = 0; i < nfiles; i++) {
347                 sprintf(name, "%s%s%05d", dir, prefix, i);
348                 t_touch(name);
349         }
350         fd = t_open(dir);
351         t_ls(fd, buf, sizeof(buf));
352         t_close(fd);
353         printf("Cleanup...\n");
354         for (i = 0; i < nfiles; i++) {
355                 sprintf(name, "%s%s%05d", dir, prefix, i);
356                 t_unlink(name);
357         }
358         t_rmdir(dir);
359         LEAVE();
360 }
361
362 void t14()
363 {
364         char *dir="/mnt/lustre/test_t14_dir/";
365         char name[1024];
366         char buf[1024];
367         const int nfiles = 256;
368         char *prefix = "test14_filename_long_prefix_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA___";
369         int fd, i;
370         ENTRY(">1 block(4k) directory readdir");
371
372         t_mkdir(dir);
373         printf("Creating %d files...\n", nfiles);
374         for (i = 0; i < nfiles; i++) {
375                 sprintf(name, "%s%s%05d", dir, prefix, i);
376                 t_touch(name);
377         }
378         fd = t_open(dir);
379         t_ls(fd, buf, sizeof(buf));
380         t_close(fd);
381         printf("Cleanup...\n");
382         for (i = 0; i < nfiles; i++) {
383                 sprintf(name, "%s%s%05d", dir, prefix, i);
384                 t_unlink(name);
385         }
386         t_rmdir(dir);
387         LEAVE();
388 }
389
390 void t15()
391 {
392         char *file = "/mnt/lustre/test_t15_file";
393         int fd;
394         ENTRY("open-stat-close");
395
396         t_touch(file);
397         fd = t_open(file);
398         t_check_stat(file, NULL);
399         t_close(fd);
400         t_unlink(file);
401         LEAVE();
402 }
403
404 extern void __liblustre_setup_(void);
405 extern void __liblustre_cleanup_(void);
406
407 void usage(char *cmd)
408 {
409         printf("Usage: \t%s --target mdsnid:/mdsname/profile\n", cmd);
410         printf("       \t%s --dumpfile dumpfile\n", cmd);
411         exit(-1);
412 }
413
414 int main(int argc, char * const argv[])
415 {
416         int opt_index, c;
417         static struct option long_opts[] = {
418                 {"target", 1, 0, 0},
419                 {"dumpfile", 1, 0, 0},
420                 {0, 0, 0, 0}
421         };
422
423         if (argc <= 1)
424                 usage(argv[0]);
425
426         while ((c = getopt_long(argc, argv, "", long_opts, &opt_index)) != -1) {
427                 switch (c) {
428                 case 0: {
429                         if (!optarg[0])
430                                 usage(argv[0]);
431
432                         if (!strcmp(long_opts[opt_index].name, "target")) {
433                                 setenv(ENV_LUSTRE_MNTTGT, optarg, 1);
434                         } else if (!strcmp(long_opts[opt_index].name, "dumpfile")) {
435                                 setenv(ENV_LUSTRE_DUMPFILE, optarg, 1);
436                         } else
437                                 usage(argv[0]);
438                         break;
439                 }
440                 default:
441                         usage(argv[0]);
442                 }
443         }
444
445         if (optind != argc)
446                 usage(argv[0]);
447
448         __liblustre_setup_();
449
450 #ifndef __CYGWIN__
451         t1();
452         t2();
453         t3();
454         t4();
455         t5();
456         t6();
457         t7();
458         t8();
459         t9();
460         t10();
461         t11();
462         t12();
463         t13();
464         t14();
465         t15();
466 #endif
467
468         printf("liblustre is about shutdown\n");
469         __liblustre_cleanup_();
470
471         printf("complete successfully\n");
472         return 0;
473 }