Whamcloud - gitweb
land v0.9.1 on HEAD, in preparation for a 1.0.x branch
[fs/lustre-release.git] / lustre / liblustre / lltest.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, 17, 255, 257, 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 t100()
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 extern void __liblustre_setup_(void);
320 extern void __liblustre_cleanup_(void);
321
322 void usage(char *cmd)
323 {
324         printf("Usage: \t%s --target mdsnid:/mdsname/profile\n", cmd);
325         printf("       \t%s --dumpfile dumpfile\n", cmd);
326         exit(-1);
327 }
328
329 int main(int argc, char * const argv[])
330 {
331         int opt_index, c;
332         static struct option long_opts[] = {
333                 {"target", 1, 0, 0},
334                 {"dumpfile", 1, 0, 0},
335                 {0, 0, 0, 0}
336         };
337
338         if (argc <= 1)
339                 usage(argv[0]);
340
341         while ((c = getopt_long(argc, argv, "", long_opts, &opt_index)) != -1) {
342                 switch (c) {
343                 case 0: {
344                         printf("optindex %d\n", opt_index);
345                         if (!optarg[0])
346                                 usage(argv[0]);
347
348                         if (!strcmp(long_opts[opt_index].name, "target")) {
349                                 setenv(ENV_LUSTRE_MNTTGT, optarg, 1);
350                         } else if (!strcmp(long_opts[opt_index].name, "dumpfile")) {
351                                 setenv(ENV_LUSTRE_DUMPFILE, optarg, 1);
352                         } else
353                                 usage(argv[0]);
354                         break;
355                 }
356                 default:
357                         usage(argv[0]);
358                 }
359         }
360
361         if (optind != argc)
362                 usage(argv[0]);
363
364         __liblustre_setup_();
365
366 #ifndef __CYGWIN__
367         t1();
368         t2();
369         t3();
370         t4();
371         t5();
372         t6();
373         t7();
374         t8();
375         t9();
376         t10();
377
378         t100();
379 #endif
380
381         printf("liblustre is about shutdown\n");
382         __liblustre_cleanup_();
383
384         printf("complete successfully\n");
385         return 0;
386 }