Whamcloud - gitweb
- merge 0.7rc1 from b_devel to HEAD (20030612 merge point)
[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_depth = 1;
22 static int opt_mknod = 0; 
23 static int opt_verbose = 0;
24 static int opt_trace = 1;
25 static char* basepathname = 0;
26 static char mycwd[PATH_MAX];
27 static char* pname = 0;
28 static char* outputfilename = 0;
29
30 void usage()
31 {
32         fprintf(stderr, "Usage: %s --depth <d> --output <outputtracefilename>"
33                 "[--mknod] [--verbose] [--notrace] <basepath>\n", pname);
34         exit(1);
35 }
36
37 int do_mkdir(char* path)
38 {
39         int rc = mkdir(path, 0755);
40         if (rc!=0) 
41                 fprintf(stderr, "mkdir(%s) failed: %s\n",
42                         path, strerror(errno));
43         if (opt_verbose)
44                 printf("mkdir %s\n", path);
45         return rc;
46 }
47
48
49 int do_mknod(char* path)
50 {
51         int rc = mknod(path, 0755, S_IFIFO);
52         if (rc!=0) 
53                 fprintf(stderr, "mkdir(%s) failed: %s\n",
54                         path, strerror(errno));
55         if (opt_verbose)
56                 printf("mknod %s\n", path);
57         return rc;
58 }
59
60 int do_chdir(char* path)
61 {
62         int rc = chdir(path);
63         if (rc!=0) 
64                 fprintf(stderr, "chdir(%s) failed: %s\n",
65                         path, strerror(errno));
66         if (opt_verbose)
67                 printf("chdir %s\n", path);
68
69         return rc;
70 }
71
72
73 int do_stat(char* path)
74 {
75         char mark_buf[PATH_MAX];
76         struct stat mystat;
77         int rc = stat(path, &mystat);
78         if (rc!=0) 
79                 fprintf(stderr, "stat(%s) failed: %s\n",
80                         path, strerror(errno));
81         if (opt_verbose)
82                 printf("stat %s = inode %lu\n", path, mystat.st_ino);
83
84         if (opt_trace) {
85                 snprintf(mark_buf, PATH_MAX, "stat %s = inode %lu", 
86                          path, mystat.st_ino);
87                 ltrace_mark(0, mark_buf);
88         }
89
90         return rc;
91 }
92
93 int main(int argc, char** argv)
94 {
95         int c, opt_index, i, mypid;
96
97         static struct option long_options[] = {
98                 {"depth", 1, 0, 0 },
99                 {"help", 0, 0, 0 },
100                 {"mknod", 0, 0, 0 },  
101                 {"verbose", 0, 0, 0 },  
102                 {"notrace", 0, 0, 0 },  
103                 {"output", 1, 0, 0 },  
104                 {0,0,0,0}
105         };
106
107         char full_pathname[PATH_MAX];
108         char rel_pathname[PATH_MAX];
109         char mark_buf[PATH_MAX];
110
111         pname = strdup(argv[0]);
112         
113         while (1) {
114                 c = getopt_long(argc, argv, "d:mhv", long_options, &opt_index);
115                 if (c == -1)
116                         break;
117                 if (c==0) {
118                         if (!strcmp(long_options[opt_index].name, "notrace")) {
119                                 opt_trace = 0;
120                                 continue;
121                         }
122                         c = long_options[opt_index].name[0];
123                 }
124                 switch (c) {
125                 case 'd': 
126                         opt_depth = atoi(optarg);
127                         if ((opt_depth == 0) || (opt_depth > 100))
128                                 usage();
129                         break;
130                 case 'm':
131                         opt_mknod = 1;
132                         break;
133                 case 'v':
134                         opt_verbose = 1;
135                         break;
136                 case 'o':
137                         outputfilename = optarg;
138                         break;
139                 case 'h':
140                 case '?': 
141                 case ':': 
142                 default:
143                         usage();
144                         break;
145                 }
146         }
147                 
148         if (optind != (argc-1)) 
149                 usage();
150
151         if (outputfilename == NULL)
152                 usage();
153
154         basepathname = argv[optind];
155         mypid = getpid();
156         
157         printf("%s(pid=%d) depth=%d mknod=%d, basepathname=%s, "
158                "trace=%d, outputfilename=%s\n",
159                pname, mypid, opt_depth, opt_mknod, basepathname, opt_trace, 
160                outputfilename);
161
162         if (!getcwd(&mycwd[0], sizeof(mycwd))) {
163                 fprintf(stderr, "%s: unable to getcwd()\n", pname);
164                 exit(1);
165         }
166
167         if (opt_trace) {
168                 ltrace_start();
169                 ltrace_clear();
170                 snprintf(mark_buf, PATH_MAX, 
171                          "Initialize - mkdir %s; chdir %s",
172                          basepathname, basepathname);
173                 ltrace_mark(2, mark_buf);
174         }
175
176         if (do_mkdir(basepathname)!=0)
177                 exit(1);
178         if (do_chdir(basepathname)!=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                 
191                 snprintf(rel_pathname, sizeof(rel_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(rel_pathname);
205                          else
206                                  do_mkdir(rel_pathname);
207                          /* Now stat it */
208                          do_stat(rel_pathname);
209                  }
210                 else {
211                         /* Not Leaf */
212
213                         if (opt_trace) {
214                                 snprintf(mark_buf, PATH_MAX, 
215                                          "Tree Level (%d) mkdir/stat/chdir",
216                                          i);
217                                 ltrace_mark(3, mark_buf);
218                         }
219                         
220                         do_mkdir(rel_pathname);
221                         do_stat(rel_pathname);
222                         do_chdir(rel_pathname);
223                 }
224         }
225         
226         /* Stat through directory tree with fullpaths */
227
228         if (opt_trace) {
229                 snprintf(mark_buf, PATH_MAX, "Walk Directory Tree");
230                 ltrace_mark(2, mark_buf);
231         }
232
233         do_chdir(basepathname);
234
235         strncpy(full_pathname, basepathname, sizeof(full_pathname));
236
237         for (i=0; i<opt_depth; i++) {
238                 snprintf(rel_pathname, sizeof(rel_pathname),"%d", i+1);
239                 strcat(full_pathname, "/");
240                 strcat(full_pathname, rel_pathname);
241
242                 if (opt_trace) {
243                         snprintf(mark_buf, PATH_MAX, "stat %s", 
244                                  full_pathname);
245                         ltrace_mark(2, mark_buf);
246                 }
247
248                 do_stat(full_pathname);
249         }
250
251         /* Cleanup */
252
253         if (opt_trace) {
254                 snprintf(mark_buf, PATH_MAX, "Cleanup");
255                 ltrace_mark(2, mark_buf);
256         }
257
258         if (opt_trace) {
259                     ltrace_write_file(outputfilename);
260                     ltrace_add_processnames(outputfilename);
261                     ltrace_stop();
262         }
263
264         do_chdir(basepathname);        
265         
266         snprintf(full_pathname, sizeof(full_pathname), 
267                  "rm -rf %s\n", basepathname);
268         if (opt_verbose) 
269                 printf("Cleanup: %s", full_pathname);
270
271         system(full_pathname);
272
273         printf("%s (pid=%d) done.\n", pname, mypid);
274         return 0;
275 }