Whamcloud - gitweb
3363824c09f899a0636e0e97ee49ea0b3756ed6b
[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  *  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 parse_kmg (uint64_t *valp, char *str)
34 {
35         uint64_t        val;
36         char            mod[32];
37
38         switch (sscanf (str, LPU64"%1[gGmMkK]", &val, mod))
39         {
40         default:
41                 return (-1);
42
43         case 1:
44                 *valp = val;
45                 return (0);
46
47         case 2:
48                 switch (*mod)
49                 {
50                 case 'g':
51                 case 'G':
52                         *valp = val << 30;
53                         return (0);
54
55                 case 'm':
56                 case 'M':
57                         *valp = val << 20;
58                         return (0);
59
60                 case 'k':
61                 case 'K':
62                         *valp = val << 10;
63                         return (0);
64
65                 default:
66                         *valp = val;
67                         return (0);
68                 }
69         }
70 }
71
72 void
73 usage (char *cmdname, int help) 
74 {
75         char *name = strrchr (cmdname, '/');
76         
77         if (name == NULL)
78                 name = cmdname;
79         
80         fprintf (help ? stdout : stderr,
81                  "usage: %s -d device -s size -o offset [-i id][-n reps][-l] oid\n",
82                  name);
83 }
84
85 int
86 exponential_modulus (int i, int base)
87 {
88         int   top = base;
89         int   mod = 1;
90         
91         for (;;) {
92                 if (i < top)
93                         return (i%mod == 0);
94                 
95                 mod = top;
96                 top *= base;
97         }
98 }
99
100 int
101 main (int argc, char **argv) 
102 {
103         uint64_t              bid = (((uint64_t)gethostid()) << 32) | getpid ();
104         int                   set_bid = 0;
105         uint64_t              oid;
106         int                   setup = 0;
107         int                   device = -1;
108         int                   npeers = 0;
109         int                   reps = 1;
110         char                  hostname[128];
111         struct obdio_conn    *conn;
112         struct obdio_barrier *b;
113         char                 *end;
114         uint64_t              val;
115         int                   rc;
116         int                   c;
117
118         setvbuf (stdout, NULL, _IOLBF, 0);
119         memset (hostname, 0, sizeof (hostname));
120         gethostname (hostname, sizeof (hostname));
121         hostname[sizeof(hostname) - 1] = 0;
122         
123         while ((c = getopt (argc, argv, "hsi:d:n:p:")) != -1)
124                 switch (c) {
125                 case 'h':
126                         usage (argv[0], 1);
127                         return (0);
128                         
129                 case 'i':
130                         bid = strtoll (optarg, &end, 0);
131                         if (end == optarg || *end != 0) {
132                                 fprintf (stderr, "Can't parse id %s\n",
133                                          optarg);
134                                 return (1);
135                         }
136                         set_bid = 1;
137                         break;
138                         
139                 case 's':
140                         setup = 1;
141                         break;
142                         
143                 case 'd':
144                         device = strtol (optarg, &end, 0);
145                         if (end == optarg || *end != 0 || device < 0) {
146                                 fprintf (stderr, "Can't parse device %s\n",
147                                          optarg);
148                                 return (1);
149                         }
150                         break;
151
152                 case 'n':
153                         if (parse_kmg (&val, optarg) != 0) {
154                                 fprintf (stderr, "Can't parse reps %s\n",
155                                          optarg);
156                                 return (1);
157                         }
158                         reps = (int)val;
159                         break;
160
161                 case 'p':
162                         npeers = strtol (optarg, &end, 0);
163                         if (end == optarg || *end != 0 || npeers <= 0) {
164                                 fprintf (stderr, "Can't parse npeers %s\n",
165                                          optarg);
166                                 return (1);
167                         }
168                         break;
169
170                 default:
171                         usage (argv[0], 0);
172                         return (1);
173         }
174
175         if ((!setup && !set_bid) ||
176             npeers <= 0 ||
177             device < 0 ||
178             optind == argc) {
179                 fprintf (stderr, "%s not specified\n",
180                          (!setup && !set_bid) ? "id" :
181                          npeers <= 0 ? "npeers" :
182                          device < 0 ? "device" : "object id");
183                 return (1);
184         }
185         
186         oid = strtoull (argv[optind], &end, 0);
187         if (end == argv[optind] || *end != 0) {
188                 fprintf (stderr, "Can't parse object id %s\n",
189                          argv[optind]);
190                 return (1);
191         }
192         
193         conn = obdio_connect (device);
194         if (conn == NULL)
195                 return (1);
196
197         b = obdio_new_barrier (oid, bid, npeers);
198         if (b == NULL)
199                 return (1);
200
201         rc = 0;
202         if (setup) {
203                 rc = obdio_setup_barrier (conn, b);
204                 if (rc == 0)
205                         printf ("Setup barrier: -d %d -i "LPX64" -p %d -n1 "LPX64"\n",
206                                 device, bid, npeers, oid);
207         } else {
208                 for (c = 0; c < reps; c++) {
209                         rc = obdio_barrier (conn, b);
210                         if (rc != 0)
211                                 break;
212                         if (exponential_modulus (c, 10))
213                                 printf ("%s: Barrier %d\n", hostname, c);
214                 }
215         }
216
217         free (b);
218         
219         obdio_disconnect (conn);
220
221         return (rc == 0 ? 0 : 1);
222 }
223
224