Whamcloud - gitweb
landing b_cmobd_merge on HEAD
[fs/lustre-release.git] / lustre / liblustre / tests / recovery_small.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 <getopt.h>
36
37 #include <sysio.h>
38 #include <mount.h>
39
40 #include "test_common.h"
41
42 #define MAX_STRING_SIZE 2048
43
44 static struct {
45         const char   *name;
46         unsigned long code;
47 } drop_arr [] =
48 {
49         {"MDS_REQUEST", 0x123},
50         {"MDS_REPLY", 0x122},
51         {NULL, 0}
52 };
53
54 static int drop_index = 0;
55
56 static char mds_server[1024] = {0, };
57 static char ssh_cmd[MAX_STRING_SIZE] = {0,};
58
59 int do_stat(const char *name, struct stat *buf)
60 {
61         struct stat stat;
62         int rc;
63
64         rc = lstat(name, &stat);
65         if (rc) {
66                 printf("error %d stat %s\n", rc, name);
67                 exit(1);
68         }
69         if (buf)
70                 memcpy(buf, &stat, sizeof(*buf));
71
72         return 0;
73 }
74
75 void prepare_reg(const char *path)
76 {
77         int fd, rc;
78
79         fd = open(path, O_RDWR|O_CREAT, 00644);
80         if (fd < 0) {
81                 printf("error %d create %s\n", fd, path);
82                 exit(1);
83         }
84
85         rc = close(fd);
86         if (rc) {
87                 printf("error %d close %s\n", rc, path);
88                 exit(1);
89         }
90 }
91
92 void cleanup_reg(const char *path)
93 {
94         int rc;
95
96         rc = unlink(path);
97         if (rc) {
98                 printf("error %d unlink %s\n", rc, path);
99                 exit(1);
100         }
101 }
102
103 void prepare_dir(const char *path)
104 {
105         int rc;
106
107         rc = mkdir(path, 00644);
108         if (rc < 0) {
109                 printf("error %d mkdir %s\n", rc, path);
110                 exit(1);
111         }
112 }
113
114 void cleanup_dir(const char *path)
115 {
116         int rc;
117
118         rc = rmdir(path);
119         if (rc) {
120                 printf("error %d unlink %s\n", rc, path);
121                 exit(1);
122         }
123 }
124
125 #define FAIL()                                                             \
126     do {                                                                   \
127         char cmd[MAX_STRING_SIZE];                                         \
128         int rc;                                                            \
129                                                                            \
130         if (drop_arr[drop_index].name) {                                   \
131             printf("server drops next %s\n", drop_arr[drop_index].name);   \
132             sprintf(cmd,                                                   \
133                     "%s %s \"echo %lu > /proc/sys/lustre/fail_loc\"",      \
134                     ssh_cmd, mds_server, drop_arr[drop_index].code);       \
135             if (system(cmd)) {                                             \
136                 printf("error excuting remote command: %d\n", rc);         \
137                 exit(rc);                                                  \
138             }                                                              \
139         }                                                                  \
140     } while (0)
141
142 #define RECOVER()                                                          \
143     do {                                                                   \
144         char cmd[1024];                                                    \
145                                                                            \
146         if (drop_arr[drop_index].name) {                                   \
147             sprintf(cmd, "%s %s \"echo 0 > /proc/sys/lustre/fail_loc\"",   \
148                     ssh_cmd, mds_server);                                  \
149             system(cmd);                                                   \
150         }                                                                  \
151     } while (0)
152
153 #define ENTRY(str)                                                      \
154         do {                                                            \
155                 char buf[100];                                          \
156                 int len;                                                \
157                 sprintf(buf, "===== START: %s ", (str));                \
158                 len = strlen(buf);                                      \
159                 if (len < 79) {                                         \
160                         memset(buf+len, '=', 100-len);                  \
161                         buf[79] = '\n';                                 \
162                         buf[80] = 0;                                    \
163                 }                                                       \
164                 printf("%s", buf);                                      \
165         } while (0)
166
167 #define LEAVE()                                                         \
168         do {                                                            \
169                 printf("----- END TEST successfully ---");              \
170                 printf("-----------------------------");                \
171                 printf("-------------------\n");                        \
172         } while (0)
173
174
175 void t1()
176 {
177         char *path="/mnt/lustre/test_t1";
178         ENTRY("create/delete");
179
180         FAIL();
181         t_touch(path);
182         RECOVER();
183         FAIL();
184         t_unlink(path);
185         RECOVER();
186         LEAVE();
187 }
188
189 void t2()
190 {
191         char *path="/mnt/lustre/test_t2";
192         ENTRY("mkdir/rmdir");
193
194         FAIL();
195         t_mkdir(path);
196         RECOVER();
197         FAIL();
198         t_rmdir(path);
199         RECOVER();
200         LEAVE();
201 }
202
203 void t3()
204 {
205         char *path="/mnt/lustre/test_t3";
206         ENTRY("regular stat");
207
208         t_touch(path);
209         FAIL();
210         t_check_stat(path, NULL);
211         RECOVER();
212         t_unlink(path);
213         LEAVE();
214 }
215
216 void t4()
217 {
218         char *path="/mnt/lustre/test_t4";
219         ENTRY("dir stat");
220
221         t_mkdir(path);
222         FAIL();
223         t_check_stat(path, NULL);
224         RECOVER();
225         t_rmdir(path);
226         LEAVE();
227 }
228
229 void t5()
230 {
231         char *path="/mnt/lustre/test_t5";
232         const int bufsize = 4096;
233         char wbuf[bufsize], rbuf[bufsize];
234         int npages = 100;
235         int fd, rc, i;
236         ENTRY("sequential page aligned file I/O");
237
238         t_touch(path);
239
240         fd = t_open(path);
241
242         for (i = 0; i < npages; i++ ) {
243                 memset(wbuf, i, bufsize);
244                 rc = write(fd, wbuf, bufsize);
245                 if (rc != bufsize) {
246                         printf("write error %d (i = %d)\n", rc, i);
247                         exit(1);
248                 }
249         }
250         printf("succefully write %d pages\n", npages);
251
252         lseek(fd, 0, SEEK_SET);
253
254         for (i = 0; i < npages; i++ ) {
255                 memset(rbuf, 0, bufsize);
256                 rc = read(fd, rbuf, bufsize);
257                 if (rc != bufsize) {
258                         printf("read error %d (i = %d)\n", rc, i);
259                         exit(1);
260                 }
261         }
262         printf("succefully read & verified %d pages\n", npages);
263
264         t_close(fd);
265
266         t_unlink(path);
267         LEAVE();
268 }
269
270 void t6()
271 {
272         char *path="/mnt/lustre/test_t6";
273         char *path2="/mnt/lustre/test_t6_link";
274         ENTRY("symlink");
275
276         t_touch(path);
277         FAIL();
278         t_symlink(path, path2);
279         RECOVER();
280         t_check_stat(path2, NULL);
281         t_unlink(path2);
282         t_unlink(path);
283         LEAVE();
284 }
285
286 void t7()
287 {
288         char *path="/mnt/lustre/test_t7";
289         ENTRY("mknod");
290
291         FAIL();
292         t_mknod(path, S_IFCHR | 0644, 5, 4);
293         RECOVER();
294         t_check_stat(path, NULL);
295         t_unlink(path);
296         LEAVE();
297 }
298
299 extern int portal_debug;
300 extern int portal_subsystem_debug;
301
302 extern void __liblustre_setup_(void);
303 extern void __liblustre_cleanup_(void);
304
305 void usage(const char *cmd)
306 {
307         printf("Usage: \t%s -s mds_hostname --target mdsnid:/mdsname/profile\n", cmd);
308         printf("       \t%s -s mds_hostname --dumpfile dumpfile\n", cmd);
309         exit(-1);
310 }
311
312 int main(int argc, char * argv[])
313 {
314         int opt_index, c;
315         char cmd[1024];
316         static struct option long_opts[] = {
317                 {"target", 1, 0, 0},
318                 {"dumpfile", 1, 0, 0},
319                 {"ssh", 1, 0, 0},
320                 {0, 0, 0, 0}
321         };
322
323         if (argc < 3)
324                 usage(argv[0]);
325
326         while ((c = getopt_long(argc, argv, "s:", long_opts, &opt_index)) != -1) {
327                 switch (c) {
328                 case 0: {
329                         if (!optarg[0])
330                                 usage(argv[0]);
331
332                         if (!strcmp(long_opts[opt_index].name, "target")) {
333                                 setenv(ENV_LUSTRE_MNTTGT, optarg, 1);
334                         } else if (!strcmp(long_opts[opt_index].name, "dumpfile")) {
335                                 setenv(ENV_LUSTRE_DUMPFILE, optarg, 1);
336                         } else if (!strcmp(long_opts[opt_index].name, "ssh")) {
337                                 safe_strncpy(ssh_cmd, optarg, MAX_STRING_SIZE);
338                         } else
339                                 usage(argv[0]);
340                         break;
341                 }
342                 case 's':
343                         safe_strncpy(mds_server, optarg, MAX_STRING_SIZE);
344                         break;
345                 default:
346                         usage(argv[0]);
347                 }
348         }
349
350         if (optind != argc)
351                 usage(argv[0]);
352
353         if (strlen(mds_server) == 0)
354                 usage(argv[0]);
355
356         /* default to using ssh */
357         if (!strlen(ssh_cmd)) {
358                 safe_strncpy(ssh_cmd, "ssh", MAX_STRING_SIZE);
359         }
360
361         sprintf(cmd, "%s %s cat /dev/null", ssh_cmd, mds_server);
362         if (system(cmd)) {
363                 printf("Can't access server node: %s using method: %s\n", mds_server, ssh_cmd);
364                 exit(-1);
365         }
366
367         setenv(ENV_LUSTRE_TIMEOUT, "10", 1);
368
369         __liblustre_setup_();
370
371         while (drop_arr[drop_index].name) {
372                 t1();
373                 t2();
374                 t3();
375                 t4();
376                 t5();
377                 t6();
378                 t7();
379
380                 drop_index++;
381         }
382
383         printf("liblustre is about shutdown\n");
384         __liblustre_cleanup_();
385
386         printf("complete successfully\n");
387         return (0);
388 }