Whamcloud - gitweb
- add obdecho directory
[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 #define printk printf
33 #include <linux/lustre_lib.h>
34 #include <linux/lustre_idl.h>
35 #include <unistd.h>
36 #include <sys/un.h>
37 #include <sys/time.h>
38 #include <netinet/in.h>
39 #include <errno.h>
40 #include <string.h>
41 #include <linux/module.h>
42
43 #define __KERNEL__
44 #include <linux/list.h>
45 #undef __KERNEL__
46
47 #include "parser.h"
48 #include <stdio.h>
49
50 int fd = -1;
51 int connid = -1;
52 char rawbuf[8192];
53 char *buf = rawbuf;
54 int max = 8192;
55
56 #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)
57
58 /*
59     pack "LL LL LL LL LL LL LL L L L L L L L L L a60 a60 L L L", 
60     $obdo->{id}, 0, 
61     $obdo->{gr}, 0, 
62     $obdo->{atime}, 0, 
63     $obdo->{mtime}, 0 ,
64     $obdo->{ctime}, 0, 
65     $obdo->{size}, 0, 
66     $obdo->{blocks}, 0, 
67     $obdo->{blksize},
68     $obdo->{mode},
69     $obdo->{uid},
70     $obdo->{gid},
71     $obdo->{flags},
72     $obdo->{obdflags},
73     $obdo->{nlink},     
74     $obdo->{generation},        
75     $obdo->{valid},     
76     $obdo->{inline},
77     $obdo->{obdmd},
78     0, 0, # struct list_head 
79     0;  #  struct obd_ops 
80 }
81
82 */
83
84 char * obdo_print(struct obdo *obd)
85 {
86         char buf[1024];
87
88         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",
89                 obd->o_id,
90                 obd->o_gr,
91                 obd->o_atime,
92                 obd->o_mtime,
93                 obd->o_ctime,
94                 obd->o_size,
95                 obd->o_blocks,
96                 obd->o_blksize,
97                 obd->o_mode,
98                 obd->o_uid,
99                 obd->o_gid,
100                 obd->o_flags,
101                 obd->o_obdflags,
102                 obd->o_nlink,
103                 obd->o_valid);
104         return strdup(buf);
105 }
106
107 static int jt_device(int argc, char **argv)
108 {
109         struct obd_ioctl_data data;
110         int rc;
111
112         memset(&data, 0, sizeof(data));
113         if ( argc != 2 ) {
114                 fprintf(stderr, "Usage: %s devno\n", argv[0]);
115                 return 1;
116         }
117
118         data.ioc_dev = atoi(argv[1]);
119
120         if (obd_ioctl_pack(&data, &buf, max)) { 
121                 printf("invalid ioctl\n"); 
122                 return 1;
123         }
124
125         if (fd == -1) 
126                 fd = open("/dev/obd", O_RDWR);
127         if (fd == -1) {
128                 printf("Opening /dev/obd: %s\n", strerror(errno));
129                 return 1;
130         }
131
132         rc = ioctl(fd, OBD_IOC_DEVICE , buf);
133         if (rc < 0) {
134                 printf("Device: %x %s\n", OBD_IOC_DEVICE, strerror(errno));
135                 return 1;
136         }
137
138         return 0;
139 }
140
141 static int jt_connect(int argc, char **argv)
142 {
143         struct obd_ioctl_data data;
144         int rc;
145
146         IOCINIT(data);
147
148         if ( argc != 1 ) {
149                 fprintf(stderr, "Usage: %s\n", argv[0]);
150                 return 1;
151         }
152
153         rc = ioctl(fd, OBD_IOC_CONNECT , &data);
154         if (rc < 0) {
155                 printf("Device: %x %s\n", OBD_IOC_CONNECT, strerror(errno));
156                 return 1;
157         }
158         connid = data.ioc_conn1;
159
160         return 0;
161 }
162
163 static int jt_disconnect(int argc, char **argv)
164 {
165         struct obd_ioctl_data data;
166         int rc;
167
168         IOCINIT(data);
169
170         if ( argc != 1 ) {
171                 fprintf(stderr, "Usage: %s\n", argv[0]);
172                 return 1;
173         }
174
175         rc = ioctl(fd, OBD_IOC_DISCONNECT , &data);
176         if (rc < 0) {
177                 printf("Device: %x %s\n", OBD_IOC_DISCONNECT, strerror(errno));
178                 return 1;
179         }
180         connid = -1;
181
182         return 0;
183 }
184
185
186 static int jt_detach(int argc, char **argv)
187 {
188         struct obd_ioctl_data data;
189         int rc;
190
191         IOCINIT(data);
192
193         if ( argc != 1 ) {
194                 fprintf(stderr, "Usage: %s\n", argv[0]);
195                 return 1;
196         }
197
198         if (obd_ioctl_pack(&data, &buf, max)) { 
199                 printf("invalid ioctl\n"); 
200                 return 1;
201         }
202
203         rc = ioctl(fd, OBD_IOC_DETACH , buf);
204         if (rc < 0) {
205                 printf("Detach: %s\n", strerror(errno));
206                 return 1;
207         }
208         return 0;
209 }
210
211 static int jt_cleanup(int argc, char **argv)
212 {
213         struct obd_ioctl_data data;
214         int rc;
215
216         IOCINIT(data);
217
218         if ( argc != 1 ) {
219                 fprintf(stderr, "Usage: %s\n", argv[0]);
220                 return 1;
221         }
222
223         rc = ioctl(fd, OBD_IOC_CLEANUP , &data);
224         if (rc < 0) {
225                 printf("Detach: %s\n", strerror(errno));
226                 return 1;
227         }
228         return 0;
229 }
230
231 static int jt_attach(int argc, char **argv)
232 {
233         struct obd_ioctl_data data;
234         int rc;
235
236         IOCINIT(data);
237
238         if ( argc != 2 && argc != 3  ) {
239                 fprintf(stderr, "Usage: %s type [data]\n", argv[0]);
240                 return 1;
241         }
242
243         data.ioc_inllen1 =  strlen(argv[1]) + 1;
244         data.ioc_inlbuf1 = argv[1];
245         if ( argc == 3 ) { 
246                 data.ioc_inllen2 = strlen(argv[2]) + 1;
247                 data.ioc_inlbuf2 = argv[2];
248         }
249
250         printf("attach len %d addr %p type %s data %s\n", data.ioc_len, buf, 
251                MKSTR(data.ioc_inlbuf1), MKSTR(data.ioc_inlbuf2));
252
253         if (obd_ioctl_pack(&data, &buf, max)) { 
254                 printf("invalid ioctl\n"); 
255                 return 1;
256         }
257         printf("attach len %d addr %p raw %p type %s data %s and %s\n", data.ioc_len, buf, rawbuf,
258                MKSTR(data.ioc_inlbuf1), MKSTR(data.ioc_inlbuf2), &buf[516]);
259
260         rc = ioctl(fd, OBD_IOC_ATTACH , buf);
261         if (rc < 0) {
262                 printf("Attach: %x %s\n", OBD_IOC_ATTACH, strerror(errno));
263                 return 1;
264         }
265         return 0;
266 }
267
268 static int jt_setup(int argc, char **argv)
269 {
270         struct obd_ioctl_data data;
271         int rc;
272
273         IOCINIT(data);
274
275         if ( argc > 3  ) {
276                 fprintf(stderr, "Usage: %s [device] [fstype]\n", argv[0]);
277                 return 1;
278         }
279
280         if (argc > 1) {
281                 data.ioc_inllen1 =  strlen(argv[1]) + 1;
282                 data.ioc_inlbuf1 = argv[1];
283                 data.ioc_dev = strtoul(argv[1], NULL, 0);
284         } else {
285                 data.ioc_dev = -1;
286         }
287         if ( argc == 3 ) { 
288                 data.ioc_inllen2 = strlen(argv[2]) + 1;
289                 data.ioc_inlbuf2 = argv[2];
290         }
291
292         printf("setup len %d addr %p device %s type %s\n", data.ioc_len, buf, 
293                MKSTR(data.ioc_inlbuf1), MKSTR(data.ioc_inlbuf2));
294
295         if (obd_ioctl_pack(&data, &buf, max)) { 
296                 printf("invalid ioctl\n"); 
297                 return 1;
298         }
299         printf("setup len %d addr %p raw %p device %s type %s\n", 
300                data.ioc_len, buf, rawbuf,
301                MKSTR(data.ioc_inlbuf1), MKSTR(data.ioc_inlbuf2));
302
303         rc = ioctl(fd, OBD_IOC_SETUP , buf);
304         if (rc < 0) {
305                 printf("setup: %x %s\n", OBD_IOC_SETUP, strerror(errno));
306                 return 1;
307         }
308         return 0;
309 }
310
311
312 static int jt_create(int argc, char **argv)
313 {
314         struct obd_ioctl_data data;
315         int num = 1;
316         int silent = 0;
317         int i;
318         int rc;
319
320         IOCINIT(data);
321         if (argc > 1) { 
322                 num = strtoul(argv[1], NULL, 0);
323         } else { 
324                 printf("usage %s num [mode] [silent]\n", argv[0]); 
325         }
326
327         if (argc > 2) { 
328                 data.ioc_obdo1.o_mode = strtoul(argv[2], NULL, 0);
329         } else { 
330                 data.ioc_obdo1.o_mode = 0100644;
331         }
332         data.ioc_obdo1.o_valid = OBD_MD_FLMODE;
333
334         if (argc > 3) { 
335                 silent = strtoul(argv[3], NULL, 0);
336         }
337                 
338         printf("Creating %d obdos\n", num);
339
340         for (i = 0 ; i<num ; i++) { 
341                 rc = ioctl(fd, OBD_IOC_CREATE , &data);
342                 if (rc < 0) {
343                         printf("Create: %x %s\n", OBD_IOC_CREATE, 
344                                strerror(errno));
345                         return 1;
346                 }
347                 printf("created obdo %Ld\n", data.ioc_obdo1.o_id);
348         }
349         return 0;
350 }
351
352 static int jt_setattr(int argc, char **argv)
353 {
354         struct obd_ioctl_data data;
355         int rc;
356
357         IOCINIT(data);
358         if (argc < 2) { 
359                 printf("usage: %s id mode\n", argv[0]); 
360                 return -1;
361         }
362
363         data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
364         data.ioc_obdo1.o_mode = strtoul(argv[2], NULL, 0);
365         data.ioc_obdo1.o_valid = OBD_MD_FLMODE; 
366
367         rc = ioctl(fd, OBD_IOC_SETATTR , &data);
368         if (rc < 0) {
369                 printf("setattr: %x %s\n", OBD_IOC_SETATTR, strerror(errno));
370         }
371         return rc;
372 }
373
374 static int jt_destroy(int argc, char **argv)
375 {
376         struct obd_ioctl_data data;
377         int rc;
378
379         IOCINIT(data);
380         if (argc < 1) { 
381                 printf("usage %s id\n", argv[0]); 
382         }
383
384         data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
385
386         rc = ioctl(fd, OBD_IOC_DESTROY , &data);
387         if (rc < 0) {
388                 printf("setattr: %x %s\n", OBD_IOC_DESTROY, strerror(errno));
389         }
390         return rc;
391 }
392
393 static int jt_multi_getattr(int argc, char **argv)
394 {
395         struct obd_ioctl_data data;
396         int count, i;
397         int rc;
398
399         IOCINIT(data);
400         if (argc == 2) { 
401                 count = strtoul(argv[1], NULL, 0);
402                 data.ioc_obdo1.o_valid = 0xffffffff;
403                 data.ioc_obdo1.o_id = 2;
404                 printf("getting %d attrs (testing only)\n", count);
405         } else { 
406                 printf("usage %s id\n", argv[0]); 
407                 return 0;
408         }
409
410         for (i = 0 ; i < count; i++) {
411                 rc = ioctl(fd, OBD_IOC_GETATTR , &data);
412                 if (rc) { 
413                         printf("Error: %s on i=%d\n", strerror(rc), i); 
414                         break;
415                 } else { 
416                         printf("attr number %d\n", i);
417                 }
418         }
419         return 0;
420 }
421
422 static int jt_getattr(int argc, char **argv)
423 {
424         struct obd_ioctl_data data;
425         int rc;
426
427         IOCINIT(data);
428         if (argc == 2) { 
429                 data.ioc_obdo1.o_id = strtoul(argv[1], NULL, 0);
430                 data.ioc_obdo1.o_valid = 0xffffffff;
431                 printf("getting attr for %Ld\n", data.ioc_obdo1.o_id);
432         } else { 
433                 printf("usage %s id\n", argv[0]); 
434                 return 0;
435         }
436
437         rc = ioctl(fd, OBD_IOC_GETATTR , &data);
438         if (rc) { 
439                 printf("Error: %s\n", strerror(rc)); 
440         } else { 
441                 printf("attr obdo %Ld, mode %o\n", data.ioc_obdo1.o_id, 
442                        data.ioc_obdo1.o_mode);
443         }
444         return 0;
445 }
446
447 static int jt_modules(int argc, char **argv)
448 {
449         char *modules[] = {"portals", "ksocknal", "obdclass", "ptlrpc",
450                            "obdext2", "ost", "osc", "mds", "mdc", "llight",
451                            "obdecho", NULL};
452         char *paths[] = {"portals/linux/oslib", "portals/linux/socknal",
453                          "obd/class", "obd/rpc", "obd/ext2obd", "obd/ost",
454                          "obd/osc", "obd/mds", "obd/mdc", "obd/llight",
455                         "obd/obdecho", NULL};
456         char *path = "..";
457         char *kernel = "linux";
458         int i;
459
460         if (argc >= 2)
461                 path = argv[1];
462         if (argc == 3) 
463                 kernel = argv[2];
464         if (argc > 3) {
465                 printf("%s [path] [kernel]\n", argv[0]);
466                 return 0;
467         }
468
469         printf("symbol-file\nsymbol-file %s\nb panic\nb stop\n", kernel); 
470
471         for (i = 0; modules[i] != NULL; i++) {
472                 struct module_info info;
473                 int rc;
474                 size_t crap;
475                 int query_module(const char *name, int which, void *buf,
476                                  size_t bufsize, size_t *ret);
477
478                 rc = query_module(modules[i], QM_INFO, &info, sizeof(info),
479                                   &crap);
480                 if (rc < 0) {
481                         if (errno != ENOENT)
482                                 printf("query_module(%s) failed: %s\n",
483                                        modules[i], strerror(errno));
484                 } else {
485                         printf("add-symbol-file %s/%s/%s.o 0x%0lx\n", path,
486                                paths[i], modules[i],
487                                info.addr + sizeof(struct module));
488                 }
489         }
490
491         return 0;
492 }
493
494 command_t list[] = {
495         {"device", jt_device, 0, "set current device (args device no)"},
496         {"attach", jt_attach, 0, "name the typed of device (args: type data"},
497         {"setup", jt_setup, 0, "setup device (args: blkdev, data"},
498         {"detach", jt_detach, 0, "detach the current device (arg: )"},
499         {"cleanup", jt_cleanup, 0, "cleanup the current device (arg: )"},
500         {"create", jt_create, 0, "create [count [mode [silent]]]"},
501         {"destroy", jt_destroy, 0, "destroy id"},
502         {"test_getattr", jt_multi_getattr, 0, "test_getattr count [silent]"},
503         {"getattr", jt_getattr, 0, "getattr id"},
504         {"setattr", jt_setattr, 0, "setattr id mode"},
505         {"connect", jt_connect, 0, "connect - get a connection to device"},
506         {"disconnect", jt_disconnect, 0, "disconnect - break connection to device"},
507         {"modules", jt_modules, 0, "provide gdb-friendly module info (arg: <path>)"},
508         {"help", Parser_help, 0, "help"},
509         {"exit", Parser_quit, 0, "quit"},
510         {"quit", Parser_quit, 0, "quit"},
511         { 0, 0, 0, NULL }
512 };
513
514 int main(int argc, char **argv)
515 {
516
517         if (argc > 1) { 
518                 return Parser_execarg(argc - 1, &argv[1], list);
519         }
520
521         Parser_init("obdctl > ", list);
522         Parser_commands();
523
524         return 0;
525 }
526