Whamcloud - gitweb
LU-5456 hsm: hold inode mutex around ll_setattr_raw()
[fs/lustre-release.git] / lustre / liblustre / tests / recovery_small.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  *
34  * lustre/liblustre/tests/recovery_small.c
35  *
36  * Lustre Light user test program
37  */
38
39 #define _BSD_SOURCE
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44 #include <getopt.h>
45 #include <string.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <fcntl.h>
49 #include <sys/queue.h>
50 #include <getopt.h>
51 #include <sys/wait.h>
52
53 #include <sysio.h>
54 #include <mount.h>
55
56 #include "test_common.h"
57
58 #define MAX_STRING_SIZE 2048
59
60 static struct {
61         const char   *name;
62         unsigned long code;
63 } drop_arr [] =
64 {
65         {"MDS_REQUEST", 0x123},
66         {"MDS_REPLY", 0x122},
67         {NULL, 0}
68 };
69
70 static int drop_index = 0;
71
72 static char mds_server[1024] = {0, };
73 static char ssh_cmd[MAX_STRING_SIZE] = {0,};
74
75 int do_stat(const char *name, struct stat *buf)
76 {
77         struct stat stat;
78         int rc;
79
80         rc = lstat(name, &stat);
81         if (rc) {
82                 printf("error %d stat %s\n", rc, name);
83                 exit(1);
84         }
85         if (buf)
86                 memcpy(buf, &stat, sizeof(*buf));
87
88         return 0;
89 }
90
91 void prepare_reg(const char *path)
92 {
93         int fd, rc;
94
95         fd = open(path, O_RDWR|O_CREAT, 00644);
96         if (fd < 0) {
97                 printf("error %d create %s\n", fd, path);
98                 exit(1);
99         }
100
101         rc = close(fd);
102         if (rc) {
103                 printf("error %d close %s\n", rc, path);
104                 exit(1);
105         }
106 }
107
108 void cleanup_reg(const char *path)
109 {
110         int rc;
111
112         rc = unlink(path);
113         if (rc) {
114                 printf("error %d unlink %s\n", rc, path);
115                 exit(1);
116         }
117 }
118
119 void prepare_dir(const char *path)
120 {
121         int rc;
122
123         rc = mkdir(path, 00644);
124         if (rc < 0) {
125                 printf("error %d mkdir %s\n", rc, path);
126                 exit(1);
127         }
128 }
129
130 void cleanup_dir(const char *path)
131 {
132         int rc;
133
134         rc = rmdir(path);
135         if (rc) {
136                 printf("error %d unlink %s\n", rc, path);
137                 exit(1);
138         }
139 }
140
141 #define FAIL()                                                             \
142     do {                                                                   \
143         char cmd[MAX_STRING_SIZE];                                         \
144         int rc;                                                            \
145                                                                            \
146         if (drop_arr[drop_index].name) {                                   \
147             printf("server drops next %s\n", drop_arr[drop_index].name);   \
148             sprintf(cmd,                                                   \
149                     "%s %s \"lctl set_param fail_loc=%lu\"",               \
150                     ssh_cmd, mds_server, drop_arr[drop_index].code);       \
151             if ((rc = system(cmd)) != 0) {                                 \
152                 rc = WEXITSTATUS(rc);                                      \
153                 printf("error excuting remote command: %d\n", rc);         \
154                 exit(rc);                                                  \
155             }                                                              \
156         }                                                                  \
157     } while (0)
158
159 #define RECOVER()                                                          \
160     do {                                                                   \
161         char cmd[1024];                                                    \
162                                                                            \
163         if (drop_arr[drop_index].name) {                                   \
164             sprintf(cmd, "%s %s \"lctl set_param fail_loc=0\"",            \
165                     ssh_cmd, mds_server);                                  \
166             if (!system(cmd)) {}                                           \
167         }                                                                  \
168     } while (0)
169
170 #define ENTRY(str)                                                      \
171         do {                                                            \
172                 char buf[100];                                          \
173                 int len;                                                \
174                 sprintf(buf, "===== START: %s ", (str));                \
175                 len = strlen(buf);                                      \
176                 if (len < 79) {                                         \
177                         memset(buf+len, '=', 100-len);                  \
178                         buf[79] = '\n';                                 \
179                         buf[80] = 0;                                    \
180                 }                                                       \
181                 printf("%s", buf);                                      \
182         } while (0)
183
184 #define LEAVE()                                                         \
185         do {                                                            \
186                 printf("----- END TEST successfully ---");              \
187                 printf("-----------------------------");                \
188                 printf("-------------------\n");                        \
189         } while (0)
190
191
192 void t1()
193 {
194         char *path="/mnt/lustre/test_t1";
195         ENTRY("create/delete");
196
197         FAIL();
198         t_touch(path);
199         RECOVER();
200         FAIL();
201         t_unlink(path);
202         RECOVER();
203         LEAVE();
204 }
205
206 void t2()
207 {
208         char *path="/mnt/lustre/test_t2";
209         ENTRY("mkdir/rmdir");
210
211         FAIL();
212         t_mkdir(path);
213         RECOVER();
214         FAIL();
215         t_rmdir(path);
216         RECOVER();
217         LEAVE();
218 }
219
220 void t3()
221 {
222         char *path="/mnt/lustre/test_t3";
223         ENTRY("regular stat");
224
225         t_touch(path);
226         FAIL();
227         t_check_stat(path, NULL);
228         RECOVER();
229         t_unlink(path);
230         LEAVE();
231 }
232
233 void t4()
234 {
235         char *path="/mnt/lustre/test_t4";
236         ENTRY("dir stat");
237
238         t_mkdir(path);
239         FAIL();
240         t_check_stat(path, NULL);
241         RECOVER();
242         t_rmdir(path);
243         LEAVE();
244 }
245
246 void t5()
247 {
248         char *path="/mnt/lustre/test_t5";
249         const int bufsize = 4096;
250         char wbuf[bufsize], rbuf[bufsize];
251         int npages = 100;
252         int fd, rc, i;
253         ENTRY("sequential page aligned file I/O");
254
255         t_touch(path);
256
257         fd = t_open(path);
258
259         for (i = 0; i < npages; i++ ) {
260                 memset(wbuf, i, bufsize);
261                 rc = write(fd, wbuf, bufsize);
262                 if (rc != bufsize) {
263                         printf("write error %d (i = %d)\n", rc, i);
264                         exit(1);
265                 }
266         }
267         printf("succefully write %d pages\n", npages);
268
269         lseek(fd, 0, SEEK_SET);
270
271         for (i = 0; i < npages; i++ ) {
272                 memset(rbuf, 0, bufsize);
273                 rc = read(fd, rbuf, bufsize);
274                 if (rc != bufsize) {
275                         printf("read error %d (i = %d)\n", rc, i);
276                         exit(1);
277                 }
278         }
279         printf("succefully read & verified %d pages\n", npages);
280
281         t_close(fd);
282
283         t_unlink(path);
284         LEAVE();
285 }
286
287 void t6()
288 {
289         char *path="/mnt/lustre/test_t6";
290         char *path2="/mnt/lustre/test_t6_link";
291         ENTRY("symlink");
292
293         t_touch(path);
294         FAIL();
295         t_symlink(path, path2);
296         RECOVER();
297         t_check_stat(path2, NULL);
298         t_unlink(path2);
299         t_unlink(path);
300         LEAVE();
301 }
302
303 void t7()
304 {
305         char *path="/mnt/lustre/test_t7";
306         ENTRY("mknod");
307
308         FAIL();
309         t_mknod(path, S_IFCHR | 0644, 5, 4);
310         RECOVER();
311         t_check_stat(path, NULL);
312         t_unlink(path);
313         LEAVE();
314 }
315
316 extern int libcfs_debug;
317 extern int libcfs_subsystem_debug;
318
319 extern void __liblustre_setup_(void);
320 extern void __liblustre_cleanup_(void);
321
322 void usage(const char *cmd)
323 {
324         printf("Usage: \t%s -s mds_hostname --target mdsnid:/mdsname/profile\n", cmd);
325         printf("       \t%s -s mds_hostname --dumpfile dumpfile\n", cmd);
326         exit(-1);
327 }
328
329 int main(int argc, char * argv[])
330 {
331         int opt_index, c;
332         char cmd[1024];
333         static struct option long_opts[] = {
334                 {"target", 1, 0, 0},
335                 {"dumpfile", 1, 0, 0},
336                 {"ssh", 1, 0, 0},
337                 {0, 0, 0, 0}
338         };
339
340         if (argc < 3 - (getenv(ENV_LUSTRE_MNTTGT)||getenv(ENV_LUSTRE_DUMPFILE)))
341                 usage(argv[0]);
342
343         while ((c = getopt_long(argc, argv, "s:", long_opts, &opt_index)) != -1) {
344                 switch (c) {
345                 case 0: {
346                         if (!optarg[0])
347                                 usage(argv[0]);
348
349                         if (!strcmp(long_opts[opt_index].name, "target")) {
350                                 setenv(ENV_LUSTRE_MNTTGT, optarg, 1);
351                         } else if (!strcmp(long_opts[opt_index].name, "dumpfile")) {
352                                 setenv(ENV_LUSTRE_DUMPFILE, optarg, 1);
353                         } else if (!strcmp(long_opts[opt_index].name, "ssh")) {
354                                 safe_strncpy(ssh_cmd, optarg, MAX_STRING_SIZE);
355                         } else
356                                 usage(argv[0]);
357                         break;
358                 }
359                 case 's':
360                         safe_strncpy(mds_server, optarg, MAX_STRING_SIZE);
361                         break;
362                 default:
363                         usage(argv[0]);
364                 }
365         }
366
367         if (optind != argc)
368                 usage(argv[0]);
369
370         if (strlen(mds_server) == 0)
371                 usage(argv[0]);
372
373         /* default to using ssh */
374         if (!strlen(ssh_cmd)) {
375                 safe_strncpy(ssh_cmd, "ssh", MAX_STRING_SIZE);
376         }
377
378         sprintf(cmd, "%s %s cat /dev/null", ssh_cmd, mds_server);
379         if (system(cmd)) {
380                 printf("Can't access server node: %s using method: %s\n", mds_server, ssh_cmd);
381                 exit(-1);
382         }
383
384         setenv(ENV_LUSTRE_TIMEOUT, "5", 1);
385
386         __liblustre_setup_();
387
388         while (drop_arr[drop_index].name) {
389                 t1();
390                 t2();
391                 t3();
392                 t4();
393 #if 0
394                 t5();
395 #endif
396                 t6();
397                 t7();
398
399                 drop_index++;
400         }
401
402         printf("liblustre is about shutdown\n");
403         __liblustre_cleanup_();
404
405         printf("complete successfully\n");
406         return (0);
407 }