Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / tests / statmany.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <errno.h>
6 #include <string.h>
7 #include <fcntl.h>
8 #include <getopt.h>
9 #include <unistd.h>
10 #include <time.h>
11 #include <limits.h>
12 #include <sys/ioctl.h>
13
14 #include <liblustre.h>
15 #include <lustre_lib.h>
16 #include <obd.h>
17
18 struct option longopts[] = {
19         {"ea", 0, 0, 'e'},
20         {"lookup", 0, 0, 'l'},
21         {"random", 0, 0, 'r'},
22         {"stat", 0, 0, 's'},
23         {NULL, 0, 0, 0},
24 };
25 char *shortopts = "ehlr:s0123456789";
26
27 static int usage(char *prog, FILE *out)
28 {
29         fprintf(out,
30                 "Usage: %s [-r rand_seed] {-s|-e|-l} filenamebase total_files iterations\n"
31                "-r : random seed\n"
32                "-s : regular stat() calls\n"
33                "-e : open then GET_EA ioctl\n"
34                "-l : lookup ioctl only\n", prog);
35         exit(out == stderr);
36 }
37
38 #ifndef LONG_MAX
39 #define LONG_MAX (1 << ((8 * sizeof(long)) - 1))
40 #endif
41
42 int main(int argc, char ** argv)
43 {
44         long i, c, count, iter = LONG_MAX, mode = 0, offset;
45         long int start, length = LONG_MAX, last, rc = 0;
46         char parent[4096], *t;
47         char *prog = argv[0], *base;
48         int seed = 0;
49         int fd = -1;
50
51         while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
52                 char *e;
53                 switch (c) {
54                 case 'r':
55                         seed = strtoul(optarg, &e, 0);
56                         if (*e) {
57                                 fprintf(stderr, "bad -r option %s\n", optarg);
58                                 usage(prog, stderr);
59                         }
60                         break;
61                 case 'e':
62                 case 'l':
63                 case 's':
64                         mode = c;
65                         break;
66                 case '0':
67                 case '1':
68                 case '2':
69                 case '3':
70                 case '4':
71                 case '5':
72                 case '6':
73                 case '7':
74                 case '8':
75                 case '9':
76                         if (length == LONG_MAX)
77                                 length = c - '0';
78                         else
79                                 length = length * 10 + (c - '0');
80                         break;
81                 case 'h':
82                         usage(prog, stdout);
83                 case '?':
84                         usage(prog, stderr);
85                 }
86         }
87
88         if (optind + 2 + (length == LONG_MAX) != argc) {
89                 fprintf(stderr, "missing filenamebase, total_files, or iterations\n");
90                 usage(prog, stderr);
91         }
92
93         base = argv[optind];
94         if (strlen(base) > 4080) {
95                 fprintf(stderr, "filenamebase too long\n");
96                 exit(1);
97         }
98
99         if (seed == 0) {
100                 int f = open("/dev/urandom", O_RDONLY);
101
102                 if (f < 0 || read(f, &seed, sizeof(seed)) < sizeof(seed))
103                         seed = time(0);
104                 if (f > 0)
105                         close(f);
106         }
107
108         printf("using seed %u\n", seed);
109         srand(seed);
110
111         count = strtoul(argv[optind + 1], NULL, 0);
112         if (length == LONG_MAX) {
113                 iter = strtoul(argv[optind + 2], NULL, 0);
114                 printf("running for %lu iterations\n", iter);
115         } else
116                 printf("running for %lu seconds\n", length);
117
118         start = last = time(0);
119
120         t = strrchr(base, '/');
121         if (t == NULL) {
122                 strcpy(parent, ".");
123                 offset = -1;
124         } else {
125                 strncpy(parent, base, t - base);
126                 offset = t - base + 1;
127         }
128
129         if (mode == 'l') {
130                 fd = open(parent, O_RDONLY);
131                 if (fd < 0) {
132                         printf("open(%s) error: %s\n", parent,
133                                strerror(errno));
134                         exit(errno);
135                 }
136         }
137
138         for (i = 0; i < iter && time(0) - start < length; i++) {
139                 char filename[4096];
140                 int tmp;
141
142                 tmp = random() % count;
143                 sprintf(filename, "%s%d", base, tmp);
144
145                 if (mode == 'e') {
146 #if 0
147                         fd = open(filename, O_RDWR|O_LARGEFILE);
148                         if (fd < 0) {
149                                 printf("open(%s) error: %s\n", filename,
150                                        strerror(errno));
151                                 break;
152                         }
153                         rc = ioctl(fd, LDISKFS_IOC_GETEA, NULL);
154                         if (rc < 0) {
155                                 printf("ioctl(%s) error: %s\n", filename,
156                                        strerror(errno));
157                                 break;
158                         }
159                         close(fd);
160                         break;
161 #endif
162                 } else if (mode == 's') {
163                         struct stat buf;
164
165                         rc = stat(filename, &buf);
166                         if (rc < 0) {
167                                 printf("stat(%s) error: %s\n", filename,
168                                        strerror(errno));
169                                 break;
170                         }
171                 } else if (mode == 'l') {
172                         struct obd_ioctl_data data;
173                         char rawbuf[8192];
174                         char *buf = rawbuf;
175                         int max = sizeof(rawbuf);
176
177                         memset(&data, 0, sizeof(data));
178                         data.ioc_version = OBD_IOCTL_VERSION;
179                         data.ioc_len = sizeof(data);
180                         if (offset >= 0)
181                                 data.ioc_inlbuf1 = filename + offset;
182                         else
183                                 data.ioc_inlbuf1 = filename;
184                         data.ioc_inllen1 = strlen(data.ioc_inlbuf1) + 1;
185
186                         if (obd_ioctl_pack(&data, &buf, max)) {
187                                 printf("ioctl_pack failed.\n");
188                                 break;
189                         }
190
191                         rc = ioctl(fd, IOC_MDC_LOOKUP, buf);
192                         if (rc < 0) {
193                                 printf("ioctl(%s) error: %s\n", filename,
194                                        strerror(errno));
195                                 break;
196                         }
197                 }
198                 if ((i % 10000) == 0) {
199                         printf(" - stat %lu (time %ld ; total %ld ; last %ld)\n",
200                                i, time(0), time(0) - start, time(0) - last);
201                         last = time(0);
202                 }
203         }
204
205         if (mode == 'l')
206                 close(fd);
207
208         printf("total: %lu stats in %ld seconds: %f stats/second\n", i,
209                time(0) - start, ((float)i / (time(0) - start)));
210
211         exit(rc);
212 }