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