X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lnet%2Futils%2Fdebug.c;h=33699ff9327939b64022974eea6ff8418d0f4596;hb=f97446c2bc3dd023e93a7e20c53a264d6ca0cd43;hp=801ba95d218ab9f90812ce2db713d9e55a287ecf;hpb=654e8f531070b1b531fb3ff80a48a0302b2f6756;p=fs%2Flustre-release.git diff --git a/lnet/utils/debug.c b/lnet/utils/debug.c index 801ba95..33699ff 100644 --- a/lnet/utils/debug.c +++ b/lnet/utils/debug.c @@ -1,6 +1,4 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * +/* * GPL HEADER START * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -26,8 +24,10 @@ * GPL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2011, 2012, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -56,23 +56,8 @@ static int debug_mask = ~0; #define MAX_MARK_SIZE 256 -static const char *libcfs_debug_subsystems[] = - {"undefined", "mdc", "mds", "osc", - "ost", "class", "log", "llite", - "rpc", "mgmt", "lnet", "lnd", - "pinger", "filter", "", "echo", - "ldlm", "lov", "lquota", "", - "", "", "", "lmv", - "", "sec", "gss", "", - "mgc", "mgs", "fid", "fld", NULL}; -static const char *libcfs_debug_masks[] = - {"trace", "inode", "super", "ext2", - "malloc", "cache", "info", "ioctl", - "neterror", "net", "warning", "buffs", - "other", "dentry", "nettrace", "page", - "dlmtrace", "error", "emerg", "ha", - "rpctrace", "vfstrace", "reada", "mmap", - "config", "console", "quota", "sec", NULL}; +static const char *libcfs_debug_subsystems[] = LIBCFS_DEBUG_SUBSYS_NAMES; +static const char *libcfs_debug_masks[] = LIBCFS_DEBUG_MASKS_NAMES; #ifdef __linux__ @@ -353,23 +338,39 @@ static int cmp_rec(const void *p1, const void *p2) return 1; } -static void print_rec(struct dbg_line **linev, int used, FILE *out) +static void print_rec(struct dbg_line ***linevp, int used, int fdout) { + struct dbg_line **linev = *linevp; int i; + qsort(linev, used, sizeof(struct dbg_line *), cmp_rec); for (i = 0; i < used; i++) { struct dbg_line *line = linev[i]; struct ptldebug_header *hdr = line->hdr; - - fprintf(out, "%08x:%08x:%u:%u." LPU64 ":%u:%u:%u:(%s:%u:%s()) %s", - hdr->ph_subsys, hdr->ph_mask, hdr->ph_cpu_id, - hdr->ph_sec, (unsigned long long)hdr->ph_usec, - hdr->ph_stack, hdr->ph_pid, hdr->ph_extern_pid, - line->file, hdr->ph_line_num, line->fn, line->text); + char out[4097]; + char *buf = out; + int bytes; + ssize_t bytes_written; + + bytes = sprintf(out, "%08x:%08x:%u.%u%s:%u.%06llu:%u:%u:%u:(%s:%u:%s()) %s", + hdr->ph_subsys, hdr->ph_mask, + hdr->ph_cpu_id, hdr->ph_type, + hdr->ph_flags & PH_FLAG_FIRST_RECORD ? "F" : "", + hdr->ph_sec, (unsigned long long)hdr->ph_usec, + hdr->ph_stack, hdr->ph_pid, hdr->ph_extern_pid, + line->file, hdr->ph_line_num, line->fn, line->text); + while (bytes > 0) { + bytes_written = write(fdout, buf, bytes); + if (bytes_written <= 0) + break; + bytes -= bytes_written; + buf += bytes_written; + } free(line->hdr); free(line); } free(linev); + *linevp = NULL; } static int add_rec(struct dbg_line *line, struct dbg_line ***linevp, int *lenp, @@ -378,96 +379,184 @@ static int add_rec(struct dbg_line *line, struct dbg_line ***linevp, int *lenp, struct dbg_line **linev = *linevp; if (used == *lenp) { - int nlen = *lenp + 512; + int nlen = *lenp + 4096; int nsize = nlen * sizeof(struct dbg_line *); - linev = *linevp ? realloc(*linevp, nsize) : malloc(nsize); + linev = realloc(*linevp, nsize); if (!linev) - return 0; + return -ENOMEM; + *linevp = linev; *lenp = nlen; } - linev[used] = line; - return 1; -} + linev[used] = line; -static int parse_buffer(FILE *in, FILE *out) + return 0; +} + +static void dump_hdr(unsigned long long offset, struct ptldebug_header *hdr) +{ + fprintf(stderr, "badly-formed record at offset = %llu\n", offset); + fprintf(stderr, " len = %u\n", hdr->ph_len); + fprintf(stderr, " flags = %x\n", hdr->ph_flags); + fprintf(stderr, " subsystem = %x\n", hdr->ph_subsys); + fprintf(stderr, " mask = %x\n", hdr->ph_mask); + fprintf(stderr, " cpu_id = %u\n", hdr->ph_cpu_id); + fprintf(stderr, " type = %u\n", hdr->ph_type); + fprintf(stderr, " seconds = %u\n", hdr->ph_sec); + fprintf(stderr, " microseconds = %lu\n", (long)hdr->ph_usec); + fprintf(stderr, " stack = %u\n", hdr->ph_stack); + fprintf(stderr, " pid = %u\n", hdr->ph_pid); + fprintf(stderr, " host pid = %u\n", hdr->ph_extern_pid); + fprintf(stderr, " line number = %u\n", hdr->ph_line_num); +} + +#define HDR_SIZE sizeof(*hdr) + +static int parse_buffer(int fdin, int fdout) { struct dbg_line *line; struct ptldebug_header *hdr; - char buf[4097], *p; - int rc; - unsigned long dropped = 0, kept = 0; + char buf[4097], *ptr; + unsigned long dropped = 0, kept = 0, bad = 0; struct dbg_line **linev = NULL; int linev_len = 0; - + int rc; + + hdr = (void *)buf; + while (1) { - rc = fread(buf, sizeof(hdr->ph_len) + sizeof(hdr->ph_flags), 1, in); + int first_bad = 1; + int count; + + count = HDR_SIZE; + ptr = buf; + readhdr: + rc = read(fdin, ptr, count); if (rc <= 0) - break; + goto print; + + ptr += rc; + count -= rc; + if (count > 0) + goto readhdr; + + if (hdr->ph_len > 4094 || /* is this header bogus? */ + hdr->ph_type >= libcfs_tcd_type_max() || + hdr->ph_stack > 65536 || + hdr->ph_sec < (1 << 30) || + hdr->ph_usec > 1000000000 || + hdr->ph_line_num > 65536) { + if (first_bad) + dump_hdr(lseek(fdin, 0, SEEK_CUR), hdr); + bad += first_bad; + first_bad = 0; + + /* try to restart on next line */ + while (count < HDR_SIZE && buf[count] != '\n') + count++; + if (buf[count] == '\n') + count++; /* move past '\n' */ + if (HDR_SIZE - count > 0) { + int left = HDR_SIZE - count; + + memmove(buf, buf + count, left); + ptr = buf + left; + + goto readhdr; + } - hdr = (void *)buf; - if (hdr->ph_len == 0) - break; - if (hdr->ph_len > 4094) { - fprintf(stderr, "unexpected large record: %d bytes. " - "aborting.\n", - hdr->ph_len); - break; + continue; } + + if (hdr->ph_len == 0) + continue; - rc = fread(buf + sizeof(hdr->ph_len) + sizeof(hdr->ph_flags), 1, - hdr->ph_len - sizeof(hdr->ph_len) - sizeof(hdr->ph_flags), in); + count = hdr->ph_len - HDR_SIZE; + readmore: + rc = read(fdin, ptr, count); if (rc <= 0) break; + + ptr += rc; + count -= rc; + if (count > 0) + goto readmore; + + first_bad = 1; if ((hdr->ph_subsys && !(subsystem_mask & hdr->ph_subsys)) || - (hdr->ph_mask && !(debug_mask & hdr->ph_mask))) { + (hdr->ph_mask && !(debug_mask & hdr->ph_mask))) { dropped++; continue; } - + + retry_alloc: line = malloc(sizeof(*line)); if (line == NULL) { - fprintf(stderr, "malloc failed; printing accumulated " - "records and exiting.\n"); + if (linev) { + fprintf(stderr, "error: line malloc(%u): " + "printing accumulated records\n", + (unsigned int)sizeof(*line)); + print_rec(&linev, kept, fdout); + + goto retry_alloc; + } + fprintf(stderr, "error: line malloc(%u): exiting\n", + (unsigned int)sizeof(*line)); break; } line->hdr = malloc(hdr->ph_len + 1); if (line->hdr == NULL) { free(line); - fprintf(stderr, "malloc failed; printing accumulated " - "records and exiting.\n"); + if (linev) { + fprintf(stderr, "error: hdr malloc(%u): " + "printing accumulated records\n", + hdr->ph_len + 1); + print_rec(&linev, kept, fdout); + + goto retry_alloc; + } + fprintf(stderr, "error: hdr malloc(%u): exiting\n", + hdr->ph_len + 1); break; } - - p = (void *)line->hdr; + + ptr = (void *)line->hdr; memcpy(line->hdr, buf, hdr->ph_len); - p[hdr->ph_len] = '\0'; - - p += sizeof(*hdr); - line->file = p; - p += strlen(line->file) + 1; - line->fn = p; - p += strlen(line->fn) + 1; - line->text = p; - - if (!add_rec(line, &linev, &linev_len, kept)) { - fprintf(stderr, "malloc failed; printing accumulated " - "records and exiting.\n"); + ptr[hdr->ph_len] = '\0'; + + ptr += sizeof(*hdr); + line->file = ptr; + ptr += strlen(line->file) + 1; + line->fn = ptr; + ptr += strlen(line->fn) + 1; + line->text = ptr; + + retry_add: + if (add_rec(line, &linev, &linev_len, kept) < 0) { + if (linev) { + fprintf(stderr, "error: add_rec[%u] failed; " + "print accumulated records\n", + linev_len); + print_rec(&linev, kept, fdout); + + goto retry_add; + } + fprintf(stderr, "error: add_rec[0] failed; exiting\n"); break; - } + } kept++; } - if (linev) { - qsort(linev, kept, sizeof(struct dbg_line *), cmp_rec); - print_rec(linev, kept, out); - } +print: + if (linev) + print_rec(&linev, kept, fdout); + + printf("Debug log: %lu lines, %lu kept, %lu dropped, %lu bad.\n", + dropped + kept + bad, kept, dropped, bad); - printf("Debug log: %lu lines, %lu kept, %lu dropped.\n", - dropped + kept, kept, dropped); return 0; } @@ -475,8 +564,11 @@ int jt_dbg_debug_kernel(int argc, char **argv) { char filename[4096]; struct stat st; - int rc, raw = 0, fd; - FILE *in, *out = stdout; + int raw = 0; + int save_errno; + int fdin; + int fdout; + int rc; if (argc > 3) { fprintf(stderr, "usage: %s [file] [raw]\n", argv[0]); @@ -497,53 +589,55 @@ int jt_dbg_debug_kernel(int argc, char **argv) strcpy(filename, argv[1]); else sprintf(filename, "%s"CFS_TIME_T".%u", - DEBUG_FILE_PATH_DEFAULT, time(NULL), getpid()); + LIBCFS_DEBUG_FILE_PATH_DEFAULT, time(NULL), getpid()); if (stat(filename, &st) == 0 && S_ISREG(st.st_mode)) unlink(filename); - fd = dbg_open_ctlhandle(DUMP_KERNEL_CTL_NAME); - if (fd < 0) { + fdin = dbg_open_ctlhandle(DUMP_KERNEL_CTL_NAME); + if (fdin < 0) { fprintf(stderr, "open(dump_kernel) failed: %s\n", strerror(errno)); return 1; } - rc = dbg_write_cmd(fd, filename, strlen(filename)); + rc = dbg_write_cmd(fdin, filename, strlen(filename)); + save_errno = errno; + dbg_close_ctlhandle(fdin); if (rc != 0) { fprintf(stderr, "write(%s) failed: %s\n", filename, - strerror(errno)); - dbg_close_ctlhandle(fd); + strerror(save_errno)); return 1; } - dbg_close_ctlhandle(fd); if (raw) return 0; - in = fopen(filename, "r"); - if (in == NULL) { + fdin = open(filename, O_RDONLY); + if (fdin < 0) { if (errno == ENOENT) /* no dump file created */ return 0; - fprintf(stderr, "fopen(%s) failed: %s\n", filename, strerror(errno)); return 1; } if (argc > 1) { - out = fopen(argv[1], "w"); - if (out == NULL) { + fdout = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR); + if (fdout < 0) { fprintf(stderr, "fopen(%s) failed: %s\n", argv[1], strerror(errno)); - fclose(in); + close(fdin); return 1; } - } + } else { + fdout = fileno(stdout); + } - rc = parse_buffer(in, out); - fclose(in); + rc = parse_buffer(fdin, fdout); + close(fdin); if (argc > 1) - fclose(out); + close(fdout); if (rc) { fprintf(stderr, "parse_buffer failed; leaving tmp file %s " "behind.\n", filename); @@ -554,6 +648,7 @@ int jt_dbg_debug_kernel(int argc, char **argv) "unlink tmp file %s: %s\n", filename, strerror(errno)); } + return rc; } @@ -561,8 +656,6 @@ int jt_dbg_debug_file(int argc, char **argv) { int fdin; int fdout; - FILE *in; - FILE *out = stdout; int rc; if (argc > 3 || argc < 2) { @@ -571,43 +664,30 @@ int jt_dbg_debug_file(int argc, char **argv) } fdin = open(argv[1], O_RDONLY | O_LARGEFILE); - if (fdin == -1) { + if (fdin < 0) { fprintf(stderr, "open(%s) failed: %s\n", argv[1], strerror(errno)); return 1; } - in = fdopen(fdin, "r"); - if (in == NULL) { - fprintf(stderr, "fopen(%s) failed: %s\n", argv[1], - strerror(errno)); - close(fdin); - return 1; - } if (argc > 2) { fdout = open(argv[2], O_CREAT | O_TRUNC | O_WRONLY | O_LARGEFILE, 0600); - if (fdout == -1) { + if (fdout < 0) { fprintf(stderr, "open(%s) failed: %s\n", argv[2], strerror(errno)); - fclose(in); - return 1; - } - out = fdopen(fdout, "w"); - if (out == NULL) { - fprintf(stderr, "fopen(%s) failed: %s\n", argv[2], - strerror(errno)); - fclose(in); - close(fdout); + close(fdin); return 1; } + } else { + fdout = fileno(stdout); } - rc = parse_buffer(in, out); + rc = parse_buffer(fdin, fdout); - fclose(in); - if (out != stdout) - fclose(out); + close(fdin); + if (fdout != fileno(stdout)) + close(fdout); return rc; } @@ -754,72 +834,57 @@ int jt_dbg_mark_debug_buf(int argc, char **argv) } static struct mod_paths { - char *name, *path; + char *name, *path; } mod_paths[] = { - {"libcfs", "libcfs/libcfs"}, - {"lnet", "lnet/lnet"}, - {"kciblnd", "lnet/klnds/ciblnd"}, - {"kgmlnd", "lnet/klnds/gmlnd"}, - {"kmxlnd", "lnet/klnds/mxlnd"}, - {"kiiblnd", "lnet/klnds/iiblnd"}, - {"ko2iblnd", "lnet/klnds/o2iblnd"}, - {"kopeniblnd", "lnet/klnds/openiblnd"}, - {"kptllnd", "lnet/klnds/ptllnd"}, - {"kqswlnd", "lnet/klnds/qswlnd"}, - {"kralnd", "lnet/klnds/ralnd"}, - {"ksocklnd", "lnet/klnds/socklnd"}, - {"ktdilnd", "lnet/klnds/tdilnd"}, - {"kviblnd", "lnet/klnds/viblnd"}, - {"lvfs", "lustre/lvfs"}, - {"obdclass", "lustre/obdclass"}, - {"llog_test", "lustre/obdclass"}, - {"ptlrpc_gss", "lustre/ptlrpc/gss"}, - {"ptlrpc", "lustre/ptlrpc"}, - {"gks", "lustre/sec/gks"}, - {"gkc", "lustre/sec/gks"}, - {"ost", "lustre/ost"}, - {"osc", "lustre/osc"}, - {"mds", "lustre/mds"}, - {"mdc", "lustre/mdc"}, - {"llite", "lustre/llite"}, - {"lustre", "lustre/llite"}, - {"llite_lloop", "lustre/llite"}, - {"ldiskfs", "ldiskfs/ldiskfs"}, - {"smfs", "lustre/smfs"}, - {"obdecho", "lustre/obdecho"}, - {"ldlm", "lustre/ldlm"}, - {"obdfilter", "lustre/obdfilter"}, - {"lov", "lustre/lov"}, - {"lmv", "lustre/lmv"}, - {"fsfilt_ext3", "lustre/lvfs"}, - {"fsfilt_reiserfs", "lustre/lvfs"}, - {"fsfilt_smfs", "lustre/lvfs"}, - {"fsfilt_ldiskfs", "lustre/lvfs"}, - {"mds_ext3", "lustre/mds"}, - {"cobd", "lustre/cobd"}, - {"cmobd", "lustre/cmobd"}, - {"lquota", "lustre/quota"}, - {"mgs", "lustre/mgs"}, - {"mgc", "lustre/mgc"}, - {"mdt", "lustre/mdt"}, - {"mdd", "lustre/mdd"}, - {"osd", "lustre/osd"}, - {"cmm", "lustre/cmm"}, + { "libcfs", "libcfs/libcfs" }, + { "lnet", "lnet/lnet" }, + { "kmxlnd", "lnet/klnds/mxlnd" }, + { "ko2iblnd", "lnet/klnds/o2iblnd" }, + { "kptllnd", "lnet/klnds/ptllnd" }, + { "kgnilnd", "lnet/klnds/gnilnd"}, + { "kqswlnd", "lnet/klnds/qswlnd" }, + { "kralnd", "lnet/klnds/ralnd" }, + { "ksocklnd", "lnet/klnds/socklnd" }, + { "ktdilnd", "lnet/klnds/tdilnd" }, + { "lvfs", "lustre/lvfs" }, + { "obdclass", "lustre/obdclass" }, + { "llog_test", "lustre/obdclass" }, + { "ptlrpc_gss", "lustre/ptlrpc/gss" }, + { "ptlrpc", "lustre/ptlrpc" }, + { "gks", "lustre/sec/gks" }, + { "gkc", "lustre/sec/gks" }, + { "ost", "lustre/ost" }, + { "osc", "lustre/osc" }, + { "mds", "lustre/mds" }, + { "mdc", "lustre/mdc" }, + { "lustre", "lustre/llite" }, + { "llite_lloop", "lustre/llite" }, + { "ldiskfs", "ldiskfs" }, + { "obdecho", "lustre/obdecho" }, + { "ldlm", "lustre/ldlm" }, + { "obdfilter", "lustre/obdfilter" }, + { "lov", "lustre/lov" }, + { "lmv", "lustre/lmv" }, + { "fsfilt_ldiskfs", "lustre/lvfs" }, + { "lquota", "lustre/quota" }, + { "mgs", "lustre/mgs" }, + { "mgc", "lustre/mgc" }, + { "mdt", "lustre/mdt" }, + { "mdd", "lustre/mdd" }, + { "osd", "lustre/osd" }, + { "cmm", "lustre/cmm" }, {"fid", "lustre/fid"}, {"fld", "lustre/fld"}, + {"lod", "lustre/lod"}, + {"osp", "lustre/osp"}, + { "lfsck", "lustre/lfsck" }, {NULL, NULL} }; -static int jt_dbg_modules_2_4(int argc, char **argv) -{ - return -EINVAL; -} - -static int jt_dbg_modules_2_5(int argc, char **argv) +int jt_dbg_modules(int argc, char **argv) { struct mod_paths *mp; char *path = ""; - char *kernel = "linux"; const char *proc = "/proc/modules"; char modname[128], buf[4096]; long modaddr; @@ -827,8 +892,6 @@ static int jt_dbg_modules_2_5(int argc, char **argv) if (argc >= 2) path = argv[1]; - if (argc == 3) - kernel = argv[2]; if (argc > 3) { printf("%s [path] [kernel]\n", argv[0]); return 0; @@ -846,11 +909,11 @@ static int jt_dbg_modules_2_5(int argc, char **argv) if (!strcmp(mp->name, modname)) break; } - if (mp->name) { - printf("add-symbol-file %s%s%s/%s.o 0x%0lx\n", - path, path[0] ? "/" : "", - mp->path, mp->name, modaddr); - } + if (mp->name) { + printf("add-symbol-file %s%s%s/%s.o 0x%0lx\n", + path, path[0] ? "/" : "", + mp->path, mp->name, modaddr); + } } } @@ -858,26 +921,6 @@ static int jt_dbg_modules_2_5(int argc, char **argv) return 0; } -int jt_dbg_modules(int argc, char **argv) -{ - int rc = 0; - struct utsname sysinfo; - - rc = uname(&sysinfo); - if (rc) { - printf("uname() failed: %s\n", strerror(errno)); - return 0; - } - - if (sysinfo.release[2] > '4') { - return jt_dbg_modules_2_5(argc, argv); - } else { - return jt_dbg_modules_2_4(argc, argv); - } - - return 0; -} - int jt_dbg_panic(int argc, char **argv) { int rc;