Whamcloud - gitweb
corrected an error made in setepall in test-framework.sh, which affects
[fs/lustre-release.git] / lustre / tests / multiop.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  */
4 #define _GNU_SOURCE /* pull in O_DIRECTORY in bits/fcntl.h */
5 #include <stdio.h>
6 #include <fcntl.h>
7 #include <string.h>
8 #include <errno.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <sys/mman.h>
12 #include <signal.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15
16 #define T1 "write data before unlink\n"
17 #define T2 "write data after unlink\n"
18 char buf[] = "yabba dabba doo, I'm coming for you, I live in a shoe, I don't know what to do.\n'Bigger, bigger,and bigger yet!' cried the Creator.  'You are not yet substantial enough for my boundless intents!'  And ever greater and greater the object became, until all was lost 'neath its momentus bulk.\n";
19
20 char usage[] = 
21 "Usage: %s filename command-sequence\n"
22 "    command-sequence items:\n"
23 "        c  close\n"
24 "        d  mkdir\n"
25 "        D  open(O_DIRECTORY)\n"
26 "        L  link\n"
27 "        l  symlink\n"
28 "        m  mknod\n"
29 "        M  rw mmap to EOF (must open and stat prior)\n"
30 "        N  rename\n"
31 "        o  open(O_RDONLY)\n"
32 "        O  open(O_CREAT|O_RDWR)\n"
33 "        r[num] read [optional length]\n"
34 "        R  reference entire mmap-ed region\n"
35 "        s  stat\n"
36 "        S  fstat\n"
37 "        t  fchmod\n"
38 "        T[num] ftruncate [optional position, default 0]\n"
39 "        u  unlink\n"
40 "        U  munmap\n"
41 "        w[num] write optional length\n"
42 "        W  write entire mmap-ed region\n"
43 "        y  fsync\n"
44 "        Y  fdatasync\n"
45 "        z[num] seek [optional position, default 0]\n"
46 "        _  wait for signal\n";
47
48 static int usr1_received;
49 void usr1_handler(int unused)
50 {
51         usr1_received = 1;
52 }
53
54 static const char *
55 pop_arg(int argc, char *argv[])
56 {
57         static int cur_arg = 3;
58
59         if (cur_arg >= argc)
60                 return NULL;
61
62         return argv[cur_arg++];
63 }
64
65 struct flag_mapping {
66        const char *string;
67        const int  flag;
68 } flag_table[] = {
69        {"O_RDONLY", O_RDONLY},
70        {"O_WRONLY", O_WRONLY},
71        {"O_RDWR", O_RDWR},
72        {"O_CREAT", O_CREAT},
73        {"O_EXCL", O_EXCL},
74        {"O_NOCTTY", O_NOCTTY},
75        {"O_TRUNC", O_TRUNC},
76        {"O_APPEND", O_APPEND},
77        {"O_NONBLOCK", O_NONBLOCK},
78        {"O_NDELAY", O_NDELAY},
79        {"O_SYNC", O_SYNC},
80 #ifdef O_DIRECT
81        {"O_DIRECT", O_DIRECT},
82 #endif
83        {"O_LARGEFILE", O_LARGEFILE},
84        {"O_DIRECTORY", O_DIRECTORY},
85        {"O_NOFOLLOW", O_NOFOLLOW},
86        {"", -1}
87 };
88
89 int get_flags(char *data, int *rflags)
90 {
91         char *cloned_flags;
92         char *tmp;
93         int flag_set = 0;
94         int flags = 0;
95         int size = 0;
96
97         cloned_flags = strdup(data);
98         if (cloned_flags == NULL) {
99                 fprintf(stderr, "Insufficient memory.\n");
100                 exit(-1);
101         }
102
103         for (tmp = strtok(cloned_flags, ":"); tmp;
104              tmp = strtok(NULL, ":")) {
105                 int i;
106
107                 size = tmp - cloned_flags;
108                 for (i = 0; flag_table[i].flag != -1; i++) {
109                         if (!strcmp(tmp, flag_table[i].string)){
110                                 flags |= flag_table[i].flag;
111                                 size += strlen(flag_table[i].string);
112                                 flag_set = 1;
113                                 break;
114                         }
115                 }
116         }
117         free(cloned_flags);
118
119         if (!flag_set) {
120                 *rflags = O_RDONLY;
121                 return 0;
122         }
123
124         *rflags = flags;
125         return size;
126 }
127
128 #define POP_ARG() (pop_arg(argc, argv))
129 #define min(a,b) ((a)>(b)?(b):(a))
130
131 int main(int argc, char **argv)
132 {
133         char *fname, *commands;
134         const char *newfile;
135         struct stat st;
136         size_t mmap_len = 0, i;
137         unsigned char *mmap_ptr = NULL, junk = 0;
138         int rc, len, fd = -1;
139         int flags;
140         int save_errno;
141
142         if (argc < 3) {
143                 fprintf(stderr, usage, argv[0]);
144                 exit(1);
145         }
146
147         signal(SIGUSR1, usr1_handler);
148
149         fname = argv[1];
150
151         for (commands = argv[2]; *commands; commands++) {
152                 switch (*commands) {
153                 case '_':
154                         if (usr1_received == 0)
155                                 pause();
156                         usr1_received = 0;
157                         signal(SIGUSR1, usr1_handler);
158                         break;
159                 case 'c':
160                         if (close(fd) == -1) {
161                                 save_errno = errno;
162                                 perror("close");
163                                 exit(save_errno);
164                         }
165                         fd = -1;
166                         break;
167                 case 'd':
168                         if (mkdir(fname, 0755) == -1) {
169                                 save_errno = errno;
170                                 perror("mkdir(0755)");
171                                 exit(save_errno);
172                         }
173                         break;
174                 case 'D':
175                         fd = open(fname, O_DIRECTORY);
176                         if (fd == -1) {
177                                 save_errno = errno;
178                                 perror("open(O_DIRECTORY)");
179                                 exit(save_errno);
180                         }
181                         break;
182                 case 'l':
183                         newfile = POP_ARG();
184                         if (!newfile)
185                                 newfile = fname;
186                         if (symlink(fname, newfile)) {
187                                 save_errno = errno;
188                                 perror("symlink()");
189                                 exit(save_errno);
190                         }
191                         break;
192                 case 'L':
193                         newfile = POP_ARG();
194                         if (!newfile)
195                                 newfile = fname;
196                         if (link(fname, newfile)) {
197                                 save_errno = errno;
198                                 perror("symlink()");
199                                 exit(save_errno);
200                         }
201                         break;
202                 case 'm':
203                         if (mknod(fname, S_IFREG | 0644, 0) == -1) {
204                                 save_errno = errno;
205                                 perror("mknod(S_IFREG|0644, 0)");
206                                 exit(save_errno);
207                         }
208                         break;
209                 case 'M':
210                         mmap_len = st.st_size;
211                         mmap_ptr = mmap(NULL, mmap_len, PROT_WRITE | PROT_READ,
212                                         MAP_SHARED, fd, 0);
213                         if (mmap_ptr == MAP_FAILED) {
214                                 save_errno = errno;
215                                 perror("mmap");
216                                 exit(save_errno);
217                         }
218                         break;
219                 case 'N':
220                         newfile = POP_ARG();
221                         if (!newfile)
222                                 newfile = fname;
223                         if (rename (fname, newfile)) {
224                                 save_errno = errno;
225                                 perror("rename()");
226                                 exit(save_errno);
227                         }
228                         break;
229                 case 'O':
230                         fd = open(fname, O_CREAT|O_RDWR, 0644);
231                         if (fd == -1) {
232                                 save_errno = errno;
233                                 perror("open(O_RDWR|O_CREAT)");
234                                 exit(save_errno);
235                         }
236                         break;
237                 case 'o':
238                         len = get_flags(commands+1, &flags);
239                         commands += len;
240                         fd = open(fname, flags);
241                         if (fd == -1) {
242                                 save_errno = errno;
243                                 perror("open");
244                                 exit(save_errno);
245                         }
246                         break;
247                 case 'r':
248                         len = atoi(commands+1);
249                         if (len <= 0)
250                                 len = 1;
251                         while(len > 0) {
252                                 if (read(fd, &buf,
253                                          min(len,sizeof(buf))) == -1) {
254                                         save_errno = errno;
255                                         perror("read");
256                                         exit(save_errno);
257                                 }
258                                 len -= sizeof(buf);
259                         }
260                         break;
261                 case 'S':
262                         if (fstat(fd, &st) == -1) {
263                                 save_errno = errno;
264                                 perror("fstat");
265                                 exit(save_errno);
266                         }
267                         break;
268                 case 'R':
269                         for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
270                                 junk += mmap_ptr[i];
271                         break;
272                 case 's':
273                         if (stat(fname, &st) == -1) {
274                                 save_errno = errno;
275                                 perror("stat");
276                                 exit(save_errno);
277                         }
278                         break;
279                 case 't':
280                         if (fchmod(fd, 0) == -1) {
281                                 save_errno = errno;
282                                 perror("fchmod");
283                                 exit(save_errno);
284                         }
285                         break;
286                 case 'T':
287                         len = atoi(commands+1);
288                         if (ftruncate(fd, len) == -1) {
289                                 save_errno = errno;
290                                 printf("ftruncate (%d,%d)\n", fd, len);
291                                 perror("ftruncate");
292                                 exit(save_errno);
293                         }
294                         break;
295                 case 'u':
296                         if (unlink(fname) == -1) {
297                                 save_errno = errno;
298                                 perror("unlink");
299                                 exit(save_errno);
300                         }
301                         break;
302                 case 'U':
303                         if (munmap(mmap_ptr, mmap_len)) {
304                                 save_errno = errno;
305                                 perror("munmap");
306                                 exit(save_errno);
307                         }
308                         break;
309                 case 'w':
310                         len = atoi(commands+1);
311                         if (len <= 0)
312                                 len = 1;
313                         while(len > 0) {
314                                 if ((rc = write(fd, buf,
315                                                 min(len, sizeof(buf))))
316                                     == -1) {
317                                         save_errno = errno;
318                                         perror("write");
319                                         exit(save_errno);
320                                 }
321                                 len -= sizeof(buf);
322                         }
323                         break;
324                 case 'W':
325                         for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
326                                 mmap_ptr[i] += junk++;
327                         break;
328                 case 'y':
329                         if (fsync(fd) == -1) {
330                                 save_errno = errno;
331                                 perror("fsync");
332                                 exit(save_errno);
333                         }
334                         break;
335                 case 'Y':
336                         if (fdatasync(fd) == -1) {
337                                 save_errno = errno;
338                                 perror("fdatasync");
339                                 exit(save_errno);
340                         }
341                 case 'z':
342                         len = atoi(commands+1);
343                         if (lseek(fd, len, SEEK_SET) == -1) {
344                                 save_errno = errno;
345                                 perror("lseek");
346                                 exit(save_errno);
347                         }
348                         break;
349                 case '0':
350                 case '1':
351                 case '2':
352                 case '3':
353                 case '4':
354                 case '5':
355                 case '6':
356                 case '7':
357                 case '8':
358                 case '9':
359                         break;
360                 default:
361                         fprintf(stderr, "unknown command \"%c\"\n", *commands);
362                         fprintf(stderr, usage, argv[0]);
363                         exit(1);
364                 }
365         }
366
367         return 0;
368 }