Whamcloud - gitweb
LU-7577 mdt: root inode checking for migration
[fs/lustre-release.git] / lustre / tests / createmany.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) 2002, 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
35 #include <stdio.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <sys/time.h>
39 #include <time.h>
40 #include <errno.h>
41 #include <string.h>
42 #include <fcntl.h>
43 #include <unistd.h>
44 #include <stdlib.h>
45 #include <getopt.h>
46
47 static void usage(char *prog)
48 {
49         printf("usage: %s {-o|-m|-d|-l<tgt>} [-r altpath ] filenamefmt count\n", prog);
50         printf("       %s {-o|-m|-d|-l<tgt>} [-r altpath ] filenamefmt ] -seconds\n", prog);
51         printf("       %s {-o|-m|-d|-l<tgt>} [-r altpath ] filenamefmt start count\n", prog);
52         exit(EXIT_FAILURE);
53 }
54
55 static char *get_file_name(const char *fmt, long n, int has_fmt_spec)
56 {
57         static char filename[4096];
58         int bytes;
59
60         bytes = has_fmt_spec ? snprintf(filename, 4095, fmt, n) :
61                 snprintf(filename, 4095, "%s%ld", fmt, n);
62         if (bytes >= 4095) {
63                 printf("file name too long\n");
64                 exit(EXIT_FAILURE);
65         }
66         return filename;
67 }
68
69 double now(void)
70 {
71         struct timeval tv;
72         gettimeofday(&tv, NULL);
73         return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
74 }
75
76 int main(int argc, char ** argv)
77 {
78         long i;
79         int rc = 0, do_open = 0, do_link = 0, do_mkdir = 0;
80         int do_unlink = 0, do_mknod = 0;
81         char *filename;
82         char *fmt = NULL, *fmt_unlink = NULL, *tgt = NULL;
83         double start, last;
84         long begin = 0, end = ~0UL >> 1, count = ~0UL >> 1;
85         int c, has_fmt_spec = 0, unlink_has_fmt_spec = 0;
86
87         /* Handle the last argument in form of "-seconds" */
88         if (argc > 1 && argv[argc - 1][0] == '-') {
89                 char *endp;
90
91                 argc--;
92                 end = strtol(argv[argc] + 1, &endp, 0);
93                 if (end <= 0 || *endp != '\0')
94                         usage(argv[0]);
95                 end = end + time(NULL);
96         }
97
98         while ((c = getopt(argc, argv, "omdl:r:")) != -1) {
99                 switch(c) {
100                 case 'o':
101                         do_open++;
102                         break;
103                 case 'm':
104                         do_mknod++;
105                         break;
106                 case 'd':
107                         do_mkdir++;
108                         break;
109                 case 'l':
110                         do_link++;
111                         tgt = optarg;
112                         break;
113                 case 'r':
114                         do_unlink++;
115                         fmt_unlink = optarg;
116                         break;
117                 case '?':
118                         printf("Unknown option '%c'\n", optopt);
119                         usage(argv[0]);
120                 }
121         }
122
123         if (do_open + do_mkdir + do_link + do_mknod != 1 ||
124             do_unlink > 1)
125                 usage(argv[0]);
126
127         switch (argc - optind) {
128         case 3:
129                 begin = strtol(argv[argc - 2], NULL, 0);
130         case 2:
131                 count = strtol(argv[argc - 1], NULL, 0);
132                 if (end != ~0UL >> 1)
133                         usage(argv[0]);
134         case 1:
135                 fmt = argv[optind];
136                 break;
137         default:
138                 usage(argv[0]);
139         }
140
141         start = last = now();
142
143         has_fmt_spec = strchr(fmt, '%') != NULL;
144         if (do_unlink)
145                 unlink_has_fmt_spec = strchr(fmt_unlink, '%') != NULL;
146
147         for (i = 0; i < count && time(NULL) < end; i++, begin++) {
148                 filename = get_file_name(fmt, begin, has_fmt_spec);
149                 if (do_open) {
150                         int fd = open(filename, O_CREAT|O_RDWR, 0644);
151                         if (fd < 0) {
152                                 printf("open(%s) error: %s\n", filename,
153                                        strerror(errno));
154                                 rc = errno;
155                                 break;
156                         }
157                         close(fd);
158                 } else if (do_link) {
159                         rc = link(tgt, filename);
160                         if (rc) {
161                                 printf("link(%s, %s) error: %s\n",
162                                        tgt, filename, strerror(errno));
163                                 rc = errno;
164                                 break;
165                         }
166                 } else if (do_mkdir) {
167                         rc = mkdir(filename, 0755);
168                         if (rc) {
169                                 printf("mkdir(%s) error: %s\n",
170                                        filename, strerror(errno));
171                                 rc = errno;
172                                 break;
173                         }
174                 } else {
175                         rc = mknod(filename, S_IFREG| 0444, 0);
176                         if (rc) {
177                                 printf("mknod(%s) error: %s\n",
178                                        filename, strerror(errno));
179                                 rc = errno;
180                                 break;
181                         }
182                 }
183                 if (do_unlink) {
184                         filename = get_file_name(fmt_unlink, begin,
185                                       unlink_has_fmt_spec);
186                         rc = do_mkdir ? rmdir(filename) : unlink(filename);
187                         if (rc) {
188                                 printf("unlink(%s) error: %s\n",
189                                        filename, strerror(errno));
190                                 rc = errno;
191                                 break;
192                         }
193                 }
194
195                 if (i && (i % 10000) == 0) {
196                         printf(" - created %ld (time %.2f total %.2f last %.2f)"
197                                "\n", i, now(), now() - start, now() - last);
198                         last = now();
199                 }
200         }
201         printf("total: %ld creates%s in %.2f seconds: %.2f creates/second\n", i,
202                do_unlink ? "/deletions" : "",
203                now() - start, ((double)i / (now() - start)));
204
205         return rc;
206 }