Whamcloud - gitweb
merge b_devel into HEAD (20030703)
[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../../portals/include -o mkdirdeep mkdirdeep.c
6  *    -L../../portals/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 <portals/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, mystat.st_ino);
90
91         if (opt_trace) {
92                 snprintf(mark_buf, PATH_MAX, "stat %s = inode %lu",
93                          path, mystat.st_ino);
94                 ltrace_mark(0, mark_buf);
95         }
96
97         return rc;
98 }
99
100 int main(int argc, char** argv)
101 {
102         int c, i, mypid;
103         int opt_depth = 1;
104         int opt_mknod = 0;
105
106         static struct option long_opt[] = {
107                 {"depth", 1, 0, 'd' },
108                 {"help", 0, 0, 'h' },
109                 {"mknod", 0, 0, 'm' },
110                 {"output", 1, 0, 'o' },
111                 {"trace", 1, 0, 't' },
112                 {"verbose", 0, 0, 'v' },
113                 {0,0,0,0}
114         };
115
116         char *outputfilename = NULL;
117         char *base_pathname;
118         char pathname[PATH_MAX];
119         char mark_buf[PATH_MAX + 50];
120         char mycwd[PATH_MAX];
121         char *pname = argv[0];
122
123         while ((c = getopt_long(argc, argv, "d:mhvo:", long_opt, NULL)) != -1) {
124                 switch (c) {
125                 case 'd':
126                         opt_depth = atoi(optarg);
127                         if ((opt_depth == 0) || (opt_depth > 1100))
128                                 usage(pname);
129                         break;
130                 case 'm':
131                         opt_mknod = 1;
132                         break;
133                 case 't':
134                         opt_trace = 1;
135                         break;
136                 case 'v':
137                         opt_verbose = 1;
138                         break;
139                 case 'o':
140                         outputfilename = optarg;
141                         break;
142                 case 'h':
143                 case '?':
144                 case ':':
145                 default:
146                         usage(pname);
147                         break;
148                 }
149         }
150
151         if (optind != (argc - 1))
152                 usage(pname);
153
154         base_pathname = argv[optind];
155         mypid = getpid();
156
157         if (!getcwd(&mycwd[0], sizeof(mycwd))) {
158                 fprintf(stderr, "%s: unable to getcwd()\n", pname);
159                 exit(1);
160         }
161
162         printf("%s(pid=%d) depth=%d mknod=%d, basepathname=%s, trace=%d\n",
163                pname, mypid, opt_depth, opt_mknod, base_pathname, opt_trace);
164
165         if (outputfilename)
166                 printf("outputfilename=%s\n", outputfilename);
167
168         if (opt_trace) {
169                 ltrace_start();
170                 ltrace_clear();
171                 snprintf(mark_buf, PATH_MAX, "Initialize - mkdir %s; chdir %s",
172                          base_pathname, base_pathname);
173                 ltrace_mark(2, mark_buf);
174         }
175
176         if (do_mkdir(base_pathname)!=0)
177                 exit(1);
178         if (do_chdir(base_pathname)!=0)
179                 exit(1);
180
181         /* Create directory tree with depth level of subdirectories */
182
183         if (opt_trace) {
184                 snprintf(mark_buf, PATH_MAX,
185                          "Create Directory Tree (depth %d)", opt_depth);
186                 ltrace_mark(2, mark_buf);
187         }
188
189         for (i = 0; i < opt_depth; i++) {
190                 snprintf(pathname, sizeof(pathname), "%d", i + 1);
191
192                 if (i == (opt_depth - 1)) {
193                         /* Last Iteration */
194
195                         if (opt_trace) {
196                                 snprintf(mark_buf, PATH_MAX,
197                                          "Tree Leaf (%d) %s/stat", i,
198                                          (opt_mknod ? "mknod" : "mkdir"));
199                                 ltrace_mark(3, mark_buf);
200                         }
201
202                         if (opt_mknod)
203                                 do_mknod(pathname);
204                         else
205                                 do_mkdir(pathname);
206                         /* Now stat it */
207                         do_stat(pathname);
208                 } else {
209                         /* Not Leaf */
210
211                         if (opt_trace) {
212                                 snprintf(mark_buf, sizeof(mark_buf),
213                                          "Tree Level (%d) mkdir/stat/chdir", i);
214                                 ltrace_mark(3, mark_buf);
215                         }
216
217                         do_mkdir(pathname);
218                         do_stat(pathname);
219                         do_chdir(pathname);
220                 }
221         }
222
223         /* Stat through directory tree with fullpaths */
224
225         if (opt_trace) {
226                 snprintf(mark_buf, PATH_MAX, "Walk Directory Tree");
227                 ltrace_mark(2, mark_buf);
228         }
229
230         do_chdir(base_pathname);
231
232         strncpy(pathname, base_pathname, sizeof(pathname));
233
234         c = strlen(base_pathname);
235         for (i = 0; i < opt_depth; i++) {
236                 c += snprintf(pathname + c, sizeof(pathname) - c, "/%d", i+1);
237
238                 if (opt_trace) {
239                         snprintf(mark_buf, PATH_MAX, "stat %s", pathname);
240                         ltrace_mark(2, mark_buf);
241                 }
242
243                 do_stat(pathname);
244         }
245
246         if (opt_trace && outputfilename) {
247                     ltrace_write_file(outputfilename);
248                     ltrace_add_processnames(outputfilename);
249                     ltrace_stop();
250         }
251
252         do_chdir(base_pathname);
253
254         printf("%s (pid=%d) done.\n", pname, mypid);
255
256         return 0;
257 }