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