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