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