Whamcloud - gitweb
land b1_5 onto HEAD
[fs/lustre-release.git] / lustre / utils / obdio.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (C) 2002 Cluster File Systems, Inc.
5  *   Author: Eric Barton <eeb@clusterfs.com>
6  *
7  *   This file is part of Lustre, http://www.lustre.org.
8  *
9  *   Lustre is free software; you can redistribute it and/or
10  *   modify it under the terms of version 2 of the GNU General Public
11  *   License as published by the Free Software Foundation.
12  *
13  *   Lustre is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with Lustre; if not, write to the Free Software
20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <string.h>
28
29 #include <liblustre.h>
30 #include "obdiolib.h"
31
32 int
33 obdio_test_fixed_extent (struct obdio_conn *conn,
34                          uint32_t myhid, uint32_t mypid,
35                          int reps, int locked, uint64_t oid,
36                          uint64_t offset, uint32_t size)
37 {
38         struct lustre_handle lh;
39         void                *space;
40         void                *buffer;
41         uint32_t            *ibuf;
42         int                  i;
43         int                  j;
44         int                  rc = 0;
45
46         space = obdio_alloc_aligned_buffer (&buffer, size);
47         if (space == NULL) {
48                 fprintf (stderr, "Can't allocate buffer size %d\n", size);
49                 return (-1);
50         }
51
52         for (i = 0; i < reps; i++) {
53                 ibuf = (uint32_t *) buffer;
54                 for (j = 0; j < size / (4 * sizeof (*ibuf)); j++) {
55                         ibuf[0] = myhid;
56                         ibuf[1] = mypid;
57                         ibuf[2] = i;
58                         ibuf[3] = j;
59                         ibuf += 4;
60                 }
61
62                 if (locked) {
63                         rc = obdio_enqueue(conn, oid, LCK_PW, offset, size,&lh);
64                         if (rc != 0) {
65                                 fprintf(stderr, "Error on enqueue "LPX64" @ "
66                                         LPU64" for %u: %s\n",
67                                         oid, offset, size, strerror (errno));
68                                 goto out;
69                         }
70                 }
71
72                 rc = obdio_pwrite (conn, oid, buffer, size, offset);
73                 if (rc != 0) {
74                         fprintf(stderr, "Error writing "LPX64" @ "LPU64
75                                 " for %u: %s\n",
76                                 oid, offset, size, strerror (errno));
77                         if (locked)
78                                 obdio_cancel (conn, &lh);
79                         rc = -1;
80                         goto out;
81                 }
82
83                 memset (buffer, 0xbb, size);
84
85                 rc = obdio_pread (conn, oid, buffer, size, offset);
86                 if (rc != 0) {
87                         fprintf(stderr, "Error reading "LPX64" @ "LPU64
88                                 " for %u: %s\n",
89                                 oid, offset, size, strerror (errno));
90                         if (locked)
91                                 obdio_cancel (conn, &lh);
92                         rc = -1;
93                         goto out;
94                 }
95
96                 if (locked) {
97                         rc = obdio_cancel (conn, &lh);
98                         if (rc != 0) {
99                                 fprintf(stderr, "Error on cancel "LPX64" @ "
100                                         LPU64" for %u: %s\n",
101                                         oid, offset, size, strerror (errno));
102                                 rc = -1;
103                                 goto out;
104                         }
105                 }
106
107                 ibuf = (uint32_t *) buffer;
108                 for (j = 0; j < size / (4 * sizeof (*ibuf)); j++) {
109                         if (ibuf[0] != myhid ||
110                             ibuf[1] != mypid ||
111                             ibuf[2] != i ||
112                             ibuf[3] != j) {
113                                 fprintf(stderr, "Error checking "LPX64" @ "
114                                         LPU64" for %u, chunk %d\n",
115                                         oid, offset, size, j);
116                                 fprintf(stderr, "Expected [%x,%x,%x,%x], "
117                                         "got [%x,%x,%x,%x]\n",
118                                         myhid, mypid, i, j,
119                                         ibuf[0], ibuf[1], ibuf[2], ibuf[3]);
120                                 rc = -1;
121                                 goto out;
122                         }
123                         ibuf += 4;
124                 }
125         }
126  out:
127         free (space);
128         return (rc);
129 }
130
131 int
132 parse_kmg (uint64_t *valp, char *str)
133 {
134         uint64_t        val;
135         char            mod[32];
136
137         switch (sscanf (str, LPU64"%1[gGmMkK]", &val, mod))
138         {
139         default:
140                 return (-1);
141
142         case 1:
143                 *valp = val;
144                 return (0);
145
146         case 2:
147                 switch (*mod)
148                 {
149                 case 'g':
150                 case 'G':
151                         *valp = val << 30;
152                         return (0);
153
154                 case 'm':
155                 case 'M':
156                         *valp = val << 20;
157                         return (0);
158
159                 case 'k':
160                 case 'K':
161                         *valp = val << 10;
162                         return (0);
163
164                 default:
165                         *valp = val;
166                         return (0);
167                 }
168         }
169 }
170
171 void
172 usage (char *cmdname, int help)
173 {
174         char *name = strrchr (cmdname, '/');
175
176         if (name == NULL)
177                 name = cmdname;
178
179         fprintf (help ? stdout : stderr,
180                  "usage: %s -d device -s size -o offset [-i id][-n reps][-l] oid\n",
181                  name);
182 }
183
184 int
185 main (int argc, char **argv)
186 {
187         uint32_t           mypid = getpid ();
188         uint32_t           myhid = gethostid ();
189         uint64_t           oid;
190         uint64_t           base_offset = 0;
191         uint32_t           size = 0;
192         int                set_size = 0;
193         int                device = -1;
194         int                reps = 1;
195         int                locked = 0;
196         char              *end;
197         struct obdio_conn *conn;
198         uint64_t           val;
199         int                v1;
200         int                v2;
201         int                rc;
202         int                c;
203
204         while ((c = getopt (argc, argv, "hi:s:o:d:n:l")) != -1)
205                 switch (c) {
206                 case 'h':
207                         usage (argv[0], 1);
208                         return (0);
209
210                 case 'i':
211                         switch (sscanf (optarg, "%i.%i", &v1, &v2)) {
212                         case 1:
213                                 mypid = v1;
214                                 break;
215                         case 2:
216                                 myhid = v1;
217                                 mypid = v2;
218                                 break;
219                         default:
220                                 fprintf (stderr, "Can't parse id %s\n",
221                                          optarg);
222                                 return (1);
223                         }
224                         break;
225
226                 case 's':
227                         if (parse_kmg (&val, optarg) != 0) {
228                                 fprintf (stderr, "Can't parse size %s\n",
229                                          optarg);
230                                 return (1);
231                         }
232                         size = (uint32_t)val;
233                         set_size++;
234                         break;
235
236                 case 'o':
237                         if (parse_kmg (&val, optarg) != 0) {
238                                 fprintf (stderr, "Can't parse offset %s\n",
239                                          optarg);
240                                 return (1);
241                         }
242                         base_offset = val;
243                         break;
244
245                 case 'd':
246                         device = strtol (optarg, &end, 0);
247                         if (end == optarg || *end != 0 || device < 0) {
248                                 fprintf (stderr, "Can't parse device %s\n",
249                                          optarg);
250                                 return (1);
251                         }
252                         break;
253                 case 'n':
254                         if (parse_kmg (&val, optarg) != 0) {
255                                 fprintf (stderr, "Can't parse reps %s\n",
256                                          optarg);
257                                 return (1);
258                         }
259                         reps = (int)val;
260                         break;
261                 case 'l':
262                         locked = 1;
263                         break;
264                 default:
265                         usage (argv[0], 0);
266                         return (1);
267         }
268
269         if (!set_size ||
270             device < 0 ||
271             optind == argc) {
272                 fprintf (stderr, "No %s specified\n",
273                          !set_size ? "size" :
274                          device < 0 ? "device" : "object id");
275                 return (1);
276         }
277
278         oid = strtoull (argv[optind], &end, 0);
279         if (end == argv[optind] || *end != 0) {
280                 fprintf (stderr, "Can't parse object id %s\n",
281                          argv[optind]);
282                 return (1);
283         }
284
285         conn = obdio_connect (device);
286         if (conn == NULL)
287                 return (1);
288
289         rc = obdio_test_fixed_extent(conn, myhid, mypid, reps, locked,
290                                      oid, base_offset, size);
291
292         obdio_disconnect(conn, 0);
293
294         return (rc == 0 ? 0 : 1);
295 }
296
297