Whamcloud - gitweb
LU-3157 llite: A not locked mutex can be unlocked.
[fs/lustre-release.git] / lustre / utils / obdbarrier.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, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  *
34  * lustre/utils/obdbarrier.c
35  *
36  * Author: Eric Barton <eeb@clusterfs.com>
37  */
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <errno.h>
42 #include <string.h>
43
44 #include <liblustre.h>
45 #include "obdiolib.h"
46
47 int
48 parse_kmg (__u64 *valp, char *str)
49 {
50         __u64        val;
51         char            mod[32];
52
53         switch (sscanf (str, LPU64"%1[gGmMkK]", &val, mod))
54         {
55         default:
56                 return (-1);
57
58         case 1:
59                 *valp = val;
60                 return (0);
61
62         case 2:
63                 switch (*mod)
64                 {
65                 case 'g':
66                 case 'G':
67                         *valp = val << 30;
68                         return (0);
69
70                 case 'm':
71                 case 'M':
72                         *valp = val << 20;
73                         return (0);
74
75                 case 'k':
76                 case 'K':
77                         *valp = val << 10;
78                         return (0);
79
80                 default:
81                         *valp = val;
82                         return (0);
83                 }
84         }
85 }
86
87 void
88 usage (char *cmdname, int help)
89 {
90         char *name = strrchr (cmdname, '/');
91
92         if (name == NULL)
93                 name = cmdname;
94
95         fprintf (help ? stdout : stderr,
96                  "usage: %s -d device -s size -o offset [-i id][-n reps][-l] oid\n",
97                  name);
98 }
99
100 int
101 exponential_modulus (int i, int base)
102 {
103         int   top = base;
104         int   mod = 1;
105
106         for (;;) {
107                 if (i < top)
108                         return (i%mod == 0);
109
110                 mod = top;
111                 top *= base;
112         }
113 }
114
115 int
116 main (int argc, char **argv)
117 {
118         __u64                 bid = (((__u64)gethostid()) << 32) | getpid ();
119         int                   set_bid = 0;
120         __u64                 oid;
121         int                   setup = 0;
122         int                   device = -1;
123         int                   npeers = 0;
124         int                   reps = 1;
125         char                  hostname[128];
126         struct obdio_conn    *conn;
127         struct obdio_barrier *b;
128         char                 *end;
129         __u64                 val;
130         int                   rc;
131         int                   c;
132
133         setvbuf (stdout, NULL, _IOLBF, 0);
134         memset (hostname, 0, sizeof (hostname));
135         gethostname (hostname, sizeof (hostname));
136         hostname[sizeof(hostname) - 1] = 0;
137
138         while ((c = getopt (argc, argv, "hsi:d:n:p:")) != -1)
139                 switch (c) {
140                 case 'h':
141                         usage (argv[0], 1);
142                         return (0);
143
144                 case 'i':
145                         bid = strtoll (optarg, &end, 0);
146                         if (end == optarg || *end != 0) {
147                                 fprintf (stderr, "Can't parse id %s\n",
148                                          optarg);
149                                 return (1);
150                         }
151                         set_bid = 1;
152                         break;
153
154                 case 's':
155                         setup = 1;
156                         break;
157
158                 case 'd':
159                         device = strtol (optarg, &end, 0);
160                         if (end == optarg || *end != 0 || device < 0) {
161                                 fprintf (stderr, "Can't parse device %s\n",
162                                          optarg);
163                                 return (1);
164                         }
165                         break;
166
167                 case 'n':
168                         if (parse_kmg (&val, optarg) != 0) {
169                                 fprintf (stderr, "Can't parse reps %s\n",
170                                          optarg);
171                                 return (1);
172                         }
173                         reps = (int)val;
174                         break;
175
176                 case 'p':
177                         npeers = strtol (optarg, &end, 0);
178                         if (end == optarg || *end != 0 || npeers <= 0) {
179                                 fprintf (stderr, "Can't parse npeers %s\n",
180                                          optarg);
181                                 return (1);
182                         }
183                         break;
184
185                 default:
186                         usage (argv[0], 0);
187                         return (1);
188         }
189
190         if ((!setup && !set_bid) ||
191             npeers <= 0 ||
192             device < 0 ||
193             optind == argc) {
194                 fprintf (stderr, "%s not specified\n",
195                          (!setup && !set_bid) ? "id" :
196                          npeers <= 0 ? "npeers" :
197                          device < 0 ? "device" : "object id");
198                 return (1);
199         }
200
201         oid = strtoull (argv[optind], &end, 0);
202         if (end == argv[optind] || *end != 0) {
203                 fprintf (stderr, "Can't parse object id %s\n",
204                          argv[optind]);
205                 return (1);
206         }
207
208         conn = obdio_connect (device);
209         if (conn == NULL)
210                 return (1);
211
212         b = obdio_new_barrier (oid, bid, npeers);
213         if (b == NULL)
214                 return (1);
215
216         rc = 0;
217         if (setup) {
218                 rc = obdio_setup_barrier (conn, b);
219                 if (rc == 0)
220                         printf ("Setup barrier: -d %d -i "LPX64" -p %d -n1 "LPX64"\n",
221                                 device, bid, npeers, oid);
222         } else {
223                 for (c = 0; c < reps; c++) {
224                         rc = obdio_barrier (conn, b);
225                         if (rc != 0)
226                                 break;
227                         if (exponential_modulus (c, 10))
228                                 printf ("%s: Barrier %d\n", hostname, c);
229                 }
230         }
231
232         free(b);
233
234         obdio_disconnect(conn, 0);
235
236         return (rc == 0 ? 0 : 1);
237 }