Whamcloud - gitweb
- track offset for debugging
[fs/lustre-release.git] / lustre / utils / obdctl.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: Peter J. Braam <braam@clusterfs.com>
6  *   Author: Phil Schwan <phil@clusterfs.com>
7  *
8  *   This file is part of Lustre, http://www.lustre.org.
9  *
10  *   Lustre is free software; you can redistribute it and/or
11  *   modify it under the terms of version 2 of the GNU General Public
12  *   License as published by the Free Software Foundation.
13  *
14  *   Lustre is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *   GNU General Public License for more details.
18  *
19  *   You should have received a copy of the GNU General Public License
20  *   along with Lustre; if not, write to the Free Software
21  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  */
24
25 #include <stdlib.h>
26 #include <sys/ioctl.h>
27 #include <fcntl.h>
28 #include <sys/socket.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <stdio.h>
32 #include <signal.h>
33 #define printk printf
34 #include <linux/lustre_lib.h>
35 #include <linux/lustre_idl.h>
36 #include <unistd.h>
37 #include <sys/un.h>
38 #include <sys/time.h>
39 #include <netinet/in.h>
40 #include <errno.h>
41 #include <string.h>
42 #include <linux/module.h>
43
44 #define __KERNEL__
45 #include <linux/list.h>
46 #undef __KERNEL__
47
48 #include "parser.h"
49 #include <stdio.h>
50
51 int fd = -1;
52 int connid = -1;
53 char rawbuf[8192];
54 char *buf = rawbuf;
55 int max = 8192;
56
57 #define IOCINIT(data) do { memset(&data, 0, sizeof(data)); data.ioc_version = OBD_IOCTL_VERSION; data.ioc_conn1 = connid; data.ioc_len = sizeof(data); if (fd < 0) { printf("No device open, use device\n"); return 1;}} while (0)
58
59 /*
60     pack "LL LL LL LL LL LL LL L L L L L L L L L a60 a60 L L L", 
61     $obdo->{id}, 0, 
62     $obdo->{gr}, 0, 
63     $obdo->{atime}, 0, 
64     $obdo->{mtime}, 0 ,
65     $obdo->{ctime}, 0, 
66     $obdo->{size}, 0, 
67     $obdo->{blocks}, 0, 
68     $obdo->{blksize},
69     $obdo->{mode},
70     $obdo->{uid},
71     $obdo->{gid},
72     $obdo->{flags},
73     $obdo->{obdflags},
74     $obdo->{nlink},     
75     $obdo->{generation},        
76     $obdo->{valid},     
77     $obdo->{inline},
78     $obdo->{obdmd},
79     0, 0, # struct list_head 
80     0;  #  struct obd_ops 
81 }
82
83 */
84
85 char * obdo_print(struct obdo *obd)
86 {
87         char buf[1024];
88
89         sprintf(buf, "id: %Ld\ngrp: %Ld\natime: %Ld\nmtime: %Ld\nctime: %Ld\nsize: %Ld\nblocks: %Ld\nblksize: %d\nmode: %o\nuid: %d\ngid: %d\nflags: %x\nobdflags: %x\nnlink: %d,\nvalid %x\n",
90                 obd->o_id,
91                 obd->o_gr,
92                 obd->o_atime,
93                 obd->o_mtime,
94                 obd->o_ctime,
95                 obd->o_size,
96                 obd->o_blocks,
97                 obd->o_blksize,
98                 obd->o_mode,
99                 obd->o_uid,
100                 obd->o_gid,
101                 obd->o_flags,
102                 obd->o_obdflags,
103                 obd->o_nlink,
104                 obd->o_valid);
105         return strdup(buf);
106 }
107
108 static int jt_device(int argc, char **argv)
109 {
110         struct obd_ioctl_data data;
111         int rc;
112
113         memset(&data, 0, sizeof(data));
114         if ( argc != 2 ) {
115                 fprintf(stderr, "Usage: %s devno\n", argv[0]);
116                 return 1;
117         }
118
119         data.ioc_dev = atoi(argv[1]);
120
121         if (obd_ioctl_pack(&data, &buf, max)) { 
122                 printf("invalid ioctl\n"); 
123                 return 1;
124         }
125
126         if (fd == -1) 
127                 fd = open("/dev/obd", O_RDWR);
128         if (fd == -1) {
129                 printf("Opening /dev/obd: %s\n", strerror(errno));
130                 return 1;
131         }
132
133         rc = ioctl(fd, OBD_IOC_DEVICE , buf);
134         if (rc < 0) {
135                 printf("Device: %x %s\n", OBD_IOC_DEVICE, strerror(errno));
136                 return 1;
137         }
138
139         return 0;
140 }
141
142 static int do_disconnect()
143 {
144         struct obd_ioctl_data data;
145         int rc;
146         IOCINIT(data);
147         
148         if (connid == -1) 
149                 return 0;
150
151         rc = ioctl(fd, OBD_IOC_DISCONNECT , &data);
152         if (rc < 0) {
153                 printf("Device: %x %s\n", OBD_IOC_DISCONNECT, strerror(errno));
154                 return 0;
155         }
156         connid = -1;
157
158         return 0;
159 }
160
161 static int jt_connect(int argc, char **argv)
162 {
163         struct obd_ioctl_data data;
164         int rc;
165
166         IOCINIT(data);
167
168         do_disconnect();
169
170         if ( argc != 1 ) {
171                 fprintf(stderr, "Usage: %s\n", argv[0]);
172                 return 1;
173         }
174
175         rc = ioctl(fd, OBD_IOC_CONNECT , &data);
176         if (rc < 0) {
177                 printf("Device: %x %s\n", OBD_IOC_CONNECT, strerror(errno));
178                 return 1;
179         }
180         connid = data.ioc_conn1;
181
182         return 0;
183 }
184
185 static int jt_disconnect(int argc, char **argv)
186 {
187         struct obd_ioctl_data data;
188         int rc;
189
190         IOCINIT(data);
191
192         if ( argc != 1 ) {
193                 fprintf(stderr, "Usage: %s\n", argv[0]);
194                 return 1;
195         }
196
197         rc = ioctl(fd, OBD_IOC_DISCONNECT , &data);
198         if (rc < 0) {
199                 printf("Device: %x %s\n", OBD_IOC_DISCONNECT, strerror(errno));
200                 return 1;
201         }
202         connid = -1;
203
204         return 0;
205 }
206
207
208 static int jt_detach(int argc, char **argv)
209 {
210         struct obd_ioctl_data data;
211         int rc;
212
213         IOCINIT(data);
214
215         if ( argc != 1 ) {
216                 fprintf(stderr, "Usage: %s\n", argv[0]);
217                 return 1;
218         }
219
220         if (obd_ioctl_pack(&data, &buf, max)) { 
221                 printf("invalid ioctl\n"); 
222                 return 1;
223         }
224
225         rc = ioctl(fd, OBD_IOC_DETACH , buf);
226         if (rc < 0) {
227                 printf("Detach: %s\n", strerror(errno));
228                 return 1;
229         }
230         return 0;
231 }
232
233 static int jt_cleanup(int argc, char **argv)
234 {
235         struct obd_ioctl_data data;
236         int rc;
237
238         IOCINIT(data);
239
240         if ( argc != 1 ) {
241                 fprintf(stderr, "Usage: %s\n", argv[0]);
242                 return 1;
243         }
244
245         rc = ioctl(fd, OBD_IOC_CLEANUP , &data);
246         if (rc < 0) {
247                 printf("Detach: %s\n", strerror(errno));
248                 return 1;
249         }
250         return 0;
251 }
252
253 static int jt_attach(int argc, char **argv)
254 {
255         struct obd_ioctl_data data;
256         int rc;
257
258         IOCINIT(data);
259
260         if ( argc != 2 && argc != 3  ) {
261                 fprintf(stderr, "Usage: %s type [data]\n", argv[0]);
262                 return 1;
263         }
264
265         data.ioc_inllen1 =  strlen(argv[1]) + 1;
266         data.ioc_inlbuf1 = argv[1];
267         if ( argc == 3 ) { 
268                 data.ioc_inllen2 = strlen(argv[2]) + 1;
269                 data.ioc_inlbuf2 = argv[2];
270         }
271
272         printf("attach len %d addr %p type %s data %s\n", data.ioc_len, buf, 
273                MKSTR(data.ioc_inlbuf1), MKSTR(data.ioc_inlbuf2));
274
275         if (obd_ioctl_pack(&data, &buf, max)) { 
276                 printf("invalid ioctl\n"); 
277                 return 1;
278         }
279         printf("attach len %d addr %p raw %p type %s data %s and %s\n", data.ioc_len, buf, rawbuf,
280                MKSTR(data.ioc_inlbuf1), MKSTR(data.ioc_inlbuf2), &buf[516]);
281
282         rc = ioctl(fd, OBD_IOC_ATTACH , buf);
283         if (rc < 0) {
284                 printf("Attach: %x %s\n", OBD_IOC_ATTACH, strerror(errno));
285                 return 1;
286         }
287         return 0;
288 }
289
290 static int jt_setup(int argc, char **argv)
291 {
292         struct obd_ioctl_data data;
293         int rc;
294
295         IOCINIT(data);
296
297         if ( argc > 3  ) {
298                 fprintf(stderr, "Usage: %s [device] [fstype]\n", argv[0]);
299                 return 1;
300         }
301
302         if (argc > 1) {
303                 data.ioc_inllen1 =  strlen(argv[1]) + 1;
304                 data.ioc_inlbuf1 = argv[1];
305                 data.ioc_dev = strtoul(argv[1], NULL, 0);
306         } else {
307                 data.ioc_dev = -1;
308         }
309         if ( argc == 3 ) { 
310                 data.ioc_inllen2 = strlen(argv[2]) + 1;
311                 data.ioc_inlbuf2 = argv[2];
312         }
313
314         printf("setup len %d addr %p device %s type %s\n", data.ioc_len, buf, 
315                MKSTR(data.ioc_inlbuf1), MKSTR(data.ioc_inlbuf2));
316
317         if (obd_ioctl_pack(&data, &buf, max)) { 
318                 printf("invalid ioctl\n"); 
319                 return 1;
320         }
321         printf("setup len %d addr %p raw %p device %s type %s\n", 
322                data.ioc_len, buf, rawbuf,
323                MKSTR(data.ioc_inlbuf1), MKSTR(data.ioc_inlbuf2));
324
325         rc = ioctl(fd, OBD_IOC_SETUP , buf);
326         if (rc < 0) {
327                 printf("setup: %x %s\n", OBD_IOC_SETUP, strerror(errno));
328                 return 1;
329         }
330         return 0;
331 }
332
333
334 static int jt_create(int argc, char **argv)
335 {
336         struct obd_ioctl_data data;
337         int num = 1;
338         int silent = 0;
339         int i;
340         int rc;
341
342         IOCINIT(data);
343         if (argc > 1) { 
344                 num = strtoul(argv[1], NULL, 0);
345         } else { 
346                 printf("usage %s num [mode] [silent]\n", argv[0]); 
347         }
348
349         if (argc > 2) { 
350                 data.ioc_obdo1.o_mode = strtoul(argv[2], NULL, 0);
351         } else { 
352                 data.ioc_obdo1.o_mode = 0100644;
353         }
354         data.ioc_obdo1.o_valid = OBD_MD_FLMODE;
355
356         if (argc > 3) { 
357                 silent = strtoul(argv[3], NULL, 0);
358         }
359                 
360         printf("Creating %d obdos\n", num);
361
362         for (i = 0 ; i<num ; i++) { 
363                 rc = ioctl(fd, OBD_IOC_CREATE , &data);
364                 if (rc < 0) {
365                         printf("Create: %x %s\n", OBD_IOC_CREATE, 
366                                strerror(errno));
367                         return 1;
368                 }
369                 printf("created obdo %Ld\n", data.ioc_obdo1.o_id);
370         }
371         return 0;
372 }
373
374 static int jt_setattr(int argc, char **argv)
375 {
376         struct obd_ioctl_data data;
377         int rc;
378
379         IOCINIT(data);
380         if (argc < 2) { 
381                 printf("usage: %s id mode\n", argv[0]); 
382                 return -1;
383         }
384
385         data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
386         data.ioc_obdo1.o_mode = strtoul(argv[2], NULL, 0);
387         data.ioc_obdo1.o_valid = OBD_MD_FLMODE; 
388
389         rc = ioctl(fd, OBD_IOC_SETATTR , &data);
390         if (rc < 0) {
391                 printf("setattr: %x %s\n", OBD_IOC_SETATTR, strerror(errno));
392         }
393         return rc;
394 }
395
396 static int jt_destroy(int argc, char **argv)
397 {
398         struct obd_ioctl_data data;
399         int rc;
400
401         IOCINIT(data);
402         if (argc < 1) { 
403                 printf("usage %s id\n", argv[0]); 
404         }
405
406         data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
407
408         rc = ioctl(fd, OBD_IOC_DESTROY , &data);
409         if (rc < 0) {
410                 printf("setattr: %x %s\n", OBD_IOC_DESTROY, strerror(errno));
411         }
412         return rc;
413 }
414
415 static int jt_multi_getattr(int argc, char **argv)
416 {
417         struct obd_ioctl_data data;
418         int count, i;
419         int rc;
420
421         IOCINIT(data);
422         if (argc == 2) { 
423                 count = strtoul(argv[1], NULL, 0);
424                 data.ioc_obdo1.o_valid = 0xffffffff;
425                 data.ioc_obdo1.o_id = 2;
426                 printf("getting %d attrs (testing only)\n", count);
427         } else { 
428                 printf("usage %s id\n", argv[0]); 
429                 return 0;
430         }
431
432         for (i = 0 ; i < count; i++) {
433                 rc = ioctl(fd, OBD_IOC_GETATTR , &data);
434                 if (rc) { 
435                         printf("Error: %s on i=%d\n", strerror(rc), i); 
436                         break;
437                 } else { 
438                         printf("attr number %d\n", i);
439                 }
440         }
441         return 0;
442 }
443
444 static int jt_getattr(int argc, char **argv)
445 {
446         struct obd_ioctl_data data;
447         int rc;
448
449         IOCINIT(data);
450         if (argc == 2) { 
451                 data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
452                 data.ioc_obdo1.o_valid = 0xffffffff;
453                 printf("getting attr for %Ld\n", data.ioc_obdo1.o_id);
454         } else { 
455                 printf("usage %s id\n", argv[0]); 
456                 return 0;
457         }
458
459         rc = ioctl(fd, OBD_IOC_GETATTR , &data);
460         if (rc) { 
461                 printf("Error: %s\n", strerror(rc)); 
462         } else { 
463                 printf("attr obdo %Ld, mode %o\n", data.ioc_obdo1.o_id, 
464                        data.ioc_obdo1.o_mode);
465         }
466         return 0;
467 }
468
469 command_t list[] = {
470         {"device", jt_device, 0, "set current device (args device no)"},
471         {"attach", jt_attach, 0, "name the typed of device (args: type data"},
472         {"setup", jt_setup, 0, "setup device (args: blkdev, data"},
473         {"detach", jt_detach, 0, "detach the current device (arg: )"},
474         {"cleanup", jt_cleanup, 0, "cleanup the current device (arg: )"},
475         {"create", jt_create, 0, "create [count [mode [silent]]]"},
476         {"destroy", jt_destroy, 0, "destroy id"},
477         {"test_getattr", jt_multi_getattr, 0, "test_getattr count [silent]"},
478         {"getattr", jt_getattr, 0, "getattr id"},
479         {"setattr", jt_setattr, 0, "setattr id mode"},
480         {"connect", jt_connect, 0, "connect - get a connection to device"},
481         {"disconnect", jt_disconnect, 0, "disconnect - break connection to device"},
482         {"help", Parser_help, 0, "help"},
483         {"exit", Parser_quit, 0, "quit"},
484         {"quit", Parser_quit, 0, "quit"},
485         { 0, 0, 0, NULL }
486 };
487
488
489 static void signal_server(int sig)
490 {
491         if (sig == SIGINT) { 
492                 printf("Disconnecting existing connection");
493                 do_disconnect();
494         }
495 }
496
497 int main(int argc, char **argv)
498 {
499         struct sigaction sigact;
500         sigact.sa_handler = signal_server;
501         sigfillset(&sigact.sa_mask);
502         sigact.sa_flags = SA_RESTART;
503         sigaction(SIGINT, &sigact, NULL);
504
505         if (argc > 1) { 
506                 return Parser_execarg(argc - 1, &argv[1], list);
507         }
508
509         Parser_init("obdctl > ", list);
510         Parser_commands();
511
512         return 0;
513 }
514