Whamcloud - gitweb
land b1_5 onto HEAD
[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 #define POP_ARG() (pop_arg(argc, argv))
65 #define min(a,b) ((a)>(b)?(b):(a))
66
67 int main(int argc, char **argv)
68 {
69         char *fname, *commands;
70         const char *newfile;
71         struct stat st;
72         size_t mmap_len = 0, i;
73         unsigned char *mmap_ptr = NULL, junk = 0;
74         int rc, len, fd = -1;
75
76         if (argc < 3) {
77                 fprintf(stderr, usage, argv[0]);
78                 exit(1);
79         }
80
81         signal(SIGUSR1, usr1_handler);
82
83         fname = argv[1];
84
85         for (commands = argv[2]; *commands; commands++) {
86                 switch (*commands) {
87                 case '_':
88                         if (usr1_received == 0)
89                                 pause();
90                         usr1_received = 0;
91                         signal(SIGUSR1, usr1_handler);
92                         break;
93                 case 'c':
94                         if (close(fd) == -1) {
95                                 perror("close");
96                                 exit(1);
97                         }
98                         fd = -1;
99                         break;
100                 case 'd':
101                         if (mkdir(fname, 0755) == -1) {
102                                 perror("mkdir(0755)");
103                                 exit(1);
104                         }
105                         break;
106                 case 'D':
107                         fd = open(fname, O_DIRECTORY);
108                         if (fd == -1) {
109                                 perror("open(O_DIRECTORY)");
110                                 exit(1);
111                         }
112                         break;
113                 case 'l':
114                         newfile = POP_ARG();
115                         if (!newfile)
116                                 newfile = fname;
117                         if (symlink(fname, newfile)) {
118                                 perror("symlink()");
119                                 exit(1);
120                         }
121                         break;
122                 case 'L':
123                         newfile = POP_ARG();
124                         if (!newfile)
125                                 newfile = fname;
126                         if (link(fname, newfile)) {
127                                 perror("symlink()");
128                                 exit(1);
129                         }
130                         break;
131                 case 'm':
132                         if (mknod(fname, S_IFREG | 0644, 0) == -1) {
133                                 perror("mknod(S_IFREG|0644, 0)");
134                                 exit(1);
135                         }
136                         break;
137                 case 'M':
138                         mmap_len = st.st_size;
139                         mmap_ptr = mmap(NULL, mmap_len, PROT_WRITE | PROT_READ,
140                                         MAP_SHARED, fd, 0);
141                         if (mmap_ptr == MAP_FAILED) {
142                                 perror("mmap");
143                                 exit(1);
144                         }
145                         break;
146                 case 'N':
147                         newfile = POP_ARG();
148                         if (!newfile)
149                                 newfile = fname;
150                         if (rename (fname, newfile)) {
151                                 perror("rename()");
152                                 exit(1);
153                         }
154                         break;
155                 case 'O':
156                         fd = open(fname, O_CREAT|O_RDWR, 0644);
157                         if (fd == -1) {
158                                 perror("open(O_RDWR|O_CREAT)");
159                                 exit(1);
160                         }
161                         break;
162                 case 'o':
163                         fd = open(fname, O_RDONLY);
164                         if (fd == -1) {
165                                 perror("open(O_RDONLY)");
166                                 exit(1);
167                         }
168                         break;
169                 case 'r': 
170                         len = atoi(commands+1);
171                         if (len <= 0)
172                                 len = 1;
173                         while(len > 0) {
174                                 if (read(fd, &buf,
175                                          min(len,sizeof(buf))) == -1) {
176                                         perror("read");
177                                         exit(1);
178                                 }
179                                 len -= sizeof(buf);
180                         }
181                         break;
182                 case 'S':
183                         if (fstat(fd, &st) == -1) {
184                                 perror("fstat");
185                                 exit(1);
186                         }
187                         break;
188                 case 'R':
189                         for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
190                                 junk += mmap_ptr[i];
191                         break;
192                 case 's':
193                         if (stat(fname, &st) == -1) {
194                                 perror("stat");
195                                 exit(1);
196                         }
197                         break;
198                 case 't':
199                         if (fchmod(fd, 0) == -1) {
200                                 perror("fchmod");
201                                 exit(1);
202                         }
203                         break;
204                 case 'T':
205                         len = atoi(commands+1);
206                         if (ftruncate(fd, len) == -1) {
207                                 printf("ftruncate (%d,%d)\n", fd, len);
208                                 perror("ftruncate");
209                                 exit(1);
210                         }
211                         break;
212                 case 'u':
213                         if (unlink(fname) == -1) {
214                                 perror("unlink");
215                                 exit(1);
216                         }
217                         break;
218                 case 'U':
219                         if (munmap(mmap_ptr, mmap_len)) {
220                                 perror("munmap");
221                                 exit(1);
222                         }
223                         break;
224                 case 'w': 
225                         len = atoi(commands+1);
226                         if (len <= 0)
227                                 len = 1;
228                         while(len > 0) {
229                                 if ((rc = write(fd, buf, 
230                                                 min(len, sizeof(buf))))
231                                     == -1) {
232                                         perror("write");
233                                         exit(1);
234                                 }
235                                 len -= sizeof(buf);
236                         }
237                         break;
238                 case 'W':
239                         for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
240                                 mmap_ptr[i] += junk++;
241                         break;
242                 case 'y':
243                         if (fsync(fd) == -1) {
244                                 perror("fsync");
245                                 exit(1);
246                         }
247                         break;
248                 case 'Y':
249                         if (fdatasync(fd) == -1) {
250                                 perror("fdatasync");
251                                 exit(1);
252                         }
253                 case 'z':
254                         len = atoi(commands+1);
255                         if (lseek(fd, len, SEEK_SET) == -1) {
256                                 perror("lseek");
257                                 exit(1);
258                         }
259                         break;
260                 case '0':
261                 case '1':
262                 case '2':
263                 case '3':
264                 case '4':
265                 case '5':
266                 case '6':
267                 case '7':
268                 case '8':
269                 case '9':
270                         break;
271                 default:
272                         fprintf(stderr, "unknown command \"%c\"\n", *commands);
273                         fprintf(stderr, usage, argv[0]);
274                         exit(1);
275                 }
276         }
277
278         return 0;
279 }