Whamcloud - gitweb
LU-329 fix missing ost_lock_put() calls
[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  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/liblustre/tests/replay_single.c
37  *
38  * Lustre Light user test program
39  */
40
41 #define _BSD_SOURCE
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <unistd.h>
46 #include <getopt.h>
47 #include <string.h>
48 #include <sys/types.h>
49 #include <sys/stat.h>
50 #include <fcntl.h>
51 #include <sys/queue.h>
52 #include <signal.h>
53
54 #include <sysio.h>
55 #include <mount.h>
56
57 #include "test_common.h"
58
59 #define MAX_STRING_SIZE 2048
60
61 static char mds_server[MAX_STRING_SIZE] = {0,};
62 static char barrier_script[MAX_STRING_SIZE] = {0,};
63 static char failover_script[MAX_STRING_SIZE] = {0,};
64 static char barrier_cmd[MAX_STRING_SIZE] = {0,};
65 static char failover_cmd[MAX_STRING_SIZE] = {0,};
66 static char ssh_cmd[MAX_STRING_SIZE] = {0,};
67
68 static void replay_barrier()
69 {
70         int rc;
71
72         if ((rc = system(barrier_cmd))) {
73                 printf("excute barrier error: %d\n", rc);
74                 exit(rc);
75         }
76 }
77
78 static void mds_failover()
79 {
80         int rc;
81
82         if ((rc = system(failover_cmd))) {
83                 printf("excute failover error: %d\n", rc);
84                 exit(rc);
85         }
86 }
87
88
89 #define ENTRY(str)                                                      \
90         do {                                                            \
91                 char buf[100];                                          \
92                 int len;                                                \
93                 sprintf(buf, "===== START: %s ", (str));                \
94                 len = strlen(buf);                                      \
95                 if (len < 79) {                                         \
96                         memset(buf+len, '=', 100-len);                  \
97                         buf[79] = '\n';                                 \
98                         buf[80] = 0;                                    \
99                 }                                                       \
100                 printf("%s", buf);                                      \
101         } while (0)
102
103 #define LEAVE()                                                         \
104         do {                                                            \
105                 printf("----- END TEST successfully ---");              \
106                 printf("-----------------------------");                \
107                 printf("-------------------\n");                        \
108         } while (0)
109
110 void t0()
111 {
112         char *path="/mnt/lustre/f0";
113         ENTRY("empty replay");
114
115         replay_barrier();
116         mds_failover();
117         t_check_stat_fail(path);
118         LEAVE();
119 }
120
121 void t1()
122 {
123         char *path="/mnt/lustre/f1";
124         ENTRY("simple create");
125
126         replay_barrier();
127         t_create(path);
128         mds_failover();
129         t_check_stat(path, NULL);
130         t_unlink(path);
131         LEAVE();
132 }
133
134 void t2a()
135 {
136         char *path="/mnt/lustre/f2a";
137         ENTRY("touch");
138
139         replay_barrier();
140         t_touch(path);
141         mds_failover();
142         t_check_stat(path, NULL);
143         t_unlink(path);
144         LEAVE();
145 }
146
147 void t2b()
148 {
149         char *path="/mnt/lustre/f2b";
150         ENTRY("mcreate+touch");
151
152         t_create(path);
153         replay_barrier();
154         t_touch(path);
155         mds_failover();
156         t_check_stat(path, NULL);
157         t_unlink(path);
158         LEAVE();
159 }
160
161
162 void n_create_delete(int nfiles)
163 {
164         char *base="/mnt/lustre/f3_";
165         char path[100];
166         char str[100];
167         int i;
168
169         replay_barrier();
170         for (i = 0; i < nfiles; i++) {
171                 sprintf(path, "%s%d\n", base, i);
172                 sprintf(str, "TEST#%d CONTENT\n", i);
173                 t_echo_create(path, str);
174         }
175         mds_failover();
176         for (i = 0; i < nfiles; i++) {
177                 sprintf(path, "%s%d\n", base, i);
178                 sprintf(str, "TEST#%d CONTENT\n", i);
179                 t_grep(path, str);
180         }
181         replay_barrier();
182         for (i = 0; i < nfiles; i++) {
183                 sprintf(path, "%s%d\n", base, i);
184                 t_unlink(path);
185         }
186         mds_failover();
187         for (i = 0; i < nfiles; i++) {
188                 sprintf(path, "%s%d\n", base, i);
189                 t_check_stat_fail(path);
190         }
191         LEAVE();
192 }
193
194 void t3a()
195 {
196         ENTRY("10 create/delete");
197         n_create_delete(10);
198         LEAVE();
199 }
200
201 void t3b()
202 {
203         ENTRY("30 create/delete(>1'st block precreated)");
204         n_create_delete(30);
205         LEAVE();
206 }
207
208 void t4()
209 {
210         char *dir="/mnt/lustre/d4";
211         char *path="/mnt/lustre/d4/f1";
212         ENTRY("mkdir + contained create");
213
214         replay_barrier();
215         t_mkdir(dir);
216         t_create(path);
217         mds_failover();
218         t_check_stat(dir, NULL);
219         t_check_stat(path, NULL);
220         sleep(2); /* wait for log process thread */
221
222         replay_barrier();
223         t_unlink(path);
224         t_rmdir(dir);
225         mds_failover();
226         t_check_stat_fail(dir);
227         t_check_stat_fail(path);
228         LEAVE();
229 }
230
231 void t5()
232 {
233         char *dir="/mnt/lustre/d5";
234         char *path="/mnt/lustre/d5/f1";
235         ENTRY("mkdir |X| contained create");
236
237         t_mkdir(dir);
238         replay_barrier();
239         t_create(path);
240         mds_failover();
241         t_check_stat(dir, NULL);
242         t_check_stat(path, NULL);
243         t_unlink(path);
244         t_rmdir(dir);
245         LEAVE();
246 }
247
248 void t6()
249 {
250         char *path="/mnt/lustre/f6";
251         int fd;
252         ENTRY("open |X| close");
253
254         replay_barrier();
255         t_create(path);
256         fd = t_open(path);
257         sleep(1);
258         mds_failover();
259         t_check_stat(path, NULL);
260         t_close(fd);
261         t_unlink(path);
262         LEAVE();
263 }
264
265 void t7()
266 {
267         char *path="/mnt/lustre/f7";
268         char *path2="/mnt/lustre/f7-2";
269         ENTRY("create |X| rename unlink");
270
271         t_create(path);
272         replay_barrier();
273         t_rename(path, path2);
274         mds_failover();
275         t_check_stat_fail(path);
276         t_check_stat(path2, NULL);
277         t_unlink(path2);
278 }
279
280 void t8()
281 {
282         char *path="/mnt/lustre/f8";
283         char *path2="/mnt/lustre/f8-2";
284         ENTRY("create open write rename |X| create-old-name read");
285
286         t_create(path);
287         t_echo_create(path, "old");
288         t_rename(path, path2);
289         replay_barrier();
290         t_echo_create(path, "new");
291         mds_failover();
292         t_grep(path, "new");
293         t_grep(path2, "old");
294         t_unlink(path);
295         t_unlink(path2);
296 }
297
298 void t9()
299 {
300         char *path="/mnt/lustre/f9";
301         char *path2="/mnt/lustre/f9-2";
302         ENTRY("|X| open(O_CREAT), unlink, touch new, unlink new");
303
304         replay_barrier();
305         t_create(path);
306         t_unlink(path);
307         t_create(path2);
308         mds_failover();
309         t_check_stat_fail(path);
310         t_check_stat(path2, NULL);
311         t_unlink(path2);
312 }
313
314 void t10()
315 {
316         char *path="/mnt/lustre/f10";
317         char *path2="/mnt/lustre/f10-2";
318         ENTRY("|X| mcreate, open write, rename");
319
320         replay_barrier();
321         t_create(path);
322         t_echo_create(path, "old");
323         t_rename(path, path2);
324         t_grep(path2, "old");
325         mds_failover();
326         t_grep(path2, "old");
327         t_unlink(path2);
328 }
329
330 extern int libcfs_debug;
331 extern int libcfs_subsystem_debug;
332
333 extern void __liblustre_setup_(void);
334 extern void __liblustre_cleanup_(void);
335
336 void usage(const char *cmd)
337 {
338         printf("Usage: \t%s --target mdsnid:/mdsname/profile -s mds_hostname "
339                 "-b \"barrier cmd\" -f \"failover cmd\" [--rsh \"rsh_cmd\"]\n", cmd);
340         printf("       \t%s --dumpfile dumpfile -s mds_hostname -b \"barrier cmd\" "
341                 "-f \"failover cmd\" [--rsh \"rsh_cmd\"]\n", cmd);
342         exit(-1);
343 }
344
345 void test_ssh()
346 {
347         char cmd[MAX_STRING_SIZE];
348
349         sprintf(cmd, "%s %s cat /dev/null", ssh_cmd, mds_server);
350         if (system(cmd)) {
351                 printf("Can't access server node: %s using method: %s\n", mds_server, ssh_cmd);
352                 exit(-1);
353         }
354 }
355
356 int main(int argc, char * const argv[])
357 {
358         int opt_index, c;
359         static struct option long_opts[] = {
360                 {"target", 1, 0, 0},
361                 {"dumpfile", 1, 0, 0},
362                 {"ssh", 1, 0, 0},
363                 {0, 0, 0, 0}
364         };
365
366         if (argc < 4 - (getenv(ENV_LUSTRE_MNTTGT)||getenv(ENV_LUSTRE_DUMPFILE)))
367                 usage(argv[0]);
368
369         while ((c = getopt_long(argc, argv, "s:b:f:", long_opts, &opt_index)) != -1) {
370                 switch (c) {
371                 case 0: {
372                         if (!optarg[0])
373                                 usage(argv[0]);
374
375                         if (!strcmp(long_opts[opt_index].name, "target")) {
376                                 setenv(ENV_LUSTRE_MNTTGT, optarg, 1);
377                         } else if (!strcmp(long_opts[opt_index].name, "dumpfile")) {
378                                 setenv(ENV_LUSTRE_DUMPFILE, optarg, 1);
379                         } else if (!strcmp(long_opts[opt_index].name, "ssh")) {
380                                 safe_strncpy(ssh_cmd, optarg, MAX_STRING_SIZE);
381                         } else
382                                 usage(argv[0]);
383                         break;
384                 }
385                 case 's':
386                         safe_strncpy(mds_server, optarg, MAX_STRING_SIZE);
387                         break;
388                 case 'b':
389                         safe_strncpy(barrier_script, optarg, MAX_STRING_SIZE);
390                         break;
391                 case 'f':
392                         safe_strncpy(failover_script, optarg, MAX_STRING_SIZE);
393                         break;
394                 default:
395                         usage(argv[0]);
396                 }
397         }
398
399         if (optind != argc)
400                 usage(argv[0]);
401         if (!strlen(mds_server) || !strlen(barrier_script) ||
402             !strlen(failover_script))
403                 usage(argv[0]);
404
405         /* default to using ssh */
406         if (!strlen(ssh_cmd)) {
407                 safe_strncpy(ssh_cmd, "ssh", MAX_STRING_SIZE);
408         }
409
410         test_ssh();
411
412         /* prepare remote command */
413         sprintf(barrier_cmd, "%s %s \"%s\"", 
414                 ssh_cmd, mds_server, barrier_script);
415         sprintf(failover_cmd, "%s %s \"%s\"", 
416                 ssh_cmd, mds_server, failover_script);
417
418         setenv(ENV_LUSTRE_TIMEOUT, "10", 1);
419
420         __liblustre_setup_();
421
422         t0();
423         t1();
424         t2a();
425         t2b();
426         t3a();
427         t3b();
428         t4();
429         t5();
430         t6();
431         t7();
432         t8();
433         t9();
434         t10();
435
436         printf("liblustre is about shutdown\n");
437         __liblustre_cleanup_();
438
439         printf("complete successfully\n");
440         return 0;
441 }