Whamcloud - gitweb
b=21932 disable some tests on NFSCLIENT
[fs/lustre-release.git] / lustre / tests / rwv.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  */
4
5 #include <stdio.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <sys/uio.h>
9 #include <sys/mman.h>
10 #include <fcntl.h>
11 #include <errno.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14
15 #include <liblustre.h>
16 #include <lnet/lnetctl.h>
17 #include <obd.h>
18 #include <lustre_lib.h>
19 #include <obd_lov.h>
20 #include <lustre/liblustreapi.h>
21
22 #define ACT_NONE        0
23 #define ACT_READ        1
24 #define ACT_WRITE       2
25 #define ACT_SEEK        4
26 #define ACT_READHOLE    8
27 #define ACT_VERIFY      16
28
29 void usage()
30 {
31         printf("usage: rwv -f filename <-r|-w> [-a] [-z] [-d] [-v]"
32                 "[-s offset] -n iovcnt SIZE1 SIZE2 SIZE3...\n");
33         printf("-a  append IO (O_APPEND)\n");
34         printf("-r  file read (O_RDONLY)\n");
35         printf("-w  file write (O_WRONLY)\n");
36         printf("-s  set the start pos of the read/write test\n");
37         printf("-z  test for read hitting hole\n");
38         printf("-d  create flags (O_LOV_DELAY_CREATE)\n");
39         printf("-v  verify the data content of read\n");
40 }
41
42 int data_verify(struct iovec *iov, int iovcnt, char c)
43 {
44         int i;
45
46         for (i = 0; i < iovcnt; i++) {
47                 size_t count = iov[i].iov_len;
48                 char *s = iov[i].iov_base;
49
50                 for (; count > 0; ++s, count--) {
51                         if (*s != c) {
52                                 printf("Data mismatch %x: %x\n", *s, c);
53                                 return 1;
54                         }
55                 }
56         }
57         return 0;
58 }
59
60 int main(int argc, char** argv)
61 {
62         int c;
63         int fd;
64         int rc = 0;
65         int flags = 0;
66         int iovcnt = 0;
67         int act = ACT_NONE;
68         char pad = 0xba;
69         char *end;
70         char *fname = "FILE";
71         unsigned long len = 0;
72         struct iovec *iov;
73         off64_t offset = 0;
74
75         while ((c = getopt(argc, argv, "f:n:s:rwahvdz")) != -1) {
76                 switch (c) {
77                 case 'f':
78                         fname = optarg;
79                         break;
80                 case 'n':
81                         iovcnt = strtoul(optarg, &end, 0);
82                         if (*end) {
83                                 printf("Bad iov count: %s\n", optarg);
84                                 return 1;
85                         }
86                         if (iovcnt > UIO_MAXIOV || iovcnt <= 0) {
87                                 printf("Wrong iov count\n");
88                                 return 1;
89                         }
90                         break;
91                 case 's':
92                         act |= ACT_SEEK;
93                         offset = strtoull(optarg, &end, 0);
94                         if (*end) {
95                                 printf("Bad seek offset: %s\n", optarg);
96                                 return 1;
97                         }
98                         break;
99                 case 'w':
100                         act |= ACT_WRITE;
101                         break;
102                 case 'r':
103                         act |= ACT_READ;
104                         break;
105                 case 'a':
106                         flags |= O_APPEND;
107                         break;
108                 case 'd':
109                         flags |= O_LOV_DELAY_CREATE;
110                         break;
111                 case 'z':
112                         pad = 0;
113                         act |= ACT_READHOLE;
114                         break;
115                 case 'v':
116                         act |= ACT_VERIFY;
117                         break;
118                 case 'h':
119                         usage();
120                         break;
121                 }
122         }
123
124         if (act == ACT_NONE) {
125                 usage();
126                 return 1;
127         }
128
129         if ((act & ACT_READ) &&  (act & ACT_WRITE)) {
130                 printf("Read and write test should be exclusive\n");
131                 return 1;
132         }
133
134         if (argc - optind < iovcnt) {
135                 printf("Not enough parameters for iov size\n");
136                 return 1;
137         }
138
139         iov = (struct iovec *)malloc(iovcnt * sizeof(struct iovec));
140         if (iov == NULL) {
141                 printf("No memory %s\n", strerror(errno));
142                 return 1;
143         }
144
145         for (c = 0; c < iovcnt; c++) {
146                 struct iovec *iv = &iov[c];
147
148                 iv->iov_len = strtoul(argv[optind++], &end, 0);
149                 if (*end) {
150                         printf("Error iov size\n");
151                         GOTO(out, rc = 1);
152                 }
153                 iv->iov_base = mmap(NULL, iv->iov_len, PROT_READ | PROT_WRITE,
154                                     MAP_PRIVATE | MAP_ANON, 0, 0);
155                 if (iv->iov_base == MAP_FAILED) {
156                         printf("No memory %s\n", strerror(errno));
157                         GOTO(out, rc = 1);
158                 }
159                 if (act & ACT_WRITE)
160                         memset(iv->iov_base, pad, iv->iov_len);
161                 len += iv->iov_len;
162         }
163
164         fd = open(fname, O_LARGEFILE | O_RDWR | O_CREAT | flags, 0644);
165         if (fd == -1) {
166                 printf("Cannot open %s:%s\n", fname, strerror(errno));
167                 return 1;
168         }
169
170         if ((act & ACT_SEEK) && (lseek64(fd, offset, SEEK_SET) < 0)) {
171                 printf("Cannot seek %s\n", strerror(errno));
172                 GOTO(out, rc == 1);
173         }
174
175         if (act & ACT_WRITE) {
176                 rc = writev(fd, iov, iovcnt);
177                 if (rc != len) {
178                         printf("Write error: %s (rc = %d, len = %ld)\n",
179                                 strerror(errno), rc, len);
180                         GOTO(out, rc = 1);
181                 }
182         } else if (act & ACT_READ) {
183                 rc = readv(fd, iov, iovcnt);
184                 if (rc != len) {
185                         printf("Read error: %s rc = %d\n", strerror(errno), rc);
186                         GOTO(out, rc = 1);
187                 }
188
189                 /* It should return zeroed buf if the read hits hole.*/
190                 if (((act & ACT_READHOLE) || (act & ACT_VERIFY)) &&
191                     data_verify(iov, iovcnt, pad))
192                         GOTO(out, rc = 1);
193         }
194
195         rc = 0;
196 out:
197         if (iov)
198                 free(iov);
199         return rc;
200 }