Whamcloud - gitweb
- OBD_ALLOC() of obdos are replaced by obdo_alloc(), the same about obdo_free().
[fs/lustre-release.git] / lnet / utils / debug.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
5  *
6  *   This file is part of Portals, http://www.sf.net/projects/lustre/
7  *
8  *   Portals is free software; you can redistribute it and/or
9  *   modify it under the terms of version 2 of the GNU General Public
10  *   License as published by the Free Software Foundation.
11  *
12  *   Portals is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with Portals; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  * Some day I'll split all of this functionality into a cfs_debug module
22  * of its own.  That day is not today.
23  *
24  */
25
26 #define __USE_FILE_OFFSET64
27 #define  _GNU_SOURCE
28
29 #include <portals/list.h>
30
31 #include <stdio.h>
32 #ifdef HAVE_NETDB_H
33 #include <netdb.h>
34 #endif
35 #include <stdlib.h>
36 #include <string.h>
37 #include "ioctl.h"
38 #include <fcntl.h>
39 #include <errno.h>
40 #include <unistd.h>
41 #ifndef __CYGWIN__
42 # include <syscall.h>
43 #endif
44
45 #include <sys/types.h>
46 #include <sys/socket.h>
47 #include <sys/ioctl.h>
48 #include <sys/stat.h>
49 #include <sys/mman.h>
50
51 #ifdef HAVE_LINUX_VERSION_H
52 #include <linux/version.h>
53
54 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
55 #define BUG()                            /* workaround for module.h includes */
56 #include <linux/module.h>
57 #endif
58 #endif /* !HAVE_LINUX_VERSION_H */
59
60 #include <sys/utsname.h>
61
62 #include <portals/api-support.h>
63 #include <portals/ptlctl.h>
64 #include "parser.h"
65
66 #include <time.h>
67
68 static char rawbuf[8192];
69 static char *buf = rawbuf;
70 static int max = 8192;
71 /*static int g_pfd = -1;*/
72 static int subsystem_mask = ~0;
73 static int debug_mask = ~0;
74
75 #define MAX_MARK_SIZE 100
76
77 static const char *portal_debug_subsystems[] =
78         {"undefined", "mdc", "mds", "osc", "ost", "class", "log", "llite",
79          "rpc", "mgmt", "portals", "libcfs", "socknal", "qswnal", "pinger",
80          "filter", "ptlbd", "echo", "ldlm", "lov", "gmnal", "router", "cobd",
81          "ibnal", "lmv", "cmobd", "smfs", NULL};
82 static const char *portal_debug_masks[] =
83         {"trace", "inode", "super", "ext2", "malloc", "cache", "info", "ioctl",
84          "blocks", "net", "warning", "buffs", "other", "dentry", "portals",
85          "page", "dlmtrace", "error", "emerg", "ha", "rpctrace", "vfstrace",
86          "reada", "mmap", NULL};
87
88 struct debug_daemon_cmd {
89         char *cmd;
90         unsigned int cmdv;
91 };
92
93 static const struct debug_daemon_cmd portal_debug_daemon_cmd[] = {
94         {"start", DEBUG_DAEMON_START},
95         {"stop", DEBUG_DAEMON_STOP},
96         {0, 0}
97 };
98
99 static int do_debug_mask(char *name, int enable)
100 {
101         int found = 0, i;
102
103         for (i = 0; portal_debug_subsystems[i] != NULL; i++) {
104                 if (strcasecmp(name, portal_debug_subsystems[i]) == 0 ||
105                     strcasecmp(name, "all_subs") == 0) {
106                         printf("%s output from subsystem \"%s\"\n",
107                                 enable ? "Enabling" : "Disabling",
108                                 portal_debug_subsystems[i]);
109                         if (enable)
110                                 subsystem_mask |= (1 << i);
111                         else
112                                 subsystem_mask &= ~(1 << i);
113                         found = 1;
114                 }
115         }
116         for (i = 0; portal_debug_masks[i] != NULL; i++) {
117                 if (strcasecmp(name, portal_debug_masks[i]) == 0 ||
118                     strcasecmp(name, "all_types") == 0) {
119                         printf("%s output of type \"%s\"\n",
120                                 enable ? "Enabling" : "Disabling",
121                                 portal_debug_masks[i]);
122                         if (enable)
123                                 debug_mask |= (1 << i);
124                         else
125                                 debug_mask &= ~(1 << i);
126                         found = 1;
127                 }
128         }
129
130         return found;
131 }
132
133 int dbg_initialize(int argc, char **argv)
134 {
135         return 0;
136 }
137
138 int jt_dbg_filter(int argc, char **argv)
139 {
140         int   i;
141
142         if (argc < 2) {
143                 fprintf(stderr, "usage: %s <subsystem ID or debug mask>\n",
144                         argv[0]);
145                 return 0;
146         }
147
148         for (i = 1; i < argc; i++)
149                 if (!do_debug_mask(argv[i], 0))
150                         fprintf(stderr, "Unknown subsystem or debug type: %s\n",
151                                 argv[i]);
152         return 0;
153 }
154
155 int jt_dbg_show(int argc, char **argv)
156 {
157         int    i;
158
159         if (argc < 2) {
160                 fprintf(stderr, "usage: %s <subsystem ID or debug mask>\n",
161                         argv[0]);
162                 return 0;
163         }
164
165         for (i = 1; i < argc; i++)
166                 if (!do_debug_mask(argv[i], 1))
167                         fprintf(stderr, "Unknown subsystem or debug type: %s\n",
168                                 argv[i]);
169
170         return 0;
171 }
172
173 static int applymask(char* procpath, int value)
174 {
175         int rc;
176         char buf[64];
177         int len = snprintf(buf, 64, "%d", value);
178
179         int fd = open(procpath, O_WRONLY);
180         if (fd == -1) {
181                 fprintf(stderr, "Unable to open %s: %s\n",
182                         procpath, strerror(errno));
183                 return fd;
184         }
185         rc = write(fd, buf, len+1);
186         if (rc<0) {
187                 fprintf(stderr, "Write to %s failed: %s\n",
188                         procpath, strerror(errno));
189                 return rc;
190         }
191         close(fd);
192         return 0;
193 }
194
195 static void applymask_all(unsigned int subs_mask, unsigned int debug_mask)
196 {
197         if (!dump_filename) {
198                 applymask("/proc/sys/portals/subsystem_debug", subs_mask);
199                 applymask("/proc/sys/portals/debug", debug_mask);
200         } else {
201                 struct portals_debug_ioctl_data data;
202
203                 data.hdr.ioc_len = sizeof(data);
204                 data.hdr.ioc_version = 0;
205                 data.subs = subs_mask;
206                 data.debug = debug_mask;
207
208                 dump(OBD_DEV_ID, PTL_IOC_DEBUG_MASK, &data);
209         }
210         printf("Applied subsystem_debug=%d, debug=%d to /proc/sys/portals\n",
211                subs_mask, debug_mask);
212 }
213
214 int jt_dbg_list(int argc, char **argv)
215 {
216         int i;
217
218         if (argc != 2) {
219                 fprintf(stderr, "usage: %s <subs || types>\n", argv[0]);
220                 return 0;
221         }
222
223         if (strcasecmp(argv[1], "subs") == 0) {
224                 printf("Subsystems: all_subs");
225                 for (i = 0; portal_debug_subsystems[i] != NULL; i++)
226                         printf(", %s", portal_debug_subsystems[i]);
227                 printf("\n");
228         } else if (strcasecmp(argv[1], "types") == 0) {
229                 printf("Types: all_types");
230                 for (i = 0; portal_debug_masks[i] != NULL; i++)
231                         printf(", %s", portal_debug_masks[i]);
232                 printf("\n");
233         } else if (strcasecmp(argv[1], "applymasks") == 0) {
234                 applymask_all(subsystem_mask, debug_mask);
235         }
236         return 0;
237 }
238
239 /* all strings nul-terminated; only the struct and hdr need to be freed */
240 struct dbg_line {
241         struct ptldebug_header *hdr;
242         char *file;
243         char *fn;
244         char *text;
245         struct list_head chain;
246 };
247
248 /* nurr. */
249 static void list_add_ordered(struct dbg_line *new, struct list_head *head)
250 {
251         struct list_head *pos;
252         struct dbg_line *curr;
253
254         list_for_each(pos, head) {
255                 curr = list_entry(pos, struct dbg_line, chain);
256
257                 if (curr->hdr->ph_sec < new->hdr->ph_sec)
258                         continue;
259                 if (curr->hdr->ph_sec == new->hdr->ph_sec &&
260                     curr->hdr->ph_usec < new->hdr->ph_usec)
261                         continue;
262
263                 list_add(&new->chain, pos->prev);
264                 return;
265         }
266         list_add_tail(&new->chain, head);
267 }
268
269 static void print_saved_records(struct list_head *list, FILE *out)
270 {
271         struct list_head *pos, *tmp;
272
273         list_for_each_safe(pos, tmp, list) {
274                 struct dbg_line *line;
275                 struct ptldebug_header *hdr;
276
277                 line = list_entry(pos, struct dbg_line, chain);
278                 list_del(&line->chain);
279
280                 hdr = line->hdr;
281                 fprintf(out, "%06x:%06x:%u:%u.%06Lu:%u:%u:%u:(%s:%u:%s()) %s",
282                         hdr->ph_subsys, hdr->ph_mask, hdr->ph_cpu_id,
283                         hdr->ph_sec, (unsigned long long)hdr->ph_usec,
284                         hdr->ph_stack, hdr->ph_pid, hdr->ph_extern_pid,
285                         line->file, hdr->ph_line_num, line->fn, line->text);
286                 free(line->hdr);
287                 free(line);
288         }
289 }
290
291 static int parse_buffer(FILE *in, FILE *out)
292 {
293         struct dbg_line *line;
294         struct ptldebug_header *hdr;
295         char buf[4097], *p;
296         int rc;
297         unsigned long dropped = 0, kept = 0;
298         struct list_head chunk_list;
299
300         INIT_LIST_HEAD(&chunk_list);
301
302         while (1) {
303                 rc = fread(buf, sizeof(hdr->ph_len), 1, in);
304                 if (rc <= 0)
305                         break;
306
307                 hdr = (void *)buf;
308                 if (hdr->ph_len == 0)
309                         break;
310                 if (hdr->ph_len > 4094) {
311                         fprintf(stderr, "unexpected large record: %d bytes.  "
312                                 "aborting.\n",
313                                 hdr->ph_len);
314                         break;
315                 }
316
317                 if (hdr->ph_flags & PH_FLAG_FIRST_RECORD) {
318                         print_saved_records(&chunk_list, out);
319                         assert(list_empty(&chunk_list));
320                 }
321
322                 rc = fread(buf + sizeof(hdr->ph_len), 1,
323                            hdr->ph_len - sizeof(hdr->ph_len), in);
324                 if (rc <= 0)
325                         break;
326
327                 if (hdr->ph_mask &&
328                     (!(subsystem_mask & hdr->ph_subsys) ||
329                      (!(debug_mask & hdr->ph_mask)))) {
330                         dropped++;
331                         continue;
332                 }
333
334                 line = malloc(sizeof(*line));
335                 if (line == NULL) {
336                         fprintf(stderr, "malloc failed; printing accumulated "
337                                 "records and exiting.\n");
338                         break;
339                 }
340
341                 line->hdr = malloc(hdr->ph_len + 1);
342                 if (line->hdr == NULL) {
343                         fprintf(stderr, "malloc failed; printing accumulated "
344                                 "records and exiting.\n");
345                         break;
346                 }
347
348                 p = (void *)line->hdr;
349                 memcpy(line->hdr, buf, hdr->ph_len);
350                 p[hdr->ph_len] = '\0';
351
352                 p += sizeof(*hdr);
353                 line->file = p;
354                 p += strlen(line->file) + 1;
355                 line->fn = p;
356                 p += strlen(line->fn) + 1;
357                 line->text = p;
358
359                 list_add_ordered(line, &chunk_list);
360                 kept++;
361         }
362
363         print_saved_records(&chunk_list, out);
364
365         printf("Debug log: %lu lines, %lu kept, %lu dropped.\n",
366                 dropped + kept, kept, dropped);
367         return 0;
368 }
369
370 int jt_dbg_debug_kernel(int argc, char **argv)
371 {
372         char filename[4096];
373         int rc, raw = 0, fd;
374         FILE *in, *out = stdout;
375
376         if (argc > 3) {
377                 fprintf(stderr, "usage: %s [file] [raw]\n", argv[0]);
378                 return 0;
379         }
380
381         if (argc > 2) {
382                 raw = atoi(argv[2]);
383         } else if (argc > 1 && (argv[1][0] == '0' || argv[1][0] == '1')) {
384                 raw = atoi(argv[1]);
385                 argc--;
386         } else {
387                 sprintf(filename, "%s.%lu.%u", argc > 1 ? argv[1] :
388                         "/tmp/lustre-log", time(NULL), getpid());
389         }
390
391         unlink(filename);
392
393         fd = open("/proc/sys/portals/dump_kernel", O_WRONLY);
394         if (fd < 0) {
395                 if (errno == ENOENT) /* no dump file created */
396                         return 0;
397
398                 fprintf(stderr, "open(dump_kernel) failed: %s\n",
399                         strerror(errno));
400                 return 1;
401         }
402
403         rc = write(fd, filename, strlen(filename));
404         if (rc != strlen(filename)) {
405                 fprintf(stderr, "write(%s) failed: %s\n", filename,
406                         strerror(errno));
407                 close(fd);
408                 return 1;
409         }
410         close(fd);
411
412         if (raw)
413                 return 0;
414
415         in = fopen(filename, "r");
416         if (in == NULL) {
417                 fprintf(stderr, "fopen(%s) failed: %s\n", filename,
418                         strerror(errno));
419                 return 1;
420         }
421         if (argc > 1) {
422                 out = fopen(argv[1], "w");
423                 if (out == NULL) {
424                         fprintf(stderr, "fopen(%s) failed: %s\n", argv[1],
425                                 strerror(errno));
426                         fclose(in);
427                         return 1;
428                 }
429         }
430
431         rc = parse_buffer(in, out);
432         fclose(in);
433         if (argc > 1)
434                 fclose(out);
435         if (rc) {
436                 fprintf(stderr, "parse_buffer failed; leaving tmp file %s "
437                         "behind.\n", filename);
438         } else {
439                 rc = unlink(filename);
440                 if (rc)
441                         fprintf(stderr, "dumped successfully, but couldn't "
442                                 "unlink tmp file %s: %s\n", filename,
443                                 strerror(errno));
444         }
445         return rc;
446 }
447
448 int jt_dbg_debug_file(int argc, char **argv)
449 {
450         int fdin,fdout;
451         FILE *in, *out = stdout;
452         if (argc > 3 || argc < 2) {
453                 fprintf(stderr, "usage: %s <input> [output]\n", argv[0]);
454                 return 0;
455         }
456
457         fdin = open(argv[1], O_RDONLY | O_LARGEFILE);
458         if (fdin == -1) {
459                 fprintf(stderr, "open(%s) failed: %s\n", argv[1],
460                         strerror(errno));
461                 return 1;
462         }
463         in = fdopen(fdin, "r");
464         if (in == NULL) {
465                 fprintf(stderr, "fopen(%s) failed: %s\n", argv[1],
466                         strerror(errno));
467                 close(fdin);
468                 return 1;
469         }
470         if (argc > 2) {
471                 fdout = open(argv[2], O_CREAT | O_WRONLY | O_LARGEFILE);
472                 if (fdout == -1) {
473                         fprintf(stderr, "open(%s) failed: %s\n", argv[2],
474                                 strerror(errno));
475                         fclose(in);
476                         return 1;
477                 }
478                 out = fdopen(fdout, "w");
479                 if (out == NULL) {
480                         fprintf(stderr, "fopen(%s) failed: %s\n", argv[2],
481                                 strerror(errno));
482                         fclose(in);
483                         close(fdout);
484                         return 1;
485                 }
486         }
487
488         return parse_buffer(in, out);
489 }
490
491 const char debug_daemon_usage[]="usage: debug_daemon {start file [MB]|stop}\n";
492 int jt_dbg_debug_daemon(int argc, char **argv)
493 {
494         int rc, fd;
495
496         if (argc <= 1) {
497                 fprintf(stderr, debug_daemon_usage);
498                 return 0;
499         }
500
501         fd = open("/proc/sys/portals/daemon_file", O_WRONLY);
502         if (fd < 0) {
503                 fprintf(stderr, "open(daemon_file) failed: %s\n",
504                         strerror(errno));
505                 return 1;
506         }
507
508         if (strcasecmp(argv[1], "start") == 0) {
509                 if (argc != 3) {
510                         fprintf(stderr, debug_daemon_usage);
511                         return 1;
512                 }
513
514                 rc = write(fd, argv[2], strlen(argv[2]));
515                 if (rc != strlen(argv[2])) {
516                         fprintf(stderr, "write(%s) failed: %s\n", argv[2],
517                                 strerror(errno));
518                         close(fd);
519                         return 1;
520                 }
521         } else if (strcasecmp(argv[1], "stop") == 0) {
522                 rc = write(fd, "stop", 4);
523                 if (rc != 4) {
524                         fprintf(stderr, "write(stop) failed: %s\n",
525                                 strerror(errno));
526                         close(fd);
527                         return 1;
528                 }
529         } else {
530                 fprintf(stderr, debug_daemon_usage);
531                 return 1;
532         }
533
534         close(fd);
535         return 0;
536 }
537
538 int jt_dbg_clear_debug_buf(int argc, char **argv)
539 {
540         int rc;
541         struct portal_ioctl_data data;
542
543         if (argc != 1) {
544                 fprintf(stderr, "usage: %s\n", argv[0]);
545                 return 0;
546         }
547
548         memset(&data, 0, sizeof(data));
549         if (portal_ioctl_pack(&data, &buf, max) != 0) {
550                 fprintf(stderr, "portal_ioctl_pack failed.\n");
551                 return -1;
552         }
553
554         rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_CLEAR_DEBUG, buf);
555         if (rc) {
556                 fprintf(stderr, "IOC_PORTAL_CLEAR_DEBUG failed: %s\n",
557                         strerror(errno));
558                 return -1;
559         }
560         return 0;
561 }
562
563 int jt_dbg_mark_debug_buf(int argc, char **argv)
564 {
565         int rc, max_size = MAX_MARK_SIZE-1;
566         struct portal_ioctl_data data;
567         char *text;
568         time_t now = time(NULL);
569
570         if (argc > 1) {
571                 int counter;
572                 text = malloc(MAX_MARK_SIZE);
573                 strncpy(text, argv[1], max_size);
574                 max_size-=strlen(argv[1]);
575                 for(counter = 2; (counter < argc) && (max_size > 0) ; counter++){
576                         strncat(text, " ", 1);
577                         max_size-=1;
578                         strncat(text, argv[counter], max_size);
579                         max_size-=strlen(argv[counter]);
580                 }
581         } else {
582                 text = ctime(&now);
583                 text[strlen(text) - 1] = '\0'; /* stupid \n */
584         }
585         if (!max_size) {
586                 text[MAX_MARK_SIZE - 1] = '\0';
587         }
588
589         memset(&data, 0, sizeof(data));
590         data.ioc_inllen1 = strlen(text) + 1;
591         data.ioc_inlbuf1 = text;
592         if (portal_ioctl_pack(&data, &buf, max) != 0) {
593                 fprintf(stderr, "portal_ioctl_pack failed.\n");
594                 return -1;
595         }
596
597         rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_MARK_DEBUG, buf);
598         if (rc) {
599                 fprintf(stderr, "IOC_PORTAL_MARK_DEBUG failed: %s\n",
600                         strerror(errno));
601                 return -1;
602         }
603         return 0;
604 }
605
606 static struct mod_paths {
607         char *name, *path;
608 } mod_paths[] = {
609         {"libcfs", "lustre/portals/libcfs"},
610         {"portals", "lustre/portals/portals"},
611         {"ksocknal", "lustre/portals/knals/socknal"},
612         {"kptlrouter", "lustre/portals/router"},
613         {"lvfs", "lustre/lvfs"},
614         {"obdclass", "lustre/obdclass"},
615         {"llog_test", "lustre/obdclass"},
616         {"ptlrpc", "lustre/ptlrpc"},
617         {"obdext2", "lustre/obdext2"},
618         {"ost", "lustre/ost"},
619         {"osc", "lustre/osc"},
620         {"mds", "lustre/mds"},
621         {"mdc", "lustre/mdc"},
622         {"llite", "lustre/llite"},
623         {"ldiskfs", "lustre/ldiskfs"},
624         {"smfs", "lustre/smfs"},
625         {"obdecho", "lustre/obdecho"},
626         {"ldlm", "lustre/ldlm"},
627         {"obdfilter", "lustre/obdfilter"},
628         {"extN", "lustre/extN"},
629         {"lov", "lustre/lov"},
630         {"lmv", "lustre/lmv"},
631         {"fsfilt_ext3", "lustre/lvfs"},
632         {"fsfilt_extN", "lustre/lvfs"},
633         {"fsfilt_reiserfs", "lustre/lvfs"},
634         {"fsfilt_smfs", "lustre/lvfs"},
635         {"fsfilt_ldiskfs", "lustre/lvfs"},
636         {"mds_ext2", "lustre/mds"},
637         {"mds_ext3", "lustre/mds"},
638         {"mds_extN", "lustre/mds"},
639         {"ptlbd", "lustre/ptlbd"},
640         {"mgmt_svc", "lustre/mgmt"},
641         {"mgmt_cli", "lustre/mgmt"},
642         {"cobd", "lustre/cobd"},
643         {"cmobd", "lustre/cmobd"},
644         {"conf_obd", "lustre/obdclass"},
645         {NULL, NULL}
646 };
647
648 static int jt_dbg_modules_2_4(int argc, char **argv)
649 {
650 #ifdef HAVE_LINUX_VERSION_H
651 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
652         struct mod_paths *mp;
653         char *path = "..";
654         char *kernel = "linux";
655
656         if (argc >= 2)
657                 path = argv[1];
658         if (argc == 3)
659                 kernel = argv[2];
660         if (argc > 3) {
661                 printf("%s [path] [kernel]\n", argv[0]);
662                 return 0;
663         }
664
665         for (mp = mod_paths; mp->name != NULL; mp++) {
666                 struct module_info info;
667                 int rc;
668                 size_t crap;
669                 int query_module(const char *name, int which, void *buf,
670                                  size_t bufsize, size_t *ret);
671
672                 rc = query_module(mp->name, QM_INFO, &info, sizeof(info),
673                                   &crap);
674                 if (rc < 0) {
675                         if (errno != ENOENT)
676                                 printf("query_module(%s) failed: %s\n",
677                                        mp->name, strerror(errno));
678                 } else {
679                         printf("add-symbol-file %s/%s/%s.o 0x%0lx\n", path,
680                                mp->path, mp->name,
681                                info.addr + sizeof(struct module));
682                 }
683         }
684
685         return 0;
686 #endif /* Headers are 2.6-only */
687 #endif /* !HAVE_LINUX_VERSION_H */
688         return -EINVAL;
689 }
690
691 static int jt_dbg_modules_2_5(int argc, char **argv)
692 {
693         struct mod_paths *mp;
694         char *path = "..";
695         char *kernel = "linux";
696         const char *proc = "/proc/modules";
697         char modname[128], others[128];
698         long modaddr;
699         int rc;
700         FILE *file;
701
702         if (argc >= 2)
703                 path = argv[1];
704         if (argc == 3)
705                 kernel = argv[2];
706         if (argc > 3) {
707                 printf("%s [path] [kernel]\n", argv[0]);
708                 return 0;
709         }
710
711         file = fopen(proc, "r");
712         if (!file) {
713                 printf("failed open %s: %s\n", proc, strerror(errno));
714                 return 0;
715         }
716
717         while ((rc = fscanf(file, "%s %s %s %s %s %lx\n",
718                 modname, others, others, others, others, &modaddr)) == 6) {
719                 for (mp = mod_paths; mp->name != NULL; mp++) {
720                         if (!strcmp(mp->name, modname))
721                                 break;
722                 }
723                 if (mp->name) {
724                         printf("add-symbol-file %s/%s/%s.o 0x%0lx\n", path,
725                                mp->path, mp->name, modaddr);
726                 }
727         }
728
729         return 0;
730 }
731
732 int jt_dbg_modules(int argc, char **argv)
733 {
734         int rc = 0;
735         struct utsname sysinfo;
736
737         rc = uname(&sysinfo);
738         if (rc) {
739                 printf("uname() failed: %s\n", strerror(errno));
740                 return 0;
741         }
742
743         if (sysinfo.release[2] > '4') {
744                 return jt_dbg_modules_2_5(argc, argv);
745         } else {
746                 return jt_dbg_modules_2_4(argc, argv);
747         }
748
749         return 0;
750 }
751
752 int jt_dbg_panic(int argc, char **argv)
753 {
754         int rc;
755         struct portal_ioctl_data data;
756
757         if (argc != 1) {
758                 fprintf(stderr, "usage: %s\n", argv[0]);
759                 return 0;
760         }
761
762         memset(&data, 0, sizeof(data));
763         if (portal_ioctl_pack(&data, &buf, max) != 0) {
764                 fprintf(stderr, "portal_ioctl_pack failed.\n");
765                 return -1;
766         }
767
768         rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_PANIC, buf);
769         if (rc) {
770                 fprintf(stderr, "IOC_PORTAL_PANIC failed: %s\n",
771                         strerror(errno));
772                 return -1;
773         }
774         return 0;
775 }