Whamcloud - gitweb
b=15870
[fs/lustre-release.git] / lustre / liblustre / tests / replay_single.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 MAX_STRING_SIZE 2048
43
44 static char mds_server[MAX_STRING_SIZE] = {0,};
45 static char barrier_script[MAX_STRING_SIZE] = {0,};
46 static char failover_script[MAX_STRING_SIZE] = {0,};
47 static char barrier_cmd[MAX_STRING_SIZE] = {0,};
48 static char failover_cmd[MAX_STRING_SIZE] = {0,};
49 static char ssh_cmd[MAX_STRING_SIZE] = {0,};
50
51 static void replay_barrier()
52 {
53         int rc;
54
55         if ((rc = system(barrier_cmd))) {
56                 printf("excute barrier error: %d\n", rc);
57                 exit(rc);
58         }
59 }
60
61 static void mds_failover()
62 {
63         int rc;
64
65         if ((rc = system(failover_cmd))) {
66                 printf("excute failover error: %d\n", rc);
67                 exit(rc);
68         }
69 }
70
71
72 #define ENTRY(str)                                                      \
73         do {                                                            \
74                 char buf[100];                                          \
75                 int len;                                                \
76                 sprintf(buf, "===== START: %s ", (str));                \
77                 len = strlen(buf);                                      \
78                 if (len < 79) {                                         \
79                         memset(buf+len, '=', 100-len);                  \
80                         buf[79] = '\n';                                 \
81                         buf[80] = 0;                                    \
82                 }                                                       \
83                 printf("%s", buf);                                      \
84         } while (0)
85
86 #define LEAVE()                                                         \
87         do {                                                            \
88                 printf("----- END TEST successfully ---");              \
89                 printf("-----------------------------");                \
90                 printf("-------------------\n");                        \
91         } while (0)
92
93 void t0()
94 {
95         char *path="/mnt/lustre/f0";
96         ENTRY("empty replay");
97         replay_barrier();
98         mds_failover();
99         t_check_stat_fail("/mnt/lustre/f0");
100         LEAVE();
101 }
102
103 void t1()
104 {
105         char *path="/mnt/lustre/f1";
106         ENTRY("simple create");
107
108         replay_barrier();
109         t_create(path);
110         mds_failover();
111         t_check_stat(path, NULL);
112         t_unlink(path);
113         LEAVE();
114 }
115
116 void t2a()
117 {
118         char *path="/mnt/lustre/f2a";
119         ENTRY("touch");
120
121         replay_barrier();
122         t_touch(path);
123         mds_failover();
124         t_check_stat(path, NULL);
125         t_unlink(path);
126         LEAVE();
127 }
128
129 void t2b()
130 {
131         char *path="/mnt/lustre/f2b";
132         ENTRY("mcreate+touch");
133
134         t_create(path);
135         replay_barrier();
136         t_touch(path);
137         mds_failover();
138         t_check_stat(path, NULL);
139         t_unlink(path);
140         LEAVE();
141 }
142
143
144 void n_create_delete(int nfiles)
145 {
146         char *base="/mnt/lustre/f3_";
147         char path[100];
148         char str[100];
149         int i;
150
151         replay_barrier();
152         for (i = 0; i < nfiles; i++) {
153                 sprintf(path, "%s%d\n", base, i);
154                 sprintf(str, "TEST#%d CONTENT\n", i);
155                 t_echo_create(path, str);
156         }
157         mds_failover();
158         for (i = 0; i < nfiles; i++) {
159                 sprintf(path, "%s%d\n", base, i);
160                 sprintf(str, "TEST#%d CONTENT\n", i);
161                 t_grep(path, str);
162         }
163         replay_barrier();
164         for (i = 0; i < nfiles; i++) {
165                 sprintf(path, "%s%d\n", base, i);
166                 t_unlink(path);
167         }
168         mds_failover();
169         for (i = 0; i < nfiles; i++) {
170                 sprintf(path, "%s%d\n", base, i);
171                 t_check_stat_fail(path);
172         }
173         LEAVE();
174 }
175
176 void t3a()
177 {
178         ENTRY("10 create/delete");
179         n_create_delete(10);
180         LEAVE();
181 }
182
183 void t3b()
184 {
185         ENTRY("30 create/delete(>1'st block precreated)");
186         n_create_delete(30);
187         LEAVE();
188 }
189
190 void t4()
191 {
192         char *dir="/mnt/lustre/d4";
193         char *path="/mnt/lustre/d4/f1";
194         ENTRY("mkdir + contained create");
195
196         replay_barrier();
197         t_mkdir(dir);
198         t_create(path);
199         mds_failover();
200         t_check_stat(dir, NULL);
201         t_check_stat(path, NULL);
202         sleep(2); /* wait for log process thread */
203
204         replay_barrier();
205         t_unlink(path);
206         t_rmdir(dir);
207         mds_failover();
208         t_check_stat_fail(dir);
209         t_check_stat_fail(path);
210         LEAVE();
211 }
212
213 void t5()
214 {
215         char *dir="/mnt/lustre/d5";
216         char *path="/mnt/lustre/d5/f1";
217         ENTRY("mkdir |X| contained create");
218
219         t_mkdir(dir);
220         replay_barrier();
221         t_create(path);
222         mds_failover();
223         t_check_stat(dir, NULL);
224         t_check_stat(path, NULL);
225         t_unlink(path);
226         t_rmdir(dir);
227         LEAVE();
228 }
229
230 void t6()
231 {
232         char *path="/mnt/lustre/f6";
233         int fd;
234         ENTRY("open |X| close");
235
236         replay_barrier();
237         t_create(path);
238         fd = t_open(path);
239         sleep(1);
240         mds_failover();
241         t_check_stat(path, NULL);
242         t_close(fd);
243         t_unlink(path);
244         LEAVE();
245 }
246
247 void t7()
248 {
249         char *path="/mnt/lustre/f7";
250         char *path2="/mnt/lustre/f7-2";
251         ENTRY("create |X| rename unlink");
252
253         t_create(path);
254         replay_barrier();
255         t_rename(path, path2);
256         mds_failover();
257         t_check_stat_fail(path);
258         t_check_stat(path2, NULL);
259         t_unlink(path2);
260 }
261
262 void t8()
263 {
264         char *path="/mnt/lustre/f8";
265         char *path2="/mnt/lustre/f8-2";
266         ENTRY("create open write rename |X| create-old-name read");
267
268         t_create(path);
269         t_echo_create(path, "old");
270         t_rename(path, path2);
271         replay_barrier();
272         t_echo_create(path, "new");
273         mds_failover();
274         t_grep(path, "new");
275         t_grep(path2, "old");
276         t_unlink(path);
277         t_unlink(path2);
278 }
279
280 void t9()
281 {
282         char *path="/mnt/lustre/f9";
283         char *path2="/mnt/lustre/f9-2";
284         ENTRY("|X| open(O_CREAT), unlink, touch new, unlink new");
285
286         replay_barrier();
287         t_create(path);
288         t_unlink(path);
289         t_create(path2);
290         mds_failover();
291         t_check_stat_fail(path);
292         t_check_stat(path2, NULL);
293         t_unlink(path2);
294 }
295
296 void t10()
297 {
298         char *path="/mnt/lustre/f10";
299         char *path2="/mnt/lustre/f10-2";
300         ENTRY("|X| mcreate, open write, rename");
301
302         replay_barrier();
303         t_create(path);
304         t_echo_create(path, "old");
305         t_rename(path, path2);
306         t_grep(path2, "old");
307         mds_failover();
308         t_grep(path2, "old");
309         t_unlink(path2);
310 }
311
312 extern int libcfs_debug;
313 extern int libcfs_subsystem_debug;
314
315 extern void __liblustre_setup_(void);
316 extern void __liblustre_cleanup_(void);
317
318 void usage(const char *cmd)
319 {
320         printf("Usage: \t%s --target mdsnid:/mdsname/profile -s mds_hostname "
321                 "-b \"barrier cmd\" -f \"failover cmd\" [--rsh \"rsh_cmd\"]\n", cmd);
322         printf("       \t%s --dumpfile dumpfile -s mds_hostname -b \"barrier cmd\" "
323                 "-f \"failover cmd\" [--rsh \"rsh_cmd\"]\n", cmd);
324         exit(-1);
325 }
326
327 void test_ssh()
328 {
329         char cmd[MAX_STRING_SIZE];
330
331         sprintf(cmd, "%s %s cat /dev/null", ssh_cmd, mds_server);
332         if (system(cmd)) {
333                 printf("Can't access server node: %s using method: %s\n", mds_server, ssh_cmd);
334                 exit(-1);
335         }
336 }
337
338 int main(int argc, char * const argv[])
339 {
340         int opt_index, c;
341         static struct option long_opts[] = {
342                 {"target", 1, 0, 0},
343                 {"dumpfile", 1, 0, 0},
344                 {"ssh", 1, 0, 0},
345                 {0, 0, 0, 0}
346         };
347
348         if (argc < 4 - (getenv(ENV_LUSTRE_MNTTGT)||getenv(ENV_LUSTRE_DUMPFILE)))
349                 usage(argv[0]);
350
351         while ((c = getopt_long(argc, argv, "s:b:f:", long_opts, &opt_index)) != -1) {
352                 switch (c) {
353                 case 0: {
354                         if (!optarg[0])
355                                 usage(argv[0]);
356
357                         if (!strcmp(long_opts[opt_index].name, "target")) {
358                                 setenv(ENV_LUSTRE_MNTTGT, optarg, 1);
359                         } else if (!strcmp(long_opts[opt_index].name, "dumpfile")) {
360                                 setenv(ENV_LUSTRE_DUMPFILE, optarg, 1);
361                         } else if (!strcmp(long_opts[opt_index].name, "ssh")) {
362                                 safe_strncpy(ssh_cmd, optarg, MAX_STRING_SIZE);
363                         } else
364                                 usage(argv[0]);
365                         break;
366                 }
367                 case 's':
368                         safe_strncpy(mds_server, optarg, MAX_STRING_SIZE);
369                         break;
370                 case 'b':
371                         safe_strncpy(barrier_script, optarg, MAX_STRING_SIZE);
372                         break;
373                 case 'f':
374                         safe_strncpy(failover_script, optarg, MAX_STRING_SIZE);
375                         break;
376                 default:
377                         usage(argv[0]);
378                 }
379         }
380
381         if (optind != argc)
382                 usage(argv[0]);
383         if (!strlen(mds_server) || !strlen(barrier_script) ||
384             !strlen(failover_script))
385                 usage(argv[0]);
386
387         /* default to using ssh */
388         if (!strlen(ssh_cmd)) {
389                 safe_strncpy(ssh_cmd, "ssh", MAX_STRING_SIZE);
390         }
391
392         test_ssh();
393
394         /* prepare remote command */
395         sprintf(barrier_cmd, "%s %s \"%s\"", 
396                 ssh_cmd, mds_server, barrier_script);
397         sprintf(failover_cmd, "%s %s \"%s\"", 
398                 ssh_cmd, mds_server, failover_script);
399
400         setenv(ENV_LUSTRE_TIMEOUT, "10", 1);
401
402         __liblustre_setup_();
403
404         t0();
405         t1();
406         t2a();
407         t2b();
408         t3a();
409         t3b();
410         t4();
411         t5();
412         t6();
413         t7();
414         t8();
415         t9();
416         t10();
417
418         printf("liblustre is about shutdown\n");
419         __liblustre_cleanup_();
420
421         printf("complete successfully\n");
422         return 0;
423 }