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.
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <sys/ioctl.h>
41 #define BUG() /* workaround for module.h includes */
42 #include <linux/version.h>
44 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
45 #include <linux/module.h>
48 #include <portals/api-support.h>
49 #include <portals/ptlctl.h>
52 static char rawbuf[8192];
53 static char *buf = rawbuf;
54 static int max = 8192;
55 //static int g_pfd = -1;
56 static int subsystem_array[1 << 8];
57 static int debug_mask = ~0;
59 static const char *portal_debug_subsystems[] =
60 {"undefined", "mdc", "mds", "osc", "ost", "class", "obdfs", "llite",
61 "rpc", "ext2obd", "portals", "socknal", "qswnal", "pinger", "filter",
62 "obdtrace", "echo", "ldlm", "lov", "gmnal", "router", "ptldb", NULL};
63 static const char *portal_debug_masks[] =
64 {"trace", "inode", "super", "ext2", "malloc", "cache", "info", "ioctl",
65 "blocks", "net", "warning", "buffs", "other", "dentry", "portals",
66 "page", "dlmtrace", "error", "emerg", "ha", "rpctrace", "vfstrace", NULL};
68 struct debug_daemon_cmd {
73 static const struct debug_daemon_cmd portal_debug_daemon_cmd[] = {
74 {"start", DEBUG_DAEMON_START},
75 {"stop", DEBUG_DAEMON_STOP},
76 {"pause", DEBUG_DAEMON_PAUSE},
77 {"continue", DEBUG_DAEMON_CONTINUE},
81 static int do_debug_mask(char *name, int enable)
85 for (i = 0; portal_debug_subsystems[i] != NULL; i++) {
86 if (strcasecmp(name, portal_debug_subsystems[i]) == 0 ||
87 strcasecmp(name, "all_subs") == 0) {
88 printf("%s output from subsystem \"%s\"\n",
89 enable ? "Enabling" : "Disabling",
90 portal_debug_subsystems[i]);
91 subsystem_array[i] = enable;
95 for (i = 0; portal_debug_masks[i] != NULL; i++) {
96 if (strcasecmp(name, portal_debug_masks[i]) == 0 ||
97 strcasecmp(name, "all_types") == 0) {
98 printf("%s output of type \"%s\"\n",
99 enable ? "Enabling" : "Disabling",
100 portal_debug_masks[i]);
102 debug_mask |= (1 << i);
104 debug_mask &= ~(1 << i);
112 int dbg_initialize(int argc, char **argv)
114 memset(subsystem_array, 1, sizeof(subsystem_array));
118 int jt_dbg_filter(int argc, char **argv)
123 fprintf(stderr, "usage: %s <subsystem ID or debug mask>\n",
128 for (i = 1; i < argc; i++)
129 if (!do_debug_mask(argv[i], 0))
130 fprintf(stderr, "Unknown subsystem or debug type: %s\n",
135 int jt_dbg_show(int argc, char **argv)
140 fprintf(stderr, "usage: %s <subsystem ID or debug mask>\n",
145 for (i = 1; i < argc; i++)
146 if (!do_debug_mask(argv[i], 1))
147 fprintf(stderr, "Unknown subsystem or debug type: %s\n",
153 static int applymask(char* procpath, int value)
157 int len = snprintf(buf, 64, "%d", value);
159 int fd = open(procpath, O_WRONLY);
161 fprintf(stderr, "Unable to open %s: %s\n",
162 procpath, strerror(errno));
165 rc = write(fd, buf, len+1);
167 fprintf(stderr, "Write to %s failed: %s\n",
168 procpath, strerror(errno));
175 extern char *dump_filename;
176 extern int dump(int dev_id, int opc, void *buf);
178 static void applymask_all(unsigned int subs_mask, unsigned int debug_mask)
180 if (!dump_filename) {
181 applymask("/proc/sys/portals/subsystem_debug", subs_mask);
182 applymask("/proc/sys/portals/debug", debug_mask);
184 struct portals_debug_ioctl_data data;
186 data.hdr.ioc_len = sizeof(data);
187 data.hdr.ioc_version = 0;
188 data.subs = subs_mask;
189 data.debug = debug_mask;
191 dump(OBD_DEV_ID, PTL_IOC_DEBUG_MASK, &data);
193 printf("Applied subsystem_debug=%d, debug=%d to /proc/sys/portals\n",
194 subs_mask, debug_mask);
197 int jt_dbg_list(int argc, char **argv)
202 fprintf(stderr, "usage: %s <subs || types>\n", argv[0]);
206 if (strcasecmp(argv[1], "subs") == 0) {
207 printf("Subsystems: all_subs");
208 for (i = 0; portal_debug_subsystems[i] != NULL; i++)
209 printf(", %s", portal_debug_subsystems[i]);
211 } else if (strcasecmp(argv[1], "types") == 0) {
212 printf("Types: all_types");
213 for (i = 0; portal_debug_masks[i] != NULL; i++)
214 printf(", %s", portal_debug_masks[i]);
217 else if (strcasecmp(argv[1], "applymasks") == 0) {
218 unsigned int subsystem_mask = 0;
219 for (i = 0; portal_debug_subsystems[i] != NULL; i++) {
220 if (subsystem_array[i]) subsystem_mask |= (1 << i);
222 applymask_all(subsystem_mask, debug_mask);
227 /* if 'raw' is true, don't strip the debug information from the front of the
229 static void dump_buffer(FILE *fd, char *buf, int size, int raw)
232 unsigned long subsystem, debug, dropped = 0, kept = 0;
233 int max_sub, max_type;
235 for (max_sub = 0; portal_debug_subsystems[max_sub] != NULL; max_sub++)
237 for (max_type = 0; portal_debug_masks[max_type] != NULL; max_type++)
241 p = memchr(buf, '\n', size);
244 subsystem = strtoul(buf, &z, 16);
245 debug = strtoul(z + 1, &z, 16);
248 /* for some reason %*s isn't working. */
250 if (subsystem < max_sub &&
251 subsystem_array[subsystem] &&
252 (!debug || (debug_mask & debug))) {
254 fprintf(fd, "%s\n", buf);
256 fprintf(fd, "%s\n", z);
257 //printf("%s\n", buf);
260 //fprintf(stderr, "dropping line (%lx:%lx): %s\n", subsystem, debug, buf);
269 printf("Debug log: %lu lines, %lu kept, %lu dropped.\n",
270 dropped + kept, kept, dropped);
273 int jt_dbg_debug_kernel(int argc, char **argv)
277 const int databuf_size = (6 << 20);
278 struct portal_ioctl_data data, *newdata;
279 char *databuf = NULL;
282 fprintf(stderr, "usage: %s [file] [raw]\n", argv[0]);
287 fd = fopen(argv[1], "w");
289 fprintf(stderr, "fopen(%s) failed: %s\n", argv[1],
297 databuf = malloc(databuf_size);
299 fprintf(stderr, "No memory for buffer.\n");
303 memset(&data, 0, sizeof(data));
304 data.ioc_plen1 = databuf_size;
305 data.ioc_pbuf1 = databuf;
307 if (portal_ioctl_pack(&data, &buf, max) != 0) {
308 fprintf(stderr, "portal_ioctl_pack failed.\n");
312 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_DEBUG, buf);
314 fprintf(stderr, "IOC_PORTAL_GET_DEBUG failed: %s\n",
319 newdata = (struct portal_ioctl_data *)buf;
320 if (newdata->ioc_size > 0)
321 dump_buffer(fd, databuf, newdata->ioc_size, raw);
331 int jt_dbg_debug_daemon(int argc, char **argv)
334 unsigned int cmd = 0;
336 struct portal_ioctl_data data;
339 fprintf(stderr, "usage: %s [start file <#MB>|stop|pause|"
340 "continue]\n", argv[0]);
343 for (i = 0; portal_debug_daemon_cmd[i].cmd != NULL; i++) {
344 if (strcasecmp(argv[1], portal_debug_daemon_cmd[i].cmd) == 0) {
345 cmd = portal_debug_daemon_cmd[i].cmdv;
349 if (portal_debug_daemon_cmd[i].cmd == NULL) {
350 fprintf(stderr, "usage: %s [start file <#MB>|stop|pause|"
351 "continue]\n", argv[0]);
354 memset(&data, 0, sizeof(data));
355 if (cmd == DEBUG_DAEMON_START) {
357 fprintf(stderr, "usage: %s [start file <#MB>|stop|"
358 "pause|continue]\n", argv[0]);
361 if (access(argv[2], F_OK) != 0) {
362 fd = fopen(argv[2], "w");
369 if (access(argv[2], W_OK) == 0)
371 fprintf(stderr, "fopen(%s) failed: %s\n", argv[2],
375 data.ioc_inllen1 = strlen(argv[2]) + 1;
376 data.ioc_inlbuf1 = argv[2];
381 size = strtoul(argv[3], NULL, 0);
383 fprintf(stderr, "file size(%s): error %s\n",
384 argv[3], strerror(errno));
387 data.ioc_misc = size;
390 data.ioc_count = cmd;
391 if (portal_ioctl_pack(&data, &buf, max) != 0) {
392 fprintf(stderr, "portal_ioctl_pack failed.\n");
395 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_SET_DAEMON, buf);
397 fprintf(stderr, "IOC_PORTAL_SET_DEMON failed: %s\n",
404 int jt_dbg_debug_file(int argc, char **argv)
406 int rc, fd = -1, raw = 1;
407 FILE *output = stdout;
408 char *databuf = NULL;
411 if (argc > 4 || argc < 2) {
412 fprintf(stderr, "usage: %s <input> [output] [raw]\n", argv[0]);
416 fd = open(argv[1], O_RDONLY);
418 fprintf(stderr, "fopen(%s) failed: %s\n", argv[1],
422 #warning FIXME: cleanup fstat issue here
424 #define __SYS_fstat__ SYS_fstat
426 #define __SYS_fstat__ SYS_fstat64
428 rc = syscall(__SYS_fstat__, fd, &statbuf);
430 fprintf(stderr, "fstat failed: %s\n", strerror(errno));
435 output = fopen(argv[2], "w");
436 if (output == NULL) {
437 fprintf(stderr, "fopen(%s) failed: %s\n", argv[2],
446 databuf = mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE,
448 if (databuf == NULL) {
449 fprintf(stderr, "mmap failed: %s\n", strerror(errno));
453 dump_buffer(output, databuf, statbuf.st_size, raw);
457 munmap(databuf, statbuf.st_size);
458 if (output != stdout)
465 int jt_dbg_clear_debug_buf(int argc, char **argv)
468 struct portal_ioctl_data data;
471 fprintf(stderr, "usage: %s\n", argv[0]);
475 memset(&data, 0, sizeof(data));
476 if (portal_ioctl_pack(&data, &buf, max) != 0) {
477 fprintf(stderr, "portal_ioctl_pack failed.\n");
481 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_CLEAR_DEBUG, buf);
483 fprintf(stderr, "IOC_PORTAL_CLEAR_DEBUG failed: %s\n",
490 int jt_dbg_mark_debug_buf(int argc, char **argv)
493 struct portal_ioctl_data data;
495 time_t now = time(NULL);
498 fprintf(stderr, "usage: %s [marker text]\n", argv[0]);
506 text[strlen(text) - 1] = '\0'; /* stupid \n */
509 memset(&data, 0, sizeof(data));
510 data.ioc_inllen1 = strlen(text) + 1;
511 data.ioc_inlbuf1 = text;
512 if (portal_ioctl_pack(&data, &buf, max) != 0) {
513 fprintf(stderr, "portal_ioctl_pack failed.\n");
517 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_MARK_DEBUG, buf);
519 fprintf(stderr, "IOC_PORTAL_MARK_DEBUG failed: %s\n",
527 int jt_dbg_modules(int argc, char **argv)
529 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
532 } *mp, mod_paths[] = {
533 {"portals", "lustre/portals/libcfs"},
534 {"ksocknal", "lustre/portals/knals/socknal"},
535 {"obdclass", "lustre/obdclass"},
536 {"ptlrpc", "lustre/ptlrpc"},
537 {"obdext2", "lustre/obdext2"},
538 {"ost", "lustre/ost"},
539 {"osc", "lustre/osc"},
540 {"mds", "lustre/mds"},
541 {"mdc", "lustre/mdc"},
542 {"llite", "lustre/llite"},
543 {"obdecho", "lustre/obdecho"},
544 {"ldlm", "lustre/ldlm"},
545 {"obdfilter", "lustre/obdfilter"},
546 {"extN", "lustre/extN"},
547 {"lov", "lustre/lov"},
548 {"fsfilt_ext3", "lustre/obdclass"},
549 {"fsfilt_extN", "lustre/obdclass"},
550 {"mds_ext2", "lustre/mds"},
551 {"mds_ext3", "lustre/mds"},
552 {"mds_extN", "lustre/mds"},
553 {"ptlbd", "lustre/ptlbd"},
557 char *kernel = "linux";
564 printf("%s [path] [kernel]\n", argv[0]);
568 for (mp = mod_paths; mp->name != NULL; mp++) {
569 struct module_info info;
572 int query_module(const char *name, int which, void *buf,
573 size_t bufsize, size_t *ret);
575 rc = query_module(mp->name, QM_INFO, &info, sizeof(info),
579 printf("query_module(%s) failed: %s\n",
580 mp->name, strerror(errno));
582 printf("add-symbol-file %s/%s/%s.o 0x%0lx\n", path,
584 info.addr + sizeof(struct module));
590 printf("jt_dbg_module is not yet implemented for Linux 2.5\n");
592 #endif /* linux 2.5 */
595 int jt_dbg_panic(int argc, char **argv)
598 struct portal_ioctl_data data;
601 fprintf(stderr, "usage: %s\n", argv[0]);
605 memset(&data, 0, sizeof(data));
606 if (portal_ioctl_pack(&data, &buf, max) != 0) {
607 fprintf(stderr, "portal_ioctl_pack failed.\n");
611 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_PANIC, buf);
613 fprintf(stderr, "IOC_PORTAL_PANIC failed: %s\n",