Whamcloud - gitweb
LU-1818 quota: en/disable quota enforcement via conf_param
[fs/lustre-release.git] / lustre / tests / mkdirdeep.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  *
34  * lustre/tests/mkdirdeep.c
35  *
36  * Compile with:
37  * cc -I../../lnet/include -o mkdirdeep mkdirdeep.c
38  *    -L../../lnet/linux/utils -lptlctl
39  */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <getopt.h>
44 #include <string.h>
45 #include <errno.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <fcntl.h>
49 #include <unistd.h>
50 #include <linux/limits.h>
51 #include <libcfs/lltrace.h>
52
53 static int opt_verbose = 0;
54 static int opt_trace = 0;
55
56 void usage(const char *pname)
57 {
58         fprintf(stderr, "Usage: %s --depth <d> [--output <outputtracefilename>]"
59                 " [--mknod] [--verbose] [--notrace] <basepath>\n", pname);
60         exit(1);
61 }
62
63 int do_mkdir(char *path)
64 {
65         int rc = mkdir(path, 0755);
66
67         if (rc) {
68                 fprintf(stderr, "mkdir(%s) failed: %s\n",
69                         path, strerror(errno));
70                 exit(1);
71         }
72         if (opt_verbose)
73                 printf("mkdir %s\n", path);
74
75         return rc;
76 }
77
78
79 int do_mknod(char *path)
80 {
81         int rc = mknod(path, 0755, S_IFIFO);
82
83         if (rc) {
84                 fprintf(stderr, "mkdir(%s) failed: %s\n",
85                         path, strerror(errno));
86                 exit(1);
87         }
88         if (opt_verbose)
89                 printf("mknod %s\n", path);
90
91         return rc;
92 }
93
94 int do_chdir(char* path)
95 {
96         int rc = chdir(path);
97
98         if (rc) {
99                 fprintf(stderr, "chdir(%s) failed: %s\n",
100                         path, strerror(errno));
101                 exit(1);
102         }
103         if (opt_verbose)
104                 printf("chdir %s\n", path);
105
106         return rc;
107 }
108
109 int do_stat(char *path)
110 {
111         char mark_buf[PATH_MAX + 50];
112         struct stat mystat;
113         int rc = stat(path, &mystat);
114
115         if (rc) {
116                 fprintf(stderr, "stat(%s) failed: %s\n",
117                         path, strerror(errno));
118                 exit(1);
119         }
120         if (opt_verbose)
121                 printf("stat %s = inode %lu\n", path,
122                        (unsigned long)mystat.st_ino);
123
124         if (opt_trace) {
125                 snprintf(mark_buf, PATH_MAX, "stat %s = inode %lu",
126                          path, (unsigned long)mystat.st_ino);
127                 ltrace_mark(0, mark_buf);
128         }
129
130         return rc;
131 }
132
133 int main(int argc, char** argv)
134 {
135         int c, i, mypid;
136         int opt_depth = 1;
137         int opt_mknod = 0;
138
139         static struct option long_opt[] = {
140                 {"depth", 1, 0, 'd' },
141                 {"help", 0, 0, 'h' },
142                 {"mknod", 0, 0, 'm' },
143                 {"output", 1, 0, 'o' },
144                 {"trace", 1, 0, 't' },
145                 {"verbose", 0, 0, 'v' },
146                 {0,0,0,0}
147         };
148
149         char *outputfilename = NULL;
150         char *base_pathname;
151         char pathname[PATH_MAX];
152         char mark_buf[PATH_MAX + 50];
153         char mycwd[PATH_MAX];
154         char *pname = argv[0];
155
156         while ((c = getopt_long(argc, argv, "d:mhvo:", long_opt, NULL)) != -1) {
157                 switch (c) {
158                 case 'd':
159                         opt_depth = atoi(optarg);
160                         if ((opt_depth == 0) || (opt_depth > 1100))
161                                 usage(pname);
162                         break;
163                 case 'm':
164                         opt_mknod = 1;
165                         break;
166                 case 't':
167                         opt_trace = 1;
168                         break;
169                 case 'v':
170                         opt_verbose = 1;
171                         break;
172                 case 'o':
173                         outputfilename = optarg;
174                         break;
175                 case 'h':
176                 case '?':
177                 case ':':
178                 default:
179                         usage(pname);
180                         break;
181                 }
182         }
183
184         if (optind != (argc - 1))
185                 usage(pname);
186
187         base_pathname = argv[optind];
188         mypid = getpid();
189
190         if (!getcwd(&mycwd[0], sizeof(mycwd))) {
191                 fprintf(stderr, "%s: unable to getcwd()\n", pname);
192                 exit(1);
193         }
194
195         printf("%s(pid=%d) depth=%d mknod=%d, basepathname=%s, trace=%d\n",
196                pname, mypid, opt_depth, opt_mknod, base_pathname, opt_trace);
197
198         if (outputfilename)
199                 printf("outputfilename=%s\n", outputfilename);
200
201         if (opt_trace) {
202                 ltrace_start();
203                 ltrace_clear();
204                 snprintf(mark_buf, PATH_MAX, "Initialize - mkdir %s; chdir %s",
205                          base_pathname, base_pathname);
206                 ltrace_mark(2, mark_buf);
207         }
208
209         if (do_mkdir(base_pathname)!=0)
210                 exit(1);
211         if (do_chdir(base_pathname)!=0)
212                 exit(1);
213
214         /* Create directory tree with depth level of subdirectories */
215
216         if (opt_trace) {
217                 snprintf(mark_buf, PATH_MAX,
218                          "Create Directory Tree (depth %d)", opt_depth);
219                 ltrace_mark(2, mark_buf);
220         }
221
222         for (i = 0; i < opt_depth; i++) {
223                 snprintf(pathname, sizeof(pathname), "%d", i + 1);
224
225                 if (i == (opt_depth - 1)) {
226                         /* Last Iteration */
227
228                         if (opt_trace) {
229                                 snprintf(mark_buf, PATH_MAX,
230                                          "Tree Leaf (%d) %s/stat", i,
231                                          (opt_mknod ? "mknod" : "mkdir"));
232                                 ltrace_mark(3, mark_buf);
233                         }
234
235                         if (opt_mknod)
236                                 do_mknod(pathname);
237                         else
238                                 do_mkdir(pathname);
239                         /* Now stat it */
240                         do_stat(pathname);
241                 } else {
242                         /* Not Leaf */
243
244                         if (opt_trace) {
245                                 snprintf(mark_buf, sizeof(mark_buf),
246                                          "Tree Level (%d) mkdir/stat/chdir", i);
247                                 ltrace_mark(3, mark_buf);
248                         }
249
250                         do_mkdir(pathname);
251                         do_stat(pathname);
252                         do_chdir(pathname);
253                 }
254         }
255
256         /* Stat through directory tree with fullpaths */
257
258         if (opt_trace) {
259                 snprintf(mark_buf, PATH_MAX, "Walk Directory Tree");
260                 ltrace_mark(2, mark_buf);
261         }
262
263         do_chdir(base_pathname);
264
265         strncpy(pathname, base_pathname, sizeof(pathname));
266
267         c = strlen(base_pathname);
268         for (i = 0; i < opt_depth; i++) {
269                 c += snprintf(pathname + c, sizeof(pathname) - c, "/%d", i+1);
270
271                 if (opt_trace) {
272                         snprintf(mark_buf, PATH_MAX, "stat %s", pathname);
273                         ltrace_mark(2, mark_buf);
274                 }
275
276                 do_stat(pathname);
277         }
278
279         if (opt_trace && outputfilename) {
280                     ltrace_write_file(outputfilename);
281                     ltrace_add_processnames(outputfilename);
282                     ltrace_stop();
283         }
284
285         do_chdir(base_pathname);
286
287         printf("%s (pid=%d) done.\n", pname, mypid);
288
289         return 0;
290 }