1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
6 * This file is part of Portals, http://www.sf.net/projects/lustre/
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.
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.
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.
21 * Some day I'll split all of this functionality into a cfs_debug module
22 * of its own. That day is not today.
26 #define __USE_FILE_OFFSET64
40 #include <sys/types.h>
41 #include <sys/socket.h>
42 #include <sys/ioctl.h>
46 #include <linux/version.h>
48 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
49 #define BUG() /* workaround for module.h includes */
50 #include <linux/module.h>
53 #include <portals/api-support.h>
54 #include <portals/ptlctl.h>
57 static char rawbuf[8192];
58 static char *buf = rawbuf;
59 static int max = 8192;
60 //static int g_pfd = -1;
61 static int subsystem_mask = ~0;
62 static int debug_mask = ~0;
64 #define MAX_MARK_SIZE 100
66 static const char *portal_debug_subsystems[] =
67 {"undefined", "mdc", "mds", "osc", "ost", "class", "log", "llite",
68 "rpc", "mgmt", "portals", "libcfs", "socknal", "qswnal", "pinger",
69 "filter", "ptlbd", "echo", "ldlm", "lov", "gmnal", "router", "cobd",
71 static const char *portal_debug_masks[] =
72 {"trace", "inode", "super", "ext2", "malloc", "cache", "info", "ioctl",
73 "blocks", "net", "warning", "buffs", "other", "dentry", "portals",
74 "page", "dlmtrace", "error", "emerg", "ha", "rpctrace", "vfstrace",
77 struct debug_daemon_cmd {
82 static const struct debug_daemon_cmd portal_debug_daemon_cmd[] = {
83 {"start", DEBUG_DAEMON_START},
84 {"stop", DEBUG_DAEMON_STOP},
85 {"pause", DEBUG_DAEMON_PAUSE},
86 {"continue", DEBUG_DAEMON_CONTINUE},
90 static int do_debug_mask(char *name, int enable)
94 for (i = 0; portal_debug_subsystems[i] != NULL; i++) {
95 if (strcasecmp(name, portal_debug_subsystems[i]) == 0 ||
96 strcasecmp(name, "all_subs") == 0) {
97 printf("%s output from subsystem \"%s\"\n",
98 enable ? "Enabling" : "Disabling",
99 portal_debug_subsystems[i]);
101 subsystem_mask |= (1 << i);
103 subsystem_mask &= ~(1 << i);
107 for (i = 0; portal_debug_masks[i] != NULL; i++) {
108 if (strcasecmp(name, portal_debug_masks[i]) == 0 ||
109 strcasecmp(name, "all_types") == 0) {
110 printf("%s output of type \"%s\"\n",
111 enable ? "Enabling" : "Disabling",
112 portal_debug_masks[i]);
114 debug_mask |= (1 << i);
116 debug_mask &= ~(1 << i);
124 int dbg_initialize(int argc, char **argv)
129 int jt_dbg_filter(int argc, char **argv)
134 fprintf(stderr, "usage: %s <subsystem ID or debug mask>\n",
139 for (i = 1; i < argc; i++)
140 if (!do_debug_mask(argv[i], 0))
141 fprintf(stderr, "Unknown subsystem or debug type: %s\n",
146 int jt_dbg_show(int argc, char **argv)
151 fprintf(stderr, "usage: %s <subsystem ID or debug mask>\n",
156 for (i = 1; i < argc; i++)
157 if (!do_debug_mask(argv[i], 1))
158 fprintf(stderr, "Unknown subsystem or debug type: %s\n",
164 static int applymask(char* procpath, int value)
168 int len = snprintf(buf, 64, "%d", value);
170 int fd = open(procpath, O_WRONLY);
172 fprintf(stderr, "Unable to open %s: %s\n",
173 procpath, strerror(errno));
176 rc = write(fd, buf, len+1);
178 fprintf(stderr, "Write to %s failed: %s\n",
179 procpath, strerror(errno));
186 static void applymask_all(unsigned int subs_mask, unsigned int debug_mask)
188 if (!dump_filename) {
189 applymask("/proc/sys/portals/subsystem_debug", subs_mask);
190 applymask("/proc/sys/portals/debug", debug_mask);
192 struct portals_debug_ioctl_data data;
194 data.hdr.ioc_len = sizeof(data);
195 data.hdr.ioc_version = 0;
196 data.subs = subs_mask;
197 data.debug = debug_mask;
199 dump(OBD_DEV_ID, PTL_IOC_DEBUG_MASK, &data);
201 printf("Applied subsystem_debug=%d, debug=%d to /proc/sys/portals\n",
202 subs_mask, debug_mask);
205 int jt_dbg_list(int argc, char **argv)
210 fprintf(stderr, "usage: %s <subs || types>\n", argv[0]);
214 if (strcasecmp(argv[1], "subs") == 0) {
215 printf("Subsystems: all_subs");
216 for (i = 0; portal_debug_subsystems[i] != NULL; i++)
217 printf(", %s", portal_debug_subsystems[i]);
219 } else if (strcasecmp(argv[1], "types") == 0) {
220 printf("Types: all_types");
221 for (i = 0; portal_debug_masks[i] != NULL; i++)
222 printf(", %s", portal_debug_masks[i]);
224 } else if (strcasecmp(argv[1], "applymasks") == 0) {
225 applymask_all(subsystem_mask, debug_mask);
230 /* if 'raw' is true, don't strip the debug information from the front of the
232 static void dump_buffer(FILE *fd, char *buf, int size, int raw)
235 unsigned long subsystem, debug, dropped = 0, kept = 0;
238 p = memchr(buf, '\n', size);
241 subsystem = strtoul(buf, &z, 16);
242 debug = strtoul(z + 1, &z, 16);
245 /* for some reason %*s isn't working. */
247 if ((subsystem_mask & subsystem) &&
248 (!debug || (debug_mask & debug))) {
250 fprintf(fd, "%s\n", buf);
252 fprintf(fd, "%s\n", z);
253 //printf("%s\n", buf);
256 //fprintf(stderr, "dropping line (%lx:%lx): %s\n", subsystem, debug, buf);
265 printf("Debug log: %lu lines, %lu kept, %lu dropped.\n",
266 dropped + kept, kept, dropped);
269 int jt_dbg_debug_kernel(int argc, char **argv)
273 const int databuf_size = (6 << 20);
274 struct portal_ioctl_data data, *newdata;
275 char *databuf = NULL;
278 fprintf(stderr, "usage: %s [file] [raw]\n", argv[0]);
283 fd = fopen(argv[1], "w");
285 fprintf(stderr, "fopen(%s) failed: %s\n", argv[1],
293 databuf = malloc(databuf_size);
295 fprintf(stderr, "No memory for buffer.\n");
299 memset(&data, 0, sizeof(data));
300 data.ioc_plen1 = databuf_size;
301 data.ioc_pbuf1 = databuf;
303 if (portal_ioctl_pack(&data, &buf, max) != 0) {
304 fprintf(stderr, "portal_ioctl_pack failed.\n");
308 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_DEBUG, buf);
310 fprintf(stderr, "IOC_PORTAL_GET_DEBUG failed: %s\n",
315 newdata = (struct portal_ioctl_data *)buf;
316 if (newdata->ioc_size > 0)
317 dump_buffer(fd, databuf, newdata->ioc_size, raw);
327 int jt_dbg_debug_daemon(int argc, char **argv)
330 unsigned int cmd = 0;
332 struct portal_ioctl_data data;
335 fprintf(stderr, "usage: %s [start file <#MB>|stop|pause|"
336 "continue]\n", argv[0]);
339 for (i = 0; portal_debug_daemon_cmd[i].cmd != NULL; i++) {
340 if (strcasecmp(argv[1], portal_debug_daemon_cmd[i].cmd) == 0) {
341 cmd = portal_debug_daemon_cmd[i].cmdv;
345 if (portal_debug_daemon_cmd[i].cmd == NULL) {
346 fprintf(stderr, "usage: %s [start file <#MB>|stop|pause|"
347 "continue]\n", argv[0]);
350 memset(&data, 0, sizeof(data));
351 if (cmd == DEBUG_DAEMON_START) {
353 fprintf(stderr, "usage: %s [start file <#MB>|stop|"
354 "pause|continue]\n", argv[0]);
357 if (access(argv[2], F_OK) != 0) {
358 fd = fopen(argv[2], "w");
365 if (access(argv[2], W_OK) == 0)
367 fprintf(stderr, "fopen(%s) failed: %s\n", argv[2],
371 data.ioc_inllen1 = strlen(argv[2]) + 1;
372 data.ioc_inlbuf1 = argv[2];
377 size = strtoul(argv[3], NULL, 0);
379 fprintf(stderr, "file size(%s): error %s\n",
380 argv[3], strerror(errno));
383 data.ioc_misc = size;
386 data.ioc_count = cmd;
387 if (portal_ioctl_pack(&data, &buf, max) != 0) {
388 fprintf(stderr, "portal_ioctl_pack failed.\n");
391 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_SET_DAEMON, buf);
393 fprintf(stderr, "IOC_PORTAL_SET_DEMON failed: %s\n",
400 int jt_dbg_debug_file(int argc, char **argv)
402 int rc, fd = -1, raw = 1;
403 FILE *output = stdout;
404 char *databuf = NULL;
407 if (argc > 4 || argc < 2) {
408 fprintf(stderr, "usage: %s <input> [output] [raw]\n", argv[0]);
412 fd = open(argv[1], O_RDONLY);
414 fprintf(stderr, "fopen(%s) failed: %s\n", argv[1],
419 rc = fstat(fd, &statbuf);
421 fprintf(stderr, "fstat failed: %s\n", strerror(errno));
426 output = fopen(argv[2], "w");
427 if (output == NULL) {
428 fprintf(stderr, "fopen(%s) failed: %s\n", argv[2],
437 databuf = mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE,
439 if (databuf == NULL) {
440 fprintf(stderr, "mmap failed: %s\n", strerror(errno));
444 dump_buffer(output, databuf, statbuf.st_size, raw);
448 munmap(databuf, statbuf.st_size);
449 if (output != stdout)
456 int jt_dbg_clear_debug_buf(int argc, char **argv)
459 struct portal_ioctl_data data;
462 fprintf(stderr, "usage: %s\n", argv[0]);
466 memset(&data, 0, sizeof(data));
467 if (portal_ioctl_pack(&data, &buf, max) != 0) {
468 fprintf(stderr, "portal_ioctl_pack failed.\n");
472 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_CLEAR_DEBUG, buf);
474 fprintf(stderr, "IOC_PORTAL_CLEAR_DEBUG failed: %s\n",
481 int jt_dbg_mark_debug_buf(int argc, char **argv)
483 int rc, max_size = MAX_MARK_SIZE-1;
484 struct portal_ioctl_data data;
486 time_t now = time(NULL);
490 text = malloc(MAX_MARK_SIZE);
491 strncpy(text, argv[1], max_size);
492 max_size-=strlen(argv[1]);
493 for(counter = 2; (counter < argc) && (max_size > 0) ; counter++){
494 strncat(text, " ", 1);
496 strncat(text, argv[counter], max_size);
497 max_size-=strlen(argv[counter]);
501 text[strlen(text) - 1] = '\0'; /* stupid \n */
504 text[MAX_MARK_SIZE - 1] = '\0';
507 memset(&data, 0, sizeof(data));
508 data.ioc_inllen1 = strlen(text) + 1;
509 data.ioc_inlbuf1 = text;
510 if (portal_ioctl_pack(&data, &buf, max) != 0) {
511 fprintf(stderr, "portal_ioctl_pack failed.\n");
515 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_MARK_DEBUG, buf);
517 fprintf(stderr, "IOC_PORTAL_MARK_DEBUG failed: %s\n",
524 static struct mod_paths {
527 {"libcfs", "lustre/portals/libcfs"},
528 {"portals", "lustre/portals/portals"},
529 {"ksocknal", "lustre/portals/knals/socknal"},
530 {"kptlrouter", "lustre/portals/router"},
531 {"lvfs", "lustre/lvfs"},
532 {"obdclass", "lustre/obdclass"},
533 {"llog_test", "lustre/obdclass"},
534 {"ptlrpc", "lustre/ptlrpc"},
535 {"obdext2", "lustre/obdext2"},
536 {"ost", "lustre/ost"},
537 {"osc", "lustre/osc"},
538 {"mds", "lustre/mds"},
539 {"mdc", "lustre/mdc"},
540 {"llite", "lustre/llite"},
541 {"smfs", "lustre/smfs"},
542 {"obdecho", "lustre/obdecho"},
543 {"ldlm", "lustre/ldlm"},
544 {"obdfilter", "lustre/obdfilter"},
545 {"extN", "lustre/extN"},
546 {"lov", "lustre/lov"},
547 {"fsfilt_ext3", "lustre/lvfs"},
548 {"fsfilt_extN", "lustre/lvfs"},
549 {"fsfilt_reiserfs", "lustre/lvfs"},
550 {"fsfilt_smfs", "lustre/lvfs"},
551 {"mds_ext2", "lustre/mds"},
552 {"mds_ext3", "lustre/mds"},
553 {"mds_extN", "lustre/mds"},
554 {"ptlbd", "lustre/ptlbd"},
555 {"mgmt_svc", "lustre/mgmt"},
556 {"mgmt_cli", "lustre/mgmt"},
560 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
561 int jt_dbg_modules(int argc, char **argv)
563 struct mod_paths *mp;
565 char *kernel = "linux";
572 printf("%s [path] [kernel]\n", argv[0]);
576 for (mp = mod_paths; mp->name != NULL; mp++) {
577 struct module_info info;
580 int query_module(const char *name, int which, void *buf,
581 size_t bufsize, size_t *ret);
583 rc = query_module(mp->name, QM_INFO, &info, sizeof(info),
587 printf("query_module(%s) failed: %s\n",
588 mp->name, strerror(errno));
590 printf("add-symbol-file %s/%s/%s.o 0x%0lx\n", path,
592 info.addr + sizeof(struct module));
599 int jt_dbg_modules(int argc, char **argv)
601 struct mod_paths *mp;
603 char *kernel = "linux";
604 const char *proc = "/proc/modules";
605 char modname[128], others[128];
615 printf("%s [path] [kernel]\n", argv[0]);
619 file = fopen(proc, "r");
621 printf("failed open %s: %s\n", proc, strerror(errno));
625 while ((rc = fscanf(file, "%s %s %s %s %s %lx\n",
626 modname, others, others, others, others, &modaddr)) == 6) {
627 for (mp = mod_paths; mp->name != NULL; mp++) {
628 if (!strcmp(mp->name, modname))
632 printf("add-symbol-file %s/%s/%s.o 0x%0lx\n", path,
633 mp->path, mp->name, modaddr);
639 #endif /* linux 2.5 */
641 int jt_dbg_panic(int argc, char **argv)
644 struct portal_ioctl_data data;
647 fprintf(stderr, "usage: %s\n", argv[0]);
651 memset(&data, 0, sizeof(data));
652 if (portal_ioctl_pack(&data, &buf, max) != 0) {
653 fprintf(stderr, "portal_ioctl_pack failed.\n");
657 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_PANIC, buf);
659 fprintf(stderr, "IOC_PORTAL_PANIC failed: %s\n",