Whamcloud - gitweb
LU-8526 tests: ensure all OSTs active for allocations
[fs/lustre-release.git] / lustre / tests / rwv.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, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 021110-1307, USA
20  *
21  * GPL HEADER END
22  */
23 /*
24  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
25  * Use is subject to license terms.
26  *
27  * Copyright (c) 2014, Intel Corporation.
28  */
29 /*
30  * This file is part of Lustre, http://www.lustre.org/
31  * Lustre is a trademark of Sun Microsystems, Inc.
32  *
33  * lustre/tests/rwv.c
34  */
35
36 #include <stdio.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <sys/uio.h>
40 #include <sys/mman.h>
41 #include <fcntl.h>
42 #include <errno.h>
43 #include <stdlib.h>
44 #include <unistd.h>
45
46 #include <lustre/lustreapi.h>
47
48 #define ACT_NONE        0
49 #define ACT_READ        1
50 #define ACT_WRITE       2
51 #define ACT_SEEK        4
52 #define ACT_READHOLE    8
53 #define ACT_VERIFY      16
54
55 void usage()
56 {
57         printf("usage: rwv -f filename <-r|-w> [-a] [-z] [-d] [-v]"
58                 "[-s offset] -n iovcnt SIZE1 SIZE2 SIZE3...\n");
59         printf("-a  append IO (O_APPEND)\n");
60         printf("-r  file read (O_RDONLY)\n");
61         printf("-w  file write (O_WRONLY)\n");
62         printf("-s  set the start pos of the read/write test\n");
63         printf("-z  test for read hitting hole\n");
64         printf("-d  create flags (O_LOV_DELAY_CREATE)\n");
65         printf("-v  verify the data content of read\n");
66 }
67
68 int data_verify(struct iovec *iov, int iovcnt, char c)
69 {
70         int i;
71
72         for (i = 0; i < iovcnt; i++) {
73                 size_t count = iov[i].iov_len;
74                 char *s = iov[i].iov_base;
75
76                 for (; count > 0; ++s, count--) {
77                         if (*s != c) {
78                                 printf("Data mismatch %x: %x\n", *s, c);
79                                 return 1;
80                         }
81                 }
82         }
83         return 0;
84 }
85
86 int main(int argc, char** argv)
87 {
88         int c;
89         int fd;
90         int rc = 0;
91         int flags = 0;
92         int iovcnt = 0;
93         int act = ACT_NONE;
94         char pad = 0xba;
95         char *end;
96         char *fname = "FILE";
97         unsigned long len = 0;
98         struct iovec *iov;
99         off64_t offset = 0;
100
101         while ((c = getopt(argc, argv, "f:n:s:rwahvdz")) != -1) {
102                 switch (c) {
103                 case 'f':
104                         fname = optarg;
105                         break;
106                 case 'n':
107                         iovcnt = strtoul(optarg, &end, 0);
108                         if (*end) {
109                                 printf("Bad iov count: %s\n", optarg);
110                                 return 1;
111                         }
112                         if (iovcnt > UIO_MAXIOV || iovcnt <= 0) {
113                                 printf("Wrong iov count\n");
114                                 return 1;
115                         }
116                         break;
117                 case 's':
118                         act |= ACT_SEEK;
119                         offset = strtoull(optarg, &end, 0);
120                         if (*end) {
121                                 printf("Bad seek offset: %s\n", optarg);
122                                 return 1;
123                         }
124                         break;
125                 case 'w':
126                         act |= ACT_WRITE;
127                         break;
128                 case 'r':
129                         act |= ACT_READ;
130                         break;
131                 case 'a':
132                         flags |= O_APPEND;
133                         break;
134                 case 'd':
135                         flags |= O_LOV_DELAY_CREATE;
136                         break;
137                 case 'z':
138                         pad = 0;
139                         act |= ACT_READHOLE;
140                         break;
141                 case 'v':
142                         act |= ACT_VERIFY;
143                         break;
144                 case 'h':
145                         usage();
146                         break;
147                 }
148         }
149
150         if (act == ACT_NONE) {
151                 usage();
152                 return 1;
153         }
154
155         if ((act & ACT_READ) &&  (act & ACT_WRITE)) {
156                 printf("Read and write test should be exclusive\n");
157                 return 1;
158         }
159
160         if (argc - optind < iovcnt) {
161                 printf("Not enough parameters for iov size\n");
162                 return 1;
163         }
164
165         iov = (struct iovec *)malloc(iovcnt * sizeof(struct iovec));
166         if (iov == NULL) {
167                 printf("No memory %s\n", strerror(errno));
168                 return 1;
169         }
170
171         for (c = 0; c < iovcnt; c++) {
172                 struct iovec *iv = &iov[c];
173
174                 iv->iov_len = strtoul(argv[optind++], &end, 0);
175                 if (*end) {
176                         printf("Error iov size\n");
177                         rc = 1;
178                         goto out;
179                 }
180                 iv->iov_base = mmap(NULL, iv->iov_len, PROT_READ | PROT_WRITE,
181                                     MAP_PRIVATE | MAP_ANON, 0, 0);
182                 if (iv->iov_base == MAP_FAILED) {
183                         printf("No memory %s\n", strerror(errno));
184                         rc = 1;
185                         goto out;
186                 }
187                 if (act & ACT_WRITE)
188                         memset(iv->iov_base, pad, iv->iov_len);
189                 len += iv->iov_len;
190         }
191
192         fd = open(fname, O_LARGEFILE | O_RDWR | O_CREAT | flags, 0644);
193         if (fd == -1) {
194                 printf("Cannot open %s:%s\n", fname, strerror(errno));
195                 return 1;
196         }
197
198         if ((act & ACT_SEEK) && (lseek64(fd, offset, SEEK_SET) < 0)) {
199                 printf("Cannot seek %s\n", strerror(errno));
200                 rc = 1;
201                 goto out;
202         }
203
204         if (act & ACT_WRITE) {
205                 rc = writev(fd, iov, iovcnt);
206                 if (rc != len) {
207                         printf("Write error: %s (rc = %d, len = %ld)\n",
208                                 strerror(errno), rc, len);
209                         rc = 1;
210                         goto out;
211                 }
212         } else if (act & ACT_READ) {
213                 rc = readv(fd, iov, iovcnt);
214                 if (rc != len) {
215                         printf("Read error: %s rc = %d\n", strerror(errno), rc);
216                         rc = 1;
217                         goto out;
218                 }
219
220                 /* It should return zeroed buf if the read hits hole.*/
221                 if (((act & ACT_READHOLE) || (act & ACT_VERIFY)) &&
222                     data_verify(iov, iovcnt, pad)) {
223                         rc = 1;
224                         goto out;
225                 }
226         }
227
228         rc = 0;
229 out:
230         if (iov)
231                 free(iov);
232         return rc;
233 }