/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Module for MDB that modifies the behavior of ::lminfo to print the full path * of the vnode instead of truncating it and also to display the whence, start * and len values. * * You'll obviousuly want your terminal set fairly wide to view the output. * * Ray Van Dolson */ #include #include #include #include "mdb_ks.h" #define LM_VNPATHLEN 255 #define LM_OUTLEN 1024 static int lminfo_cb(uintptr_t addr, const void *data, void *priv) { const lock_descriptor_t *ld = data; char buf[LM_VNPATHLEN]; char outbuf[LM_OUTLEN]; char outbuf2[LM_OUTLEN]; char *q, *r; proc_t p; mdb_vnode2path((uintptr_t)ld->l_vnode, buf, sizeof (buf)); mdb_snprintf(outbuf, sizeof(outbuf), "%-?p %2s %04x %6d %-16s %-?p %-9d %-9d %-9d %s", addr, ld->l_type == F_RDLCK ? "RD" : ld->l_type == F_WRLCK ? "WR" : "??", ld->l_state, ld->l_flock.l_pid, ld->l_flock.l_pid == 0 ? "" : mdb_pid2proc(ld->l_flock.l_pid, &p) == NULL ? "" : p.p_user.u_comm, ld->l_vnode, ld->l_flock.l_whence, ld->l_flock.l_start, ld->l_flock.l_len, buf); /* * mdb_snprintf throws in a random newline because it wants to format * the output for the expected terminal width. Cycle through our output * and copy it into a new output buffer stripping out this extra newline * along the way. */ q = &outbuf[0]; r = &outbuf2[0]; while (*q != '\0') { if (*q != '\n') { *r = *q; r++; } q++; } *r = '\0'; printf("%s\n", outbuf2); return (WALK_NEXT); } int lminfo2(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { char t[32]; char s[32]; if (DCMD_HDRSPEC(flags)) { mdb_snprintf(t, sizeof(t), "%%-?s", "ADDR"); mdb_snprintf(s, sizeof(t), "%-?s", "VNODE"); printf("%s %2s %4s %6s %-16s %s %-9s %-9s %-9s %s\n", t, "TP", "FLAG", "PID", "COMM", s, "WHENCE", "START", "LEN", "PATH"); } return (mdb_pwalk("lock_graph", lminfo_cb, NULL, NULL)); } static const mdb_dcmd_t dcmds[] = { { "lminfo2", NULL, "print lock manager information", lminfo2 }, { NULL } }; static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, NULL }; const mdb_modinfo_t * _mdb_init(void) { return (&modinfo); } /* ex: set sw=8 sts=8 noexpandtab: */