Whamcloud - gitweb
b=23408 disable failure temporarily while we collect performance stats
[fs/lustre-release.git] / lustre / tests / mkdirdeep.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/tests/mkdirdeep.c
37  *
38  * Compile with:
39  * cc -I../../lnet/include -o mkdirdeep mkdirdeep.c
40  *    -L../../lnet/linux/utils -lptlctl
41  */
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <getopt.h>
46 #include <string.h>
47 #include <errno.h>
48 #include <sys/types.h>
49 #include <sys/stat.h>
50 #include <fcntl.h>
51 #include <unistd.h>
52 #include <linux/limits.h>
53 #include <libcfs/lltrace.h>
54
55 static int opt_verbose = 0;
56 static int opt_trace = 0;
57
58 void usage(const char *pname)
59 {
60         fprintf(stderr, "Usage: %s --depth <d> [--output <outputtracefilename>]"
61                 " [--mknod] [--verbose] [--notrace] <basepath>\n", pname);
62         exit(1);
63 }
64
65 int do_mkdir(char *path)
66 {
67         int rc = mkdir(path, 0755);
68
69         if (rc) {
70                 fprintf(stderr, "mkdir(%s) failed: %s\n",
71                         path, strerror(errno));
72                 exit(1);
73         }
74         if (opt_verbose)
75                 printf("mkdir %s\n", path);
76
77         return rc;
78 }
79
80
81 int do_mknod(char *path)
82 {
83         int rc = mknod(path, 0755, S_IFIFO);
84
85         if (rc) {
86                 fprintf(stderr, "mkdir(%s) failed: %s\n",
87                         path, strerror(errno));
88                 exit(1);
89         }
90         if (opt_verbose)
91                 printf("mknod %s\n", path);
92
93         return rc;
94 }
95
96 int do_chdir(char* path)
97 {
98         int rc = chdir(path);
99
100         if (rc) {
101                 fprintf(stderr, "chdir(%s) failed: %s\n",
102                         path, strerror(errno));
103                 exit(1);
104         }
105         if (opt_verbose)
106                 printf("chdir %s\n", path);
107
108         return rc;
109 }
110
111 int do_stat(char *path)
112 {
113         char mark_buf[PATH_MAX + 50];
114         struct stat mystat;
115         int rc = stat(path, &mystat);
116
117         if (rc) {
118                 fprintf(stderr, "stat(%s) failed: %s\n",
119                         path, strerror(errno));
120                 exit(1);
121         }
122         if (opt_verbose)
123                 printf("stat %s = inode %lu\n", path,
124                        (unsigned long)mystat.st_ino);
125
126         if (opt_trace) {
127                 snprintf(mark_buf, PATH_MAX, "stat %s = inode %lu",
128                          path, (unsigned long)mystat.st_ino);
129                 ltrace_mark(0, mark_buf);
130         }
131
132         return rc;
133 }
134
135 int main(int argc, char** argv)
136 {
137         int c, i, mypid;
138         int opt_depth = 1;
139         int opt_mknod = 0;
140
141         static struct option long_opt[] = {
142                 {"depth", 1, 0, 'd' },
143                 {"help", 0, 0, 'h' },
144                 {"mknod", 0, 0, 'm' },
145                 {"output", 1, 0, 'o' },
146                 {"trace", 1, 0, 't' },
147                 {"verbose", 0, 0, 'v' },
148                 {0,0,0,0}
149         };
150
151         char *outputfilename = NULL;
152         char *base_pathname;
153         char pathname[PATH_MAX];
154         char mark_buf[PATH_MAX + 50];
155         char mycwd[PATH_MAX];
156         char *pname = argv[0];
157
158         while ((c = getopt_long(argc, argv, "d:mhvo:", long_opt, NULL)) != -1) {
159                 switch (c) {
160                 case 'd':
161                         opt_depth = atoi(optarg);
162                         if ((opt_depth == 0) || (opt_depth > 1100))
163                                 usage(pname);
164                         break;
165                 case 'm':
166                         opt_mknod = 1;
167                         break;
168                 case 't':
169                         opt_trace = 1;
170                         break;
171                 case 'v':
172                         opt_verbose = 1;
173                         break;
174                 case 'o':
175                         outputfilename = optarg;
176                         break;
177                 case 'h':
178                 case '?':
179                 case ':':
180                 default:
181                         usage(pname);
182                         break;
183                 }
184         }
185
186         if (optind != (argc - 1))
187                 usage(pname);
188
189         base_pathname = argv[optind];
190         mypid = getpid();
191
192         if (!getcwd(&mycwd[0], sizeof(mycwd))) {
193                 fprintf(stderr, "%s: unable to getcwd()\n", pname);
194                 exit(1);
195         }
196
197         printf("%s(pid=%d) depth=%d mknod=%d, basepathname=%s, trace=%d\n",
198                pname, mypid, opt_depth, opt_mknod, base_pathname, opt_trace);
199
200         if (outputfilename)
201                 printf("outputfilename=%s\n", outputfilename);
202
203         if (opt_trace) {
204                 ltrace_start();
205                 ltrace_clear();
206                 snprintf(mark_buf, PATH_MAX, "Initialize - mkdir %s; chdir %s",
207                          base_pathname, base_pathname);
208                 ltrace_mark(2, mark_buf);
209         }
210
211         if (do_mkdir(base_pathname)!=0)
212                 exit(1);
213         if (do_chdir(base_pathname)!=0)
214                 exit(1);
215
216         /* Create directory tree with depth level of subdirectories */
217
218         if (opt_trace) {
219                 snprintf(mark_buf, PATH_MAX,
220                          "Create Directory Tree (depth %d)", opt_depth);
221                 ltrace_mark(2, mark_buf);
222         }
223
224         for (i = 0; i < opt_depth; i++) {
225                 snprintf(pathname, sizeof(pathname), "%d", i + 1);
226
227                 if (i == (opt_depth - 1)) {
228                         /* Last Iteration */
229
230                         if (opt_trace) {
231                                 snprintf(mark_buf, PATH_MAX,
232                                          "Tree Leaf (%d) %s/stat", i,
233                                          (opt_mknod ? "mknod" : "mkdir"));
234                                 ltrace_mark(3, mark_buf);
235                         }
236
237                         if (opt_mknod)
238                                 do_mknod(pathname);
239                         else
240                                 do_mkdir(pathname);
241                         /* Now stat it */
242                         do_stat(pathname);
243                 } else {
244                         /* Not Leaf */
245
246                         if (opt_trace) {
247                                 snprintf(mark_buf, sizeof(mark_buf),
248                                          "Tree Level (%d) mkdir/stat/chdir", i);
249                                 ltrace_mark(3, mark_buf);
250                         }
251
252                         do_mkdir(pathname);
253                         do_stat(pathname);
254                         do_chdir(pathname);
255                 }
256         }
257
258         /* Stat through directory tree with fullpaths */
259
260         if (opt_trace) {
261                 snprintf(mark_buf, PATH_MAX, "Walk Directory Tree");
262                 ltrace_mark(2, mark_buf);
263         }
264
265         do_chdir(base_pathname);
266
267         strncpy(pathname, base_pathname, sizeof(pathname));
268
269         c = strlen(base_pathname);
270         for (i = 0; i < opt_depth; i++) {
271                 c += snprintf(pathname + c, sizeof(pathname) - c, "/%d", i+1);
272
273                 if (opt_trace) {
274                         snprintf(mark_buf, PATH_MAX, "stat %s", pathname);
275                         ltrace_mark(2, mark_buf);
276                 }
277
278                 do_stat(pathname);
279         }
280
281         if (opt_trace && outputfilename) {
282                     ltrace_write_file(outputfilename);
283                     ltrace_add_processnames(outputfilename);
284                     ltrace_stop();
285         }
286
287         do_chdir(base_pathname);
288
289         printf("%s (pid=%d) done.\n", pname, mypid);
290
291         return 0;
292 }