xref: /titanic_52/usr/src/cmd/mdb/common/modules/genunix/vfs.c (revision 1665390b481087ca2aaff06a502c62b3ee91d530)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5150d2c52Svb160487  * Common Development and Distribution License (the "License").
6150d2c52Svb160487  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
226be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
267c478bd9Sstevel@tonic-gate #include <mdb/mdb_ks.h>
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <sys/types.h>
297c478bd9Sstevel@tonic-gate #include <sys/systm.h>
307c478bd9Sstevel@tonic-gate #include <sys/door.h>
317c478bd9Sstevel@tonic-gate #include <sys/file.h>
327c478bd9Sstevel@tonic-gate #include <sys/mount.h>
337c478bd9Sstevel@tonic-gate #include <sys/proc.h>
347c478bd9Sstevel@tonic-gate #include <sys/procfs.h>
357c478bd9Sstevel@tonic-gate #include <sys/proc/prdata.h>
367c478bd9Sstevel@tonic-gate #include <sys/stat.h>
377c478bd9Sstevel@tonic-gate #include <sys/vfs.h>
387c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
397c478bd9Sstevel@tonic-gate #include <sys/fs/snode.h>
407c478bd9Sstevel@tonic-gate #include <sys/fs/fifonode.h>
417c478bd9Sstevel@tonic-gate #include <sys/fs/namenode.h>
427c478bd9Sstevel@tonic-gate #include <sys/socket.h>
437c478bd9Sstevel@tonic-gate #include <sys/stropts.h>
447c478bd9Sstevel@tonic-gate #include <sys/socketvar.h>
457c478bd9Sstevel@tonic-gate #include <sys/strsubr.h>
467c478bd9Sstevel@tonic-gate #include <sys/un.h>
470f1702c5SYu Xiangning #include <fs/sockfs/socktpi_impl.h>
480f1702c5SYu Xiangning #include <inet/ipclassifier.h>
490f1702c5SYu Xiangning #include <inet/ip_if.h>
500f1702c5SYu Xiangning #include <inet/sctp/sctp_impl.h>
510f1702c5SYu Xiangning #include <inet/sctp/sctp_addr.h>
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate int
547c478bd9Sstevel@tonic-gate vfs_walk_init(mdb_walk_state_t *wsp)
557c478bd9Sstevel@tonic-gate {
567c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr == NULL &&
577c478bd9Sstevel@tonic-gate 	    mdb_readvar(&wsp->walk_addr, "rootvfs") == -1) {
587c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read 'rootvfs'");
597c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
607c478bd9Sstevel@tonic-gate 	}
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 	wsp->walk_data = (void *)wsp->walk_addr;
637c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
647c478bd9Sstevel@tonic-gate }
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate int
677c478bd9Sstevel@tonic-gate vfs_walk_step(mdb_walk_state_t *wsp)
687c478bd9Sstevel@tonic-gate {
697c478bd9Sstevel@tonic-gate 	vfs_t vfs;
707c478bd9Sstevel@tonic-gate 	int status;
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate 	if (mdb_vread(&vfs, sizeof (vfs), wsp->walk_addr) == -1) {
737c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read vfs_t at %p", wsp->walk_addr);
747c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
757c478bd9Sstevel@tonic-gate 	}
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 	status = wsp->walk_callback(wsp->walk_addr, &vfs, wsp->walk_cbdata);
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 	if (vfs.vfs_next == wsp->walk_data)
807c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)vfs.vfs_next;
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate 	return (status);
857c478bd9Sstevel@tonic-gate }
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate /*
887c478bd9Sstevel@tonic-gate  * Utility routine to read in a filesystem name given a vfs pointer.  If
897c478bd9Sstevel@tonic-gate  * no vfssw entry for the vfs is available (as is the case with some pseudo-
907c478bd9Sstevel@tonic-gate  * filesystems), we check against some known problem fs's: doorfs and
917c478bd9Sstevel@tonic-gate  * portfs.  If that fails, we try to guess the filesystem name using
927c478bd9Sstevel@tonic-gate  * symbol names.  fsname should be a buffer of size _ST_FSTYPSZ.
937c478bd9Sstevel@tonic-gate  */
947c478bd9Sstevel@tonic-gate static int
957c478bd9Sstevel@tonic-gate read_fsname(uintptr_t vfsp, char *fsname)
967c478bd9Sstevel@tonic-gate {
977c478bd9Sstevel@tonic-gate 	vfs_t vfs;
987c478bd9Sstevel@tonic-gate 	struct vfssw vfssw_entry;
997c478bd9Sstevel@tonic-gate 	GElf_Sym vfssw_sym, test_sym;
1007c478bd9Sstevel@tonic-gate 	char testname[MDB_SYM_NAMLEN];
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate 	if (mdb_vread(&vfs, sizeof (vfs), vfsp) == -1) {
1037c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read vfs %p", vfsp);
1047c478bd9Sstevel@tonic-gate 		return (-1);
1057c478bd9Sstevel@tonic-gate 	}
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate 	if (mdb_lookup_by_name("vfssw", &vfssw_sym) == -1) {
1087c478bd9Sstevel@tonic-gate 		mdb_warn("failed to find vfssw");
1097c478bd9Sstevel@tonic-gate 		return (-1);
1107c478bd9Sstevel@tonic-gate 	}
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 	/*
1137c478bd9Sstevel@tonic-gate 	 * vfssw is an array; we need vfssw[vfs.vfs_fstype].
1147c478bd9Sstevel@tonic-gate 	 */
1157c478bd9Sstevel@tonic-gate 	if (mdb_vread(&vfssw_entry, sizeof (vfssw_entry),
1167c478bd9Sstevel@tonic-gate 	    vfssw_sym.st_value + (sizeof (struct vfssw) * vfs.vfs_fstype))
1177c478bd9Sstevel@tonic-gate 	    == -1) {
1187c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read vfssw index %d", vfs.vfs_fstype);
1197c478bd9Sstevel@tonic-gate 		return (-1);
1207c478bd9Sstevel@tonic-gate 	}
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 	if (vfs.vfs_fstype != 0) {
1237c478bd9Sstevel@tonic-gate 		if (mdb_readstr(fsname, _ST_FSTYPSZ,
1247c478bd9Sstevel@tonic-gate 		    (uintptr_t)vfssw_entry.vsw_name) == -1) {
1257c478bd9Sstevel@tonic-gate 			mdb_warn("failed to find fs name %p",
1267c478bd9Sstevel@tonic-gate 			    vfssw_entry.vsw_name);
1277c478bd9Sstevel@tonic-gate 			return (-1);
1287c478bd9Sstevel@tonic-gate 		}
1297c478bd9Sstevel@tonic-gate 		return (0);
1307c478bd9Sstevel@tonic-gate 	}
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 	/*
1337c478bd9Sstevel@tonic-gate 	 * Do precise detection for certain filesystem types that we
1347c478bd9Sstevel@tonic-gate 	 * know do not appear in vfssw[], and that we depend upon in other
1357c478bd9Sstevel@tonic-gate 	 * parts of the code: doorfs and portfs.
1367c478bd9Sstevel@tonic-gate 	 */
1377c478bd9Sstevel@tonic-gate 	if (mdb_lookup_by_name("door_vfs", &test_sym) != -1) {
1387c478bd9Sstevel@tonic-gate 		if (test_sym.st_value == vfsp) {
1397c478bd9Sstevel@tonic-gate 			strcpy(fsname, "doorfs");
1407c478bd9Sstevel@tonic-gate 			return (0);
1417c478bd9Sstevel@tonic-gate 		}
1427c478bd9Sstevel@tonic-gate 	}
1437c478bd9Sstevel@tonic-gate 	if (mdb_lookup_by_name("port_vfs", &test_sym) != -1) {
1447c478bd9Sstevel@tonic-gate 		if (test_sym.st_value == vfsp) {
1457c478bd9Sstevel@tonic-gate 			strcpy(fsname, "portfs");
1467c478bd9Sstevel@tonic-gate 			return (0);
1477c478bd9Sstevel@tonic-gate 		}
1487c478bd9Sstevel@tonic-gate 	}
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	/*
1517c478bd9Sstevel@tonic-gate 	 * Heuristic detection for other filesystems that don't have a
1527c478bd9Sstevel@tonic-gate 	 * vfssw[] entry.  These tend to be named <fsname>_vfs, so we do a
1537c478bd9Sstevel@tonic-gate 	 * lookup_by_addr and see if we find a symbol of that name.
1547c478bd9Sstevel@tonic-gate 	 */
1557c478bd9Sstevel@tonic-gate 	if (mdb_lookup_by_addr(vfsp, MDB_SYM_EXACT, testname, sizeof (testname),
1567c478bd9Sstevel@tonic-gate 	    &test_sym) != -1) {
1577c478bd9Sstevel@tonic-gate 		if ((strlen(testname) > 4) &&
1587c478bd9Sstevel@tonic-gate 		    (strcmp(testname + strlen(testname) - 4, "_vfs") == 0)) {
1597c478bd9Sstevel@tonic-gate 			testname[strlen(testname) - 4] = '\0';
1607c478bd9Sstevel@tonic-gate 			strncpy(fsname, testname, _ST_FSTYPSZ);
1617c478bd9Sstevel@tonic-gate 			return (0);
1627c478bd9Sstevel@tonic-gate 		}
1637c478bd9Sstevel@tonic-gate 	}
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate 	mdb_warn("unknown filesystem type for vfs %p", vfsp);
1667c478bd9Sstevel@tonic-gate 	return (-1);
1677c478bd9Sstevel@tonic-gate }
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate /*
1707c478bd9Sstevel@tonic-gate  * Column widths for mount point display in ::fsinfo output.
1717c478bd9Sstevel@tonic-gate  */
1727c478bd9Sstevel@tonic-gate #ifdef _LP64
1737c478bd9Sstevel@tonic-gate #define	FSINFO_MNTLEN	48
1747c478bd9Sstevel@tonic-gate #else
1757c478bd9Sstevel@tonic-gate #define	FSINFO_MNTLEN	56
1767c478bd9Sstevel@tonic-gate #endif
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate /* ARGSUSED */
1797c478bd9Sstevel@tonic-gate int
1807c478bd9Sstevel@tonic-gate fsinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1817c478bd9Sstevel@tonic-gate {
1827c478bd9Sstevel@tonic-gate 	vfs_t vfs;
1837c478bd9Sstevel@tonic-gate 	int len;
1847c478bd9Sstevel@tonic-gate 	int opt_v = 0;
1857c478bd9Sstevel@tonic-gate 	char buf[MAXPATHLEN];
1867c478bd9Sstevel@tonic-gate 	char fsname[_ST_FSTYPSZ];
1877c478bd9Sstevel@tonic-gate 	mntopt_t *mntopts;
1887c478bd9Sstevel@tonic-gate 	size_t size;
1897c478bd9Sstevel@tonic-gate 	int i;
1907c478bd9Sstevel@tonic-gate 	int first = 1;
1917c478bd9Sstevel@tonic-gate 	char opt[MAX_MNTOPT_STR];
1927c478bd9Sstevel@tonic-gate 	uintptr_t global_zone;
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
1957c478bd9Sstevel@tonic-gate 		if (mdb_walk_dcmd("vfs", "fsinfo", argc, argv) == -1) {
1967c478bd9Sstevel@tonic-gate 			mdb_warn("failed to walk file system list");
1977c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
1987c478bd9Sstevel@tonic-gate 		}
1997c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
2007c478bd9Sstevel@tonic-gate 	}
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv,
2037c478bd9Sstevel@tonic-gate 	    'v', MDB_OPT_SETBITS, TRUE, &opt_v, NULL) != argc)
2047c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags))
2077c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%?s %-15s %s%</u>\n",
2087c478bd9Sstevel@tonic-gate 		    "VFSP", "FS", "MOUNT");
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 	if (mdb_vread(&vfs, sizeof (vfs), addr) == -1) {
2117c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read vfs_t %p", addr);
2127c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
2137c478bd9Sstevel@tonic-gate 	}
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	if ((len = mdb_read_refstr((uintptr_t)vfs.vfs_mntpt, buf,
2167c478bd9Sstevel@tonic-gate 	    sizeof (buf))) <= 0)
2177c478bd9Sstevel@tonic-gate 		strcpy(buf, "??");
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 	else if (!opt_v && (len >= FSINFO_MNTLEN))
2207c478bd9Sstevel@tonic-gate 		/*
2217c478bd9Sstevel@tonic-gate 		 * In normal mode, we truncate the path to keep the output
2227c478bd9Sstevel@tonic-gate 		 * clean.  In -v mode, we just print the full path.
2237c478bd9Sstevel@tonic-gate 		 */
2247c478bd9Sstevel@tonic-gate 		strcpy(&buf[FSINFO_MNTLEN - 4], "...");
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 	if (read_fsname(addr, fsname) == -1)
2277c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 	mdb_printf("%0?p %-15s %s\n", addr, fsname, buf);
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 	if (!opt_v)
2327c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate 	/*
2357c478bd9Sstevel@tonic-gate 	 * Print 'resource' string; this shows what we're mounted upon.
2367c478bd9Sstevel@tonic-gate 	 */
2377c478bd9Sstevel@tonic-gate 	if (mdb_read_refstr((uintptr_t)vfs.vfs_resource, buf,
2387c478bd9Sstevel@tonic-gate 	    MAXPATHLEN) <= 0)
2397c478bd9Sstevel@tonic-gate 		strcpy(buf, "??");
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate 	mdb_printf("%?s %s\n", "R:", buf);
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 	/*
2447c478bd9Sstevel@tonic-gate 	 * Print mount options array; it sucks to be a mimic, but we copy
2457c478bd9Sstevel@tonic-gate 	 * the same logic as in mntvnops.c for adding zone= tags, and we
2467c478bd9Sstevel@tonic-gate 	 * don't bother with the obsolete dev= option.
2477c478bd9Sstevel@tonic-gate 	 */
2487c478bd9Sstevel@tonic-gate 	size = vfs.vfs_mntopts.mo_count * sizeof (mntopt_t);
2497c478bd9Sstevel@tonic-gate 	mntopts = mdb_alloc(size, UM_SLEEP | UM_GC);
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 	if (mdb_vread(mntopts, size,
2527c478bd9Sstevel@tonic-gate 	    (uintptr_t)vfs.vfs_mntopts.mo_list) == -1) {
2537c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read mntopts %p", vfs.vfs_mntopts.mo_list);
2547c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
2557c478bd9Sstevel@tonic-gate 	}
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 	for (i = 0; i < vfs.vfs_mntopts.mo_count; i++) {
2587c478bd9Sstevel@tonic-gate 		if (mntopts[i].mo_flags & MO_SET) {
2597c478bd9Sstevel@tonic-gate 			if (mdb_readstr(opt, sizeof (opt),
2607c478bd9Sstevel@tonic-gate 			    (uintptr_t)mntopts[i].mo_name) == -1) {
2617c478bd9Sstevel@tonic-gate 				mdb_warn("failed to read mntopt name %p",
2627c478bd9Sstevel@tonic-gate 				    mntopts[i].mo_name);
2637c478bd9Sstevel@tonic-gate 				return (DCMD_ERR);
2647c478bd9Sstevel@tonic-gate 			}
2657c478bd9Sstevel@tonic-gate 			if (first) {
2667c478bd9Sstevel@tonic-gate 				mdb_printf("%?s ", "O:");
2677c478bd9Sstevel@tonic-gate 				first = 0;
2687c478bd9Sstevel@tonic-gate 			} else {
2697c478bd9Sstevel@tonic-gate 				mdb_printf(",");
2707c478bd9Sstevel@tonic-gate 			}
2717c478bd9Sstevel@tonic-gate 			mdb_printf("%s", opt);
2727c478bd9Sstevel@tonic-gate 			if (mntopts[i].mo_flags & MO_HASVALUE) {
2737c478bd9Sstevel@tonic-gate 				if (mdb_readstr(opt, sizeof (opt),
2747c478bd9Sstevel@tonic-gate 				    (uintptr_t)mntopts[i].mo_arg) == -1) {
2757c478bd9Sstevel@tonic-gate 					mdb_warn("failed to read mntopt "
2767c478bd9Sstevel@tonic-gate 					    "value %p", mntopts[i].mo_arg);
2777c478bd9Sstevel@tonic-gate 					return (DCMD_ERR);
2787c478bd9Sstevel@tonic-gate 				}
2797c478bd9Sstevel@tonic-gate 				mdb_printf("=%s", opt);
2807c478bd9Sstevel@tonic-gate 			}
2817c478bd9Sstevel@tonic-gate 		}
2827c478bd9Sstevel@tonic-gate 	}
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&global_zone, "global_zone") == -1) {
2857c478bd9Sstevel@tonic-gate 		mdb_warn("failed to locate global_zone");
2867c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
2877c478bd9Sstevel@tonic-gate 	}
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate 	if ((vfs.vfs_zone != NULL) &&
2907c478bd9Sstevel@tonic-gate 	    ((uintptr_t)vfs.vfs_zone != global_zone)) {
2917c478bd9Sstevel@tonic-gate 		zone_t z;
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate 		if (mdb_vread(&z, sizeof (z), (uintptr_t)vfs.vfs_zone) == -1) {
2947c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read zone");
2957c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
2967c478bd9Sstevel@tonic-gate 		}
2977c478bd9Sstevel@tonic-gate 		/*
2987c478bd9Sstevel@tonic-gate 		 * zone names are much shorter than MAX_MNTOPT_STR
2997c478bd9Sstevel@tonic-gate 		 */
3007c478bd9Sstevel@tonic-gate 		if (mdb_readstr(opt, sizeof (opt),
3017c478bd9Sstevel@tonic-gate 		    (uintptr_t)z.zone_name) == -1) {
3027c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read zone name");
3037c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
3047c478bd9Sstevel@tonic-gate 		}
3057c478bd9Sstevel@tonic-gate 		if (first) {
3067c478bd9Sstevel@tonic-gate 			mdb_printf("%?s ", "O:");
3077c478bd9Sstevel@tonic-gate 		} else {
3087c478bd9Sstevel@tonic-gate 			mdb_printf(",");
3097c478bd9Sstevel@tonic-gate 		}
3107c478bd9Sstevel@tonic-gate 		mdb_printf("zone=%s", opt);
3117c478bd9Sstevel@tonic-gate 	}
3127c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate #define	REALVP_DONE	0
3177c478bd9Sstevel@tonic-gate #define	REALVP_ERR	1
3187c478bd9Sstevel@tonic-gate #define	REALVP_CONTINUE	2
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate static int
3217c478bd9Sstevel@tonic-gate next_realvp(uintptr_t invp, struct vnode *outvn, uintptr_t *outvp)
3227c478bd9Sstevel@tonic-gate {
3237c478bd9Sstevel@tonic-gate 	char fsname[_ST_FSTYPSZ];
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 	*outvp = invp;
3267c478bd9Sstevel@tonic-gate 	if (mdb_vread(outvn, sizeof (struct vnode), invp) == -1) {
3277c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read vnode at %p", invp);
3287c478bd9Sstevel@tonic-gate 		return (REALVP_ERR);
3297c478bd9Sstevel@tonic-gate 	}
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate 	if (read_fsname((uintptr_t)outvn->v_vfsp, fsname) == -1)
3327c478bd9Sstevel@tonic-gate 		return (REALVP_ERR);
3337c478bd9Sstevel@tonic-gate 
3347c478bd9Sstevel@tonic-gate 	/*
3357c478bd9Sstevel@tonic-gate 	 * We know how to do 'realvp' for as many filesystems as possible;
3367c478bd9Sstevel@tonic-gate 	 * for all other filesystems, we assume that the vp we are given
3377c478bd9Sstevel@tonic-gate 	 * is the realvp.  In the kernel, a realvp operation will sometimes
3387c478bd9Sstevel@tonic-gate 	 * dig through multiple layers.  Here, we only fetch the pointer
3397c478bd9Sstevel@tonic-gate 	 * to the next layer down.  This allows dcmds to print out the
3407c478bd9Sstevel@tonic-gate 	 * various layers.
3417c478bd9Sstevel@tonic-gate 	 */
3427c478bd9Sstevel@tonic-gate 	if (strcmp(fsname, "fifofs") == 0) {
3437c478bd9Sstevel@tonic-gate 		fifonode_t fn;
3447c478bd9Sstevel@tonic-gate 		if (mdb_vread(&fn, sizeof (fn),
3457c478bd9Sstevel@tonic-gate 		    (uintptr_t)outvn->v_data) == -1) {
3467c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read fifonode");
3477c478bd9Sstevel@tonic-gate 			return (REALVP_ERR);
3487c478bd9Sstevel@tonic-gate 		}
3497c478bd9Sstevel@tonic-gate 		*outvp = (uintptr_t)fn.fn_realvp;
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate 	} else if (strcmp(fsname, "namefs") == 0) {
3527c478bd9Sstevel@tonic-gate 		struct namenode nn;
3537c478bd9Sstevel@tonic-gate 		if (mdb_vread(&nn, sizeof (nn),
3547c478bd9Sstevel@tonic-gate 		    (uintptr_t)outvn->v_data) == -1) {
3557c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read namenode");
3567c478bd9Sstevel@tonic-gate 			return (REALVP_ERR);
3577c478bd9Sstevel@tonic-gate 		}
3587c478bd9Sstevel@tonic-gate 		*outvp = (uintptr_t)nn.nm_filevp;
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate 	} else if (outvn->v_type == VSOCK && outvn->v_stream != NULL) {
3617c478bd9Sstevel@tonic-gate 		struct stdata stream;
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate 		/*
3647c478bd9Sstevel@tonic-gate 		 * Sockets have a strange and different layering scheme; we
3657c478bd9Sstevel@tonic-gate 		 * hop over into the sockfs vnode (accessible via the stream
3667c478bd9Sstevel@tonic-gate 		 * head) if possible.
3677c478bd9Sstevel@tonic-gate 		 */
3687c478bd9Sstevel@tonic-gate 		if (mdb_vread(&stream, sizeof (stream),
3697c478bd9Sstevel@tonic-gate 		    (uintptr_t)outvn->v_stream) == -1) {
3707c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read stream data");
3717c478bd9Sstevel@tonic-gate 			return (REALVP_ERR);
3727c478bd9Sstevel@tonic-gate 		}
3737c478bd9Sstevel@tonic-gate 		*outvp = (uintptr_t)stream.sd_vnode;
3747c478bd9Sstevel@tonic-gate 	}
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 	if (*outvp == invp || *outvp == NULL)
3777c478bd9Sstevel@tonic-gate 		return (REALVP_DONE);
3787c478bd9Sstevel@tonic-gate 
3797c478bd9Sstevel@tonic-gate 	return (REALVP_CONTINUE);
3807c478bd9Sstevel@tonic-gate }
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate static void
3837c478bd9Sstevel@tonic-gate pfiles_print_addr(struct sockaddr *addr)
3847c478bd9Sstevel@tonic-gate {
3857c478bd9Sstevel@tonic-gate 	struct sockaddr_in *s_in;
3867c478bd9Sstevel@tonic-gate 	struct sockaddr_un *s_un;
3877c478bd9Sstevel@tonic-gate 	struct sockaddr_in6 *s_in6;
388150d2c52Svb160487 	in_port_t port;
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate 	switch (addr->sa_family) {
3917c478bd9Sstevel@tonic-gate 	case AF_INET:
3927c478bd9Sstevel@tonic-gate 		/* LINTED: alignment */
3937c478bd9Sstevel@tonic-gate 		s_in = (struct sockaddr_in *)addr;
394150d2c52Svb160487 		mdb_nhconvert(&port, &s_in->sin_port, sizeof (port));
395150d2c52Svb160487 		mdb_printf("AF_INET %I %d ", s_in->sin_addr.s_addr, port);
3967c478bd9Sstevel@tonic-gate 		break;
3977c478bd9Sstevel@tonic-gate 
3987c478bd9Sstevel@tonic-gate 	case AF_INET6:
3997c478bd9Sstevel@tonic-gate 		/* LINTED: alignment */
4007c478bd9Sstevel@tonic-gate 		s_in6 = (struct sockaddr_in6 *)addr;
401150d2c52Svb160487 		mdb_nhconvert(&port, &s_in6->sin6_port, sizeof (port));
402150d2c52Svb160487 		mdb_printf("AF_INET6 %N %d ", &(s_in6->sin6_addr), port);
4037c478bd9Sstevel@tonic-gate 		break;
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate 	case AF_UNIX:
4067c478bd9Sstevel@tonic-gate 		s_un = (struct sockaddr_un *)addr;
4077c478bd9Sstevel@tonic-gate 		mdb_printf("AF_UNIX %s ", s_un->sun_path);
4087c478bd9Sstevel@tonic-gate 		break;
4097c478bd9Sstevel@tonic-gate 	default:
4107c478bd9Sstevel@tonic-gate 		mdb_printf("AF_?? (%d) ", addr->sa_family);
4117c478bd9Sstevel@tonic-gate 		break;
4127c478bd9Sstevel@tonic-gate 	}
4137c478bd9Sstevel@tonic-gate }
4147c478bd9Sstevel@tonic-gate 
4157c478bd9Sstevel@tonic-gate static int
4160f1702c5SYu Xiangning pfiles_get_sonode(vnode_t *v_sock, struct sonode *sonode)
4177c478bd9Sstevel@tonic-gate {
4180f1702c5SYu Xiangning 	if (mdb_vread(sonode, sizeof (struct sonode),
4190f1702c5SYu Xiangning 	    (uintptr_t)v_sock->v_data) == -1) {
4200f1702c5SYu Xiangning 		mdb_warn("failed to read sonode");
4217c478bd9Sstevel@tonic-gate 		return (-1);
4227c478bd9Sstevel@tonic-gate 	}
4237c478bd9Sstevel@tonic-gate 
4240f1702c5SYu Xiangning 	return (0);
4250f1702c5SYu Xiangning }
4260f1702c5SYu Xiangning 
4270f1702c5SYu Xiangning static int
4280f1702c5SYu Xiangning pfiles_get_tpi_sonode(vnode_t *v_sock, sotpi_sonode_t *sotpi_sonode)
4290f1702c5SYu Xiangning {
4300f1702c5SYu Xiangning 
4310f1702c5SYu Xiangning 	struct stdata stream;
4320f1702c5SYu Xiangning 
4330f1702c5SYu Xiangning 	if (mdb_vread(&stream, sizeof (stream),
4340f1702c5SYu Xiangning 	    (uintptr_t)v_sock->v_stream) == -1) {
4357c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read stream data");
4367c478bd9Sstevel@tonic-gate 		return (-1);
4377c478bd9Sstevel@tonic-gate 	}
4387c478bd9Sstevel@tonic-gate 
4390f1702c5SYu Xiangning 	if (mdb_vread(v_sock, sizeof (vnode_t),
4400f1702c5SYu Xiangning 	    (uintptr_t)stream.sd_vnode) == -1) {
4417c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read stream vnode");
4427c478bd9Sstevel@tonic-gate 		return (-1);
4437c478bd9Sstevel@tonic-gate 	}
4447c478bd9Sstevel@tonic-gate 
4450f1702c5SYu Xiangning 	if (mdb_vread(sotpi_sonode, sizeof (sotpi_sonode_t),
4460f1702c5SYu Xiangning 	    (uintptr_t)v_sock->v_data) == -1) {
4470f1702c5SYu Xiangning 		mdb_warn("failed to read sotpi_sonode");
4487c478bd9Sstevel@tonic-gate 		return (-1);
4497c478bd9Sstevel@tonic-gate 	}
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 	return (0);
4527c478bd9Sstevel@tonic-gate }
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate /*
4557c478bd9Sstevel@tonic-gate  * Do some digging to get a reasonable pathname for this vnode. 'path'
4567c478bd9Sstevel@tonic-gate  * should point at a buffer of MAXPATHLEN in size.
4577c478bd9Sstevel@tonic-gate  */
4587c478bd9Sstevel@tonic-gate static int
4597c478bd9Sstevel@tonic-gate pfiles_dig_pathname(uintptr_t vp, char *path)
4607c478bd9Sstevel@tonic-gate {
4617c478bd9Sstevel@tonic-gate 	vnode_t v;
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate 	bzero(path, MAXPATHLEN);
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 	if (mdb_vread(&v, sizeof (v), vp) == -1) {
4667c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read vnode");
4677c478bd9Sstevel@tonic-gate 		return (-1);
4687c478bd9Sstevel@tonic-gate 	}
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 	if (v.v_path == NULL) {
4717c478bd9Sstevel@tonic-gate 		/*
4727c478bd9Sstevel@tonic-gate 		 * fifo's and doors are special.   Some have pathnames, and
4737c478bd9Sstevel@tonic-gate 		 * some do not.  And for these, it is pointless to go off to
4747c478bd9Sstevel@tonic-gate 		 * mdb_vnode2path, which is very slow.
4757c478bd9Sstevel@tonic-gate 		 *
4767c478bd9Sstevel@tonic-gate 		 * Event ports never have a pathname.
4777c478bd9Sstevel@tonic-gate 		 */
4787c478bd9Sstevel@tonic-gate 		if (v.v_type == VFIFO || v.v_type == VDOOR || v.v_type == VPORT)
4797c478bd9Sstevel@tonic-gate 			return (0);
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate 		/*
4827c478bd9Sstevel@tonic-gate 		 * For sockets, we won't find a path unless we print the path
4830f1702c5SYu Xiangning 		 * associated with transport's STREAM device.
4847c478bd9Sstevel@tonic-gate 		 */
4857c478bd9Sstevel@tonic-gate 		if (v.v_type == VSOCK) {
4867c478bd9Sstevel@tonic-gate 			struct sonode sonode;
487869114bdSDan Price 			struct sockparams sockparams;
4887c478bd9Sstevel@tonic-gate 
4890f1702c5SYu Xiangning 			if (pfiles_get_sonode(&v, &sonode) == -1) {
4907c478bd9Sstevel@tonic-gate 				return (-1);
4917c478bd9Sstevel@tonic-gate 			}
492869114bdSDan Price 			if (mdb_vread(&sockparams, sizeof (sockparams),
493869114bdSDan Price 			    (uintptr_t)sonode.so_sockparams) == -1) {
494869114bdSDan Price 				mdb_warn("failed to read sockparams");
495869114bdSDan Price 				return (-1);
496869114bdSDan Price 			}
497869114bdSDan Price 
4980f1702c5SYu Xiangning 			if (!SOCK_IS_NONSTR(&sonode)) {
499869114bdSDan Price 				vp = (uintptr_t)
500869114bdSDan Price 				    sockparams.sp_sdev_info.sd_vnode;
5010f1702c5SYu Xiangning 			} else {
5020f1702c5SYu Xiangning 				vp = NULL;
5030f1702c5SYu Xiangning 			}
5047c478bd9Sstevel@tonic-gate 		}
5057c478bd9Sstevel@tonic-gate 	}
5067c478bd9Sstevel@tonic-gate 
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 	/*
5097c478bd9Sstevel@tonic-gate 	 * mdb_vnode2path will print an error for us as needed, but not
5107c478bd9Sstevel@tonic-gate 	 * finding a pathname is not really an error, so we plow on.
5117c478bd9Sstevel@tonic-gate 	 */
5127c478bd9Sstevel@tonic-gate 	(void) mdb_vnode2path(vp, path, MAXPATHLEN);
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 	/*
5157c478bd9Sstevel@tonic-gate 	 * A common problem is that device pathnames are prefixed with
5167c478bd9Sstevel@tonic-gate 	 * /dev/../devices/.  We just clean those up slightly:
5177c478bd9Sstevel@tonic-gate 	 * 	/dev/../devices/<mumble> --> /devices/<mumble>
5187c478bd9Sstevel@tonic-gate 	 * 	/dev/pts/../../devices/<mumble> --> /devices/<mumble>
5197c478bd9Sstevel@tonic-gate 	 */
5207c478bd9Sstevel@tonic-gate 	if (strncmp("/dev/../devices/", path, strlen("/dev/../devices/")) == 0)
5217c478bd9Sstevel@tonic-gate 		strcpy(path, path + 7);
5227c478bd9Sstevel@tonic-gate 
5237c478bd9Sstevel@tonic-gate 	if (strncmp("/dev/pts/../../devices/", path,
5247c478bd9Sstevel@tonic-gate 	    strlen("/dev/pts/../../devices/")) == 0)
5257c478bd9Sstevel@tonic-gate 		strcpy(path, path + 14);
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate 	return (0);
5287c478bd9Sstevel@tonic-gate }
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate const struct fs_type {
531*1665390bSRichard Lowe 	vtype_t type;
5327c478bd9Sstevel@tonic-gate 	const char *name;
5337c478bd9Sstevel@tonic-gate } fs_types[] = {
5347c478bd9Sstevel@tonic-gate 	{ VNON,   "NON" },
5357c478bd9Sstevel@tonic-gate 	{ VREG,   "REG" },
5367c478bd9Sstevel@tonic-gate 	{ VDIR,   "DIR" },
5377c478bd9Sstevel@tonic-gate 	{ VBLK,   "BLK" },
5387c478bd9Sstevel@tonic-gate 	{ VCHR,   "CHR" },
5397c478bd9Sstevel@tonic-gate 	{ VLNK,   "LNK" },
5407c478bd9Sstevel@tonic-gate 	{ VFIFO,  "FIFO" },
5417c478bd9Sstevel@tonic-gate 	{ VDOOR,  "DOOR" },
5427c478bd9Sstevel@tonic-gate 	{ VPROC,  "PROC" },
5437c478bd9Sstevel@tonic-gate 	{ VSOCK,  "SOCK" },
5447c478bd9Sstevel@tonic-gate 	{ VPORT,  "PORT" },
5457c478bd9Sstevel@tonic-gate 	{ VBAD,   "BAD" }
5467c478bd9Sstevel@tonic-gate };
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate #define	NUM_FS_TYPES (sizeof (fs_types) / sizeof (struct fs_type))
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate struct pfiles_cbdata {
5517c478bd9Sstevel@tonic-gate 	int opt_p;
5527c478bd9Sstevel@tonic-gate 	int fd;
5537c478bd9Sstevel@tonic-gate };
5547c478bd9Sstevel@tonic-gate 
5550f1702c5SYu Xiangning #define	list_d2l(a, obj) ((list_node_t *)(((char *)obj) + (a)->list_offset))
5560f1702c5SYu Xiangning #define	list_object(a, node) ((void *)(((char *)node) - (a)->list_offset))
5570f1702c5SYu Xiangning 
5580f1702c5SYu Xiangning /*
5590f1702c5SYu Xiangning  * SCTP interface for geting the first source address of a sctp_t.
5600f1702c5SYu Xiangning  */
5610f1702c5SYu Xiangning int
5620f1702c5SYu Xiangning sctp_getsockaddr(sctp_t *sctp, struct sockaddr *addr)
5630f1702c5SYu Xiangning {
5640f1702c5SYu Xiangning 	int			err = -1;
5650f1702c5SYu Xiangning 	int			i;
5660f1702c5SYu Xiangning 	int			l;
5670f1702c5SYu Xiangning 	sctp_saddr_ipif_t	*pobj;
5680f1702c5SYu Xiangning 	sctp_saddr_ipif_t	obj;
5690f1702c5SYu Xiangning 	size_t			added = 0;
5700f1702c5SYu Xiangning 	sin6_t			*sin6;
5710f1702c5SYu Xiangning 	sin_t			*sin4;
5720f1702c5SYu Xiangning 	int			scanned = 0;
5730f1702c5SYu Xiangning 	boolean_t		skip_lback = B_FALSE;
574bd670b35SErik Nordmark 	conn_t			*connp = sctp->sctp_connp;
5750f1702c5SYu Xiangning 
576bd670b35SErik Nordmark 	addr->sa_family = connp->conn_family;
5770f1702c5SYu Xiangning 	if (sctp->sctp_nsaddrs == 0)
5780f1702c5SYu Xiangning 		goto done;
5790f1702c5SYu Xiangning 
5800f1702c5SYu Xiangning 	/*
5810f1702c5SYu Xiangning 	 * Skip loopback addresses for non-loopback assoc.
5820f1702c5SYu Xiangning 	 */
5830f1702c5SYu Xiangning 	if (sctp->sctp_state >= SCTPS_ESTABLISHED && !sctp->sctp_loopback) {
5840f1702c5SYu Xiangning 		skip_lback = B_TRUE;
5850f1702c5SYu Xiangning 	}
5860f1702c5SYu Xiangning 
5870f1702c5SYu Xiangning 	for (i = 0; i < SCTP_IPIF_HASH; i++) {
5880f1702c5SYu Xiangning 		if (sctp->sctp_saddrs[i].ipif_count == 0)
5890f1702c5SYu Xiangning 			continue;
5900f1702c5SYu Xiangning 
5910f1702c5SYu Xiangning 		pobj = list_object(&sctp->sctp_saddrs[i].sctp_ipif_list,
5920f1702c5SYu Xiangning 		    sctp->sctp_saddrs[i].sctp_ipif_list.list_head.list_next);
5930f1702c5SYu Xiangning 		if (mdb_vread(&obj, sizeof (sctp_saddr_ipif_t),
5940f1702c5SYu Xiangning 		    (uintptr_t)pobj) == -1) {
5950f1702c5SYu Xiangning 			mdb_warn("failed to read sctp_saddr_ipif_t");
5960f1702c5SYu Xiangning 			return (err);
5970f1702c5SYu Xiangning 		}
5980f1702c5SYu Xiangning 
5990f1702c5SYu Xiangning 		for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) {
6000f1702c5SYu Xiangning 			sctp_ipif_t	ipif;
6010f1702c5SYu Xiangning 			in6_addr_t	laddr;
6020f1702c5SYu Xiangning 			list_node_t 	*pnode;
6030f1702c5SYu Xiangning 			list_node_t	node;
6040f1702c5SYu Xiangning 
6050f1702c5SYu Xiangning 			if (mdb_vread(&ipif, sizeof (sctp_ipif_t),
6060f1702c5SYu Xiangning 			    (uintptr_t)obj.saddr_ipifp) == -1) {
6070f1702c5SYu Xiangning 				mdb_warn("failed to read sctp_ipif_t");
6080f1702c5SYu Xiangning 				return (err);
6090f1702c5SYu Xiangning 			}
6100f1702c5SYu Xiangning 			laddr = ipif.sctp_ipif_saddr;
6110f1702c5SYu Xiangning 
6120f1702c5SYu Xiangning 			scanned++;
6130f1702c5SYu Xiangning 			if ((ipif.sctp_ipif_state == SCTP_IPIFS_CONDEMNED) ||
6140f1702c5SYu Xiangning 			    SCTP_DONT_SRC(&obj) ||
6150f1702c5SYu Xiangning 			    (ipif.sctp_ipif_ill->sctp_ill_flags &
6160f1702c5SYu Xiangning 			    PHYI_LOOPBACK) && skip_lback) {
6170f1702c5SYu Xiangning 				if (scanned >= sctp->sctp_nsaddrs)
6180f1702c5SYu Xiangning 					goto done;
6190f1702c5SYu Xiangning 
6200f1702c5SYu Xiangning 				/* LINTED: alignment */
6210f1702c5SYu Xiangning 				pnode = list_d2l(&sctp->sctp_saddrs[i].
6220f1702c5SYu Xiangning 				    sctp_ipif_list, pobj);
6230f1702c5SYu Xiangning 				if (mdb_vread(&node, sizeof (list_node_t),
6240f1702c5SYu Xiangning 				    (uintptr_t)pnode) == -1) {
6250f1702c5SYu Xiangning 					mdb_warn("failed to read list_node_t");
6260f1702c5SYu Xiangning 					return (err);
6270f1702c5SYu Xiangning 				}
6280f1702c5SYu Xiangning 				pobj = list_object(&sctp->sctp_saddrs[i].
6290f1702c5SYu Xiangning 				    sctp_ipif_list, node.list_next);
6300f1702c5SYu Xiangning 				if (mdb_vread(&obj, sizeof (sctp_saddr_ipif_t),
6310f1702c5SYu Xiangning 				    (uintptr_t)pobj) == -1) {
6320f1702c5SYu Xiangning 					mdb_warn("failed to read "
6330f1702c5SYu Xiangning 					    "sctp_saddr_ipif_t");
6340f1702c5SYu Xiangning 					return (err);
6350f1702c5SYu Xiangning 				}
6360f1702c5SYu Xiangning 				continue;
6370f1702c5SYu Xiangning 			}
6380f1702c5SYu Xiangning 
639bd670b35SErik Nordmark 			switch (connp->conn_family) {
6400f1702c5SYu Xiangning 			case AF_INET:
6410f1702c5SYu Xiangning 				/* LINTED: alignment */
6420f1702c5SYu Xiangning 				sin4 = (sin_t *)addr;
6430f1702c5SYu Xiangning 				if ((sctp->sctp_state <= SCTPS_LISTEN) &&
6440f1702c5SYu Xiangning 				    sctp->sctp_bound_to_all) {
6450f1702c5SYu Xiangning 					sin4->sin_addr.s_addr = INADDR_ANY;
646bd670b35SErik Nordmark 					sin4->sin_port = connp->conn_lport;
6470f1702c5SYu Xiangning 				} else {
6480f1702c5SYu Xiangning 					sin4 += added;
6490f1702c5SYu Xiangning 					sin4->sin_family = AF_INET;
650bd670b35SErik Nordmark 					sin4->sin_port = connp->conn_lport;
6510f1702c5SYu Xiangning 					IN6_V4MAPPED_TO_INADDR(&laddr,
6520f1702c5SYu Xiangning 					    &sin4->sin_addr);
6530f1702c5SYu Xiangning 				}
6540f1702c5SYu Xiangning 				break;
6550f1702c5SYu Xiangning 
6560f1702c5SYu Xiangning 			case AF_INET6:
6570f1702c5SYu Xiangning 				/* LINTED: alignment */
6580f1702c5SYu Xiangning 				sin6 = (sin6_t *)addr;
6590f1702c5SYu Xiangning 				if ((sctp->sctp_state <= SCTPS_LISTEN) &&
6600f1702c5SYu Xiangning 				    sctp->sctp_bound_to_all) {
6610f1702c5SYu Xiangning 					bzero(&sin6->sin6_addr,
6620f1702c5SYu Xiangning 					    sizeof (sin6->sin6_addr));
663bd670b35SErik Nordmark 					sin6->sin6_port = connp->conn_lport;
6640f1702c5SYu Xiangning 				} else {
6650f1702c5SYu Xiangning 					sin6 += added;
6660f1702c5SYu Xiangning 					sin6->sin6_family = AF_INET6;
667bd670b35SErik Nordmark 					sin6->sin6_port = connp->conn_lport;
6680f1702c5SYu Xiangning 					sin6->sin6_addr = laddr;
6690f1702c5SYu Xiangning 				}
670bd670b35SErik Nordmark 				sin6->sin6_flowinfo = connp->conn_flowinfo;
6710f1702c5SYu Xiangning 				sin6->sin6_scope_id = 0;
6720f1702c5SYu Xiangning 				sin6->__sin6_src_id = 0;
6730f1702c5SYu Xiangning 				break;
6740f1702c5SYu Xiangning 			}
6750f1702c5SYu Xiangning 			added++;
6760f1702c5SYu Xiangning 			if (added >= 1) {
6770f1702c5SYu Xiangning 				err = 0;
6780f1702c5SYu Xiangning 				goto done;
6790f1702c5SYu Xiangning 			}
6800f1702c5SYu Xiangning 			if (scanned >= sctp->sctp_nsaddrs)
6810f1702c5SYu Xiangning 				goto done;
6820f1702c5SYu Xiangning 
6830f1702c5SYu Xiangning 			/* LINTED: alignment */
6840f1702c5SYu Xiangning 			pnode = list_d2l(&sctp->sctp_saddrs[i].sctp_ipif_list,
6850f1702c5SYu Xiangning 			    pobj);
6860f1702c5SYu Xiangning 			if (mdb_vread(&node, sizeof (list_node_t),
6870f1702c5SYu Xiangning 			    (uintptr_t)pnode) == -1) {
6880f1702c5SYu Xiangning 				mdb_warn("failed to read list_node_t");
6890f1702c5SYu Xiangning 				return (err);
6900f1702c5SYu Xiangning 			}
6910f1702c5SYu Xiangning 			pobj = list_object(&sctp->sctp_saddrs[i].
6920f1702c5SYu Xiangning 			    sctp_ipif_list, node.list_next);
6930f1702c5SYu Xiangning 			if (mdb_vread(&obj, sizeof (sctp_saddr_ipif_t),
6940f1702c5SYu Xiangning 			    (uintptr_t)pobj) == -1) {
6950f1702c5SYu Xiangning 				mdb_warn("failed to read sctp_saddr_ipif_t");
6960f1702c5SYu Xiangning 				return (err);
6970f1702c5SYu Xiangning 			}
6980f1702c5SYu Xiangning 		}
6990f1702c5SYu Xiangning 	}
7000f1702c5SYu Xiangning done:
7010f1702c5SYu Xiangning 	return (err);
7020f1702c5SYu Xiangning }
7030f1702c5SYu Xiangning 
7040f1702c5SYu Xiangning /*
7050f1702c5SYu Xiangning  * SCTP interface for geting the primary peer address of a sctp_t.
7060f1702c5SYu Xiangning  */
7070f1702c5SYu Xiangning static int
7080f1702c5SYu Xiangning sctp_getpeeraddr(sctp_t *sctp, struct sockaddr *addr)
7090f1702c5SYu Xiangning {
7100f1702c5SYu Xiangning 	struct sockaddr_in	*sin4;
7110f1702c5SYu Xiangning 	struct sockaddr_in6	*sin6;
7120f1702c5SYu Xiangning 	sctp_faddr_t		sctp_primary;
7130f1702c5SYu Xiangning 	in6_addr_t		faddr;
714bd670b35SErik Nordmark 	conn_t			*connp = sctp->sctp_connp;
7150f1702c5SYu Xiangning 
7160f1702c5SYu Xiangning 	if (sctp->sctp_faddrs == NULL)
7170f1702c5SYu Xiangning 		return (-1);
7180f1702c5SYu Xiangning 
719bd670b35SErik Nordmark 	addr->sa_family = connp->conn_family;
7200f1702c5SYu Xiangning 	if (mdb_vread(&sctp_primary, sizeof (sctp_faddr_t),
7210f1702c5SYu Xiangning 	    (uintptr_t)sctp->sctp_primary) == -1) {
7220f1702c5SYu Xiangning 		mdb_warn("failed to read sctp primary faddr");
7230f1702c5SYu Xiangning 		return (-1);
7240f1702c5SYu Xiangning 	}
7256be61d4eSchandrasekar marimuthu - Sun Microsystems - Bangalore India 	faddr = sctp_primary.sf_faddr;
7260f1702c5SYu Xiangning 
727bd670b35SErik Nordmark 	switch (connp->conn_family) {
7280f1702c5SYu Xiangning 	case AF_INET:
7290f1702c5SYu Xiangning 		/* LINTED: alignment */
7300f1702c5SYu Xiangning 		sin4 = (struct sockaddr_in *)addr;
7310f1702c5SYu Xiangning 		IN6_V4MAPPED_TO_INADDR(&faddr, &sin4->sin_addr);
732bd670b35SErik Nordmark 		sin4->sin_port = connp->conn_fport;
7330f1702c5SYu Xiangning 		sin4->sin_family = AF_INET;
7340f1702c5SYu Xiangning 		break;
7350f1702c5SYu Xiangning 
7360f1702c5SYu Xiangning 	case AF_INET6:
7370f1702c5SYu Xiangning 		/* LINTED: alignment */
7380f1702c5SYu Xiangning 		sin6 = (struct sockaddr_in6 *)addr;
7390f1702c5SYu Xiangning 		sin6->sin6_addr = faddr;
740bd670b35SErik Nordmark 		sin6->sin6_port = connp->conn_fport;
7410f1702c5SYu Xiangning 		sin6->sin6_family = AF_INET6;
7420f1702c5SYu Xiangning 		sin6->sin6_flowinfo = 0;
7430f1702c5SYu Xiangning 		sin6->sin6_scope_id = 0;
7440f1702c5SYu Xiangning 		sin6->__sin6_src_id = 0;
7450f1702c5SYu Xiangning 		break;
7460f1702c5SYu Xiangning 	}
7470f1702c5SYu Xiangning 
7480f1702c5SYu Xiangning 	return (0);
7490f1702c5SYu Xiangning }
7500f1702c5SYu Xiangning 
7510f1702c5SYu Xiangning static int
7520f1702c5SYu Xiangning tpi_sock_print(sotpi_sonode_t *sotpi_sonode)
7530f1702c5SYu Xiangning {
7540f1702c5SYu Xiangning 	if (sotpi_sonode->st_info.sti_laddr_valid == 1) {
7550f1702c5SYu Xiangning 		struct sockaddr *laddr =
7560f1702c5SYu Xiangning 		    mdb_alloc(sotpi_sonode->st_info.sti_laddr_len, UM_SLEEP);
7570f1702c5SYu Xiangning 		if (mdb_vread(laddr, sotpi_sonode->st_info.sti_laddr_len,
7580f1702c5SYu Xiangning 		    (uintptr_t)sotpi_sonode->st_info.sti_laddr_sa) == -1) {
7590f1702c5SYu Xiangning 			mdb_warn("failed to read sotpi_sonode socket addr");
7600f1702c5SYu Xiangning 			return (-1);
7610f1702c5SYu Xiangning 		}
7620f1702c5SYu Xiangning 
7630f1702c5SYu Xiangning 		mdb_printf("socket: ");
7640f1702c5SYu Xiangning 		pfiles_print_addr(laddr);
7650f1702c5SYu Xiangning 	}
7660f1702c5SYu Xiangning 
7670f1702c5SYu Xiangning 	if (sotpi_sonode->st_info.sti_faddr_valid == 1) {
7680f1702c5SYu Xiangning 		struct sockaddr *faddr =
7690f1702c5SYu Xiangning 		    mdb_alloc(sotpi_sonode->st_info.sti_faddr_len, UM_SLEEP);
7700f1702c5SYu Xiangning 		if (mdb_vread(faddr, sotpi_sonode->st_info.sti_faddr_len,
7710f1702c5SYu Xiangning 		    (uintptr_t)sotpi_sonode->st_info.sti_faddr_sa) == -1) {
7720f1702c5SYu Xiangning 			mdb_warn("failed to read sotpi_sonode remote addr");
7730f1702c5SYu Xiangning 			return (-1);
7740f1702c5SYu Xiangning 		}
7750f1702c5SYu Xiangning 
7760f1702c5SYu Xiangning 		mdb_printf("remote: ");
7770f1702c5SYu Xiangning 		pfiles_print_addr(faddr);
7780f1702c5SYu Xiangning 	}
7790f1702c5SYu Xiangning 
7800f1702c5SYu Xiangning 	return (0);
7810f1702c5SYu Xiangning }
7820f1702c5SYu Xiangning 
7830f1702c5SYu Xiangning static int
7840f1702c5SYu Xiangning tcpip_sock_print(struct sonode *socknode)
7850f1702c5SYu Xiangning {
7860f1702c5SYu Xiangning 	switch (socknode->so_family) {
7870f1702c5SYu Xiangning 	case AF_INET:
7880f1702c5SYu Xiangning 	{
7890f1702c5SYu Xiangning 		conn_t conn_t;
7900f1702c5SYu Xiangning 		in_port_t port;
7910f1702c5SYu Xiangning 
7920f1702c5SYu Xiangning 		if (mdb_vread(&conn_t, sizeof (conn_t),
7930f1702c5SYu Xiangning 		    (uintptr_t)socknode->so_proto_handle) == -1) {
7940f1702c5SYu Xiangning 			mdb_warn("failed to read conn_t V4");
7950f1702c5SYu Xiangning 			return (-1);
7960f1702c5SYu Xiangning 		}
7970f1702c5SYu Xiangning 
7980f1702c5SYu Xiangning 		mdb_printf("socket: ");
7990f1702c5SYu Xiangning 		mdb_nhconvert(&port, &conn_t.conn_lport, sizeof (port));
800bd670b35SErik Nordmark 		mdb_printf("AF_INET %I %d ", conn_t.conn_laddr_v4, port);
8010f1702c5SYu Xiangning 
8020f1702c5SYu Xiangning 		/*
8030f1702c5SYu Xiangning 		 * If this is a listening socket, we don't print
8040f1702c5SYu Xiangning 		 * the remote address.
8050f1702c5SYu Xiangning 		 */
8060f1702c5SYu Xiangning 		if (IPCL_IS_TCP(&conn_t) && IPCL_IS_BOUND(&conn_t) == 0 ||
8070f1702c5SYu Xiangning 		    IPCL_IS_UDP(&conn_t) && IPCL_IS_CONNECTED(&conn_t)) {
8080f1702c5SYu Xiangning 			mdb_printf("remote: ");
8090f1702c5SYu Xiangning 			mdb_nhconvert(&port, &conn_t.conn_fport, sizeof (port));
810bd670b35SErik Nordmark 			mdb_printf("AF_INET %I %d ", conn_t.conn_faddr_v4,
811bd670b35SErik Nordmark 			    port);
8120f1702c5SYu Xiangning 		}
8130f1702c5SYu Xiangning 
8140f1702c5SYu Xiangning 		break;
8150f1702c5SYu Xiangning 	}
8160f1702c5SYu Xiangning 
8170f1702c5SYu Xiangning 	case AF_INET6:
8180f1702c5SYu Xiangning 	{
8190f1702c5SYu Xiangning 		conn_t conn_t;
8200f1702c5SYu Xiangning 		in_port_t port;
8210f1702c5SYu Xiangning 
8220f1702c5SYu Xiangning 		if (mdb_vread(&conn_t, sizeof (conn_t),
8230f1702c5SYu Xiangning 		    (uintptr_t)socknode->so_proto_handle) == -1) {
8240f1702c5SYu Xiangning 			mdb_warn("failed to read conn_t V6");
8250f1702c5SYu Xiangning 			return (-1);
8260f1702c5SYu Xiangning 		}
8270f1702c5SYu Xiangning 
8280f1702c5SYu Xiangning 		mdb_printf("socket: ");
8290f1702c5SYu Xiangning 		mdb_nhconvert(&port, &conn_t.conn_lport, sizeof (port));
830bd670b35SErik Nordmark 		mdb_printf("AF_INET6 %N %d ", &conn_t.conn_laddr_v4, port);
8310f1702c5SYu Xiangning 
8320f1702c5SYu Xiangning 		/*
8330f1702c5SYu Xiangning 		 * If this is a listening socket, we don't print
8340f1702c5SYu Xiangning 		 * the remote address.
8350f1702c5SYu Xiangning 		 */
8360f1702c5SYu Xiangning 		if (IPCL_IS_TCP(&conn_t) && IPCL_IS_BOUND(&conn_t) == 0 ||
8370f1702c5SYu Xiangning 		    IPCL_IS_UDP(&conn_t) && IPCL_IS_CONNECTED(&conn_t)) {
8380f1702c5SYu Xiangning 			mdb_printf("remote: ");
8390f1702c5SYu Xiangning 			mdb_nhconvert(&port, &conn_t.conn_fport, sizeof (port));
840bd670b35SErik Nordmark 			mdb_printf("AF_INET6 %N %d ", &conn_t.conn_faddr_v6,
841bd670b35SErik Nordmark 			    port);
8420f1702c5SYu Xiangning 		}
8430f1702c5SYu Xiangning 
8440f1702c5SYu Xiangning 		break;
8450f1702c5SYu Xiangning 	}
8460f1702c5SYu Xiangning 
8470f1702c5SYu Xiangning 	default:
8480f1702c5SYu Xiangning 		mdb_printf("AF_?? (%d)", socknode->so_family);
8490f1702c5SYu Xiangning 		break;
8500f1702c5SYu Xiangning 	}
8510f1702c5SYu Xiangning 
8520f1702c5SYu Xiangning 	return (0);
8530f1702c5SYu Xiangning }
8540f1702c5SYu Xiangning 
8550f1702c5SYu Xiangning static int
8560f1702c5SYu Xiangning sctp_sock_print(struct sonode *socknode)
8570f1702c5SYu Xiangning {
8580f1702c5SYu Xiangning 	sctp_t sctp_t;
859bd670b35SErik Nordmark 	conn_t conns;
8600f1702c5SYu Xiangning 
8610f1702c5SYu Xiangning 	struct sockaddr *laddr = mdb_alloc(sizeof (struct sockaddr), UM_SLEEP);
8620f1702c5SYu Xiangning 	struct sockaddr *faddr = mdb_alloc(sizeof (struct sockaddr), UM_SLEEP);
8630f1702c5SYu Xiangning 
8640f1702c5SYu Xiangning 	if (mdb_vread(&sctp_t, sizeof (sctp_t),
8650f1702c5SYu Xiangning 	    (uintptr_t)socknode->so_proto_handle) == -1) {
8660f1702c5SYu Xiangning 		mdb_warn("failed to read sctp_t");
8670f1702c5SYu Xiangning 		return (-1);
8680f1702c5SYu Xiangning 	}
8690f1702c5SYu Xiangning 
870bd670b35SErik Nordmark 	if (mdb_vread(&conns, sizeof (conn_t),
871bd670b35SErik Nordmark 	    (uintptr_t)sctp_t.sctp_connp) == -1) {
872bd670b35SErik Nordmark 		mdb_warn("failed to read conn_t at %p",
873bd670b35SErik Nordmark 		    (uintptr_t)sctp_t.sctp_connp);
874bd670b35SErik Nordmark 		return (-1);
875bd670b35SErik Nordmark 	}
876bd670b35SErik Nordmark 	sctp_t.sctp_connp = &conns;
877bd670b35SErik Nordmark 
8780f1702c5SYu Xiangning 	if (sctp_getsockaddr(&sctp_t, laddr) == 0) {
8790f1702c5SYu Xiangning 		mdb_printf("socket:");
8800f1702c5SYu Xiangning 		pfiles_print_addr(laddr);
8810f1702c5SYu Xiangning 	}
8820f1702c5SYu Xiangning 	if (sctp_getpeeraddr(&sctp_t, faddr) == 0) {
8830f1702c5SYu Xiangning 		mdb_printf("remote:");
8840f1702c5SYu Xiangning 		pfiles_print_addr(faddr);
8850f1702c5SYu Xiangning 	}
8860f1702c5SYu Xiangning 
8870f1702c5SYu Xiangning 	return (0);
8880f1702c5SYu Xiangning }
8890f1702c5SYu Xiangning 
8900f1702c5SYu Xiangning /* ARGSUSED */
8910f1702c5SYu Xiangning static int
8920f1702c5SYu Xiangning sdp_sock_print(struct sonode *socknode)
8930f1702c5SYu Xiangning {
8940f1702c5SYu Xiangning 	return (0);
8950f1702c5SYu Xiangning }
8960f1702c5SYu Xiangning 
8970f1702c5SYu Xiangning struct sock_print {
8980f1702c5SYu Xiangning 	int	family;
8990f1702c5SYu Xiangning 	int	type;
9000f1702c5SYu Xiangning 	int	pro;
9010f1702c5SYu Xiangning 	int	(*print)(struct sonode *socknode);
9020f1702c5SYu Xiangning } sock_prints[] = {
9030f1702c5SYu Xiangning 	{ 2,	2,	0,	tcpip_sock_print },	/* /dev/tcp	*/
9040f1702c5SYu Xiangning 	{ 2,	2,	6,	tcpip_sock_print },	/* /dev/tcp	*/
9050f1702c5SYu Xiangning 	{ 26,	2,	0,	tcpip_sock_print },	/* /dev/tcp6	*/
9060f1702c5SYu Xiangning 	{ 26,	2,	6,	tcpip_sock_print },	/* /dev/tcp6	*/
9070f1702c5SYu Xiangning 	{ 2,	1,	0,	tcpip_sock_print },	/* /dev/udp	*/
9080f1702c5SYu Xiangning 	{ 2,	1,	17,	tcpip_sock_print },	/* /dev/udp	*/
9090f1702c5SYu Xiangning 	{ 26,	1,	0,	tcpip_sock_print },	/* /dev/udp6	*/
9100f1702c5SYu Xiangning 	{ 26,	1,	17,	tcpip_sock_print },	/* /dev/udp6	*/
9110f1702c5SYu Xiangning 	{ 2,	4,	0,	tcpip_sock_print },	/* /dev/rawip	*/
9120f1702c5SYu Xiangning 	{ 26,	4,	0,	tcpip_sock_print },	/* /dev/rawip6	*/
9130f1702c5SYu Xiangning 	{ 2,	2,	132,	sctp_sock_print },	/* /dev/sctp	*/
9140f1702c5SYu Xiangning 	{ 26,	2,	132,	sctp_sock_print },	/* /dev/sctp6	*/
9150f1702c5SYu Xiangning 	{ 2,	6,	132,	sctp_sock_print },	/* /dev/sctp	*/
9160f1702c5SYu Xiangning 	{ 26,	6,	132,	sctp_sock_print },	/* /dev/sctp6	*/
9170f1702c5SYu Xiangning 	{ 24,	4,	0,	tcpip_sock_print },	/* /dev/rts	*/
9180f1702c5SYu Xiangning 	{ 2,	2,	257,	sdp_sock_print },	/* /dev/sdp	*/
9190f1702c5SYu Xiangning 	{ 26,	2,	257,	sdp_sock_print },	/* /dev/sdp	*/
9200f1702c5SYu Xiangning };
9210f1702c5SYu Xiangning 
9220f1702c5SYu Xiangning #define	NUM_SOCK_PRINTS                                         \
9230f1702c5SYu Xiangning 	(sizeof (sock_prints) / sizeof (struct sock_print))
9240f1702c5SYu Xiangning 
9257c478bd9Sstevel@tonic-gate static int
9267c478bd9Sstevel@tonic-gate pfile_callback(uintptr_t addr, const struct file *f, struct pfiles_cbdata *cb)
9277c478bd9Sstevel@tonic-gate {
9287c478bd9Sstevel@tonic-gate 	vnode_t v, layer_vn;
9297c478bd9Sstevel@tonic-gate 	int myfd = cb->fd;
9307c478bd9Sstevel@tonic-gate 	const char *type;
9317c478bd9Sstevel@tonic-gate 	char path[MAXPATHLEN];
9327c478bd9Sstevel@tonic-gate 	uintptr_t top_vnodep, realvpp;
9337c478bd9Sstevel@tonic-gate 	char fsname[_ST_FSTYPSZ];
9347c478bd9Sstevel@tonic-gate 	int err, i;
9357c478bd9Sstevel@tonic-gate 
9367c478bd9Sstevel@tonic-gate 	cb->fd++;
9377c478bd9Sstevel@tonic-gate 
9387c478bd9Sstevel@tonic-gate 	if (addr == NULL) {
9397c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
9407c478bd9Sstevel@tonic-gate 	}
9417c478bd9Sstevel@tonic-gate 
9427c478bd9Sstevel@tonic-gate 	top_vnodep = realvpp = (uintptr_t)f->f_vnode;
9437c478bd9Sstevel@tonic-gate 
9447c478bd9Sstevel@tonic-gate 	if (mdb_vread(&v, sizeof (v), realvpp) == -1) {
9457c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read vnode");
9467c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
9477c478bd9Sstevel@tonic-gate 	}
9487c478bd9Sstevel@tonic-gate 
9497c478bd9Sstevel@tonic-gate 	type = "?";
950*1665390bSRichard Lowe 	for (i = 0; i < NUM_FS_TYPES; i++) {
951*1665390bSRichard Lowe 		if (fs_types[i].type == v.v_type) {
9527c478bd9Sstevel@tonic-gate 			type = fs_types[i].name;
953*1665390bSRichard Lowe 			break;
954*1665390bSRichard Lowe 		}
9557c478bd9Sstevel@tonic-gate 	}
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate 	do {
9587c478bd9Sstevel@tonic-gate 		uintptr_t next_realvpp;
9597c478bd9Sstevel@tonic-gate 
9607c478bd9Sstevel@tonic-gate 		err = next_realvp(realvpp, &layer_vn, &next_realvpp);
9617c478bd9Sstevel@tonic-gate 		if (next_realvpp != NULL)
9627c478bd9Sstevel@tonic-gate 			realvpp = next_realvpp;
9637c478bd9Sstevel@tonic-gate 
9647c478bd9Sstevel@tonic-gate 	} while (err == REALVP_CONTINUE);
9657c478bd9Sstevel@tonic-gate 
9667c478bd9Sstevel@tonic-gate 	if (err == REALVP_ERR) {
9677c478bd9Sstevel@tonic-gate 		mdb_warn("failed to do realvp() for %p", realvpp);
9687c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
9697c478bd9Sstevel@tonic-gate 	}
9707c478bd9Sstevel@tonic-gate 
9717c478bd9Sstevel@tonic-gate 	if (read_fsname((uintptr_t)layer_vn.v_vfsp, fsname) == -1)
9727c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate 	mdb_printf("%4d %4s %?0p ", myfd, type, top_vnodep);
9757c478bd9Sstevel@tonic-gate 
9767c478bd9Sstevel@tonic-gate 	if (cb->opt_p) {
9777c478bd9Sstevel@tonic-gate 		if (pfiles_dig_pathname(top_vnodep, path) == -1)
9787c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
9797c478bd9Sstevel@tonic-gate 
9807c478bd9Sstevel@tonic-gate 		mdb_printf("%s\n", path);
9817c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
9827c478bd9Sstevel@tonic-gate 	}
9837c478bd9Sstevel@tonic-gate 
9847c478bd9Sstevel@tonic-gate 	/*
9857c478bd9Sstevel@tonic-gate 	 * Sockets generally don't have interesting pathnames; we only
9867c478bd9Sstevel@tonic-gate 	 * show those in the '-p' view.
9877c478bd9Sstevel@tonic-gate 	 */
9887c478bd9Sstevel@tonic-gate 	path[0] = '\0';
9897c478bd9Sstevel@tonic-gate 	if (v.v_type != VSOCK) {
9907c478bd9Sstevel@tonic-gate 		if (pfiles_dig_pathname(top_vnodep, path) == -1)
9917c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
9927c478bd9Sstevel@tonic-gate 	}
9937c478bd9Sstevel@tonic-gate 	mdb_printf("%s%s", path, path[0] == '\0' ? "" : " ");
9947c478bd9Sstevel@tonic-gate 
9957c478bd9Sstevel@tonic-gate 	switch (v.v_type) {
9967c478bd9Sstevel@tonic-gate 	case VDOOR:
9977c478bd9Sstevel@tonic-gate 	{
9987c478bd9Sstevel@tonic-gate 		door_node_t doornode;
9997c478bd9Sstevel@tonic-gate 		proc_t pr;
10007c478bd9Sstevel@tonic-gate 
10017c478bd9Sstevel@tonic-gate 		if (mdb_vread(&doornode, sizeof (doornode),
10027c478bd9Sstevel@tonic-gate 		    (uintptr_t)layer_vn.v_data) == -1) {
10037c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read door_node");
10047c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
10057c478bd9Sstevel@tonic-gate 		}
10067c478bd9Sstevel@tonic-gate 
10077c478bd9Sstevel@tonic-gate 		if (mdb_vread(&pr, sizeof (pr),
10087c478bd9Sstevel@tonic-gate 		    (uintptr_t)doornode.door_target) == -1) {
10097c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read door server process %p",
10107c478bd9Sstevel@tonic-gate 			    doornode.door_target);
10117c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
10127c478bd9Sstevel@tonic-gate 		}
10137c478bd9Sstevel@tonic-gate 		mdb_printf("[door to '%s' (proc=%p)]", pr.p_user.u_comm,
10147c478bd9Sstevel@tonic-gate 		    doornode.door_target);
10157c478bd9Sstevel@tonic-gate 		break;
10167c478bd9Sstevel@tonic-gate 	}
10177c478bd9Sstevel@tonic-gate 
10187c478bd9Sstevel@tonic-gate 	case VSOCK:
10197c478bd9Sstevel@tonic-gate 	{
10200f1702c5SYu Xiangning 		vnode_t v_sock;
10210f1702c5SYu Xiangning 		struct sonode so;
10227c478bd9Sstevel@tonic-gate 
10230f1702c5SYu Xiangning 		if (mdb_vread(&v_sock, sizeof (v_sock), realvpp) == -1) {
10240f1702c5SYu Xiangning 			mdb_warn("failed to read socket vnode");
10250f1702c5SYu Xiangning 			return (DCMD_ERR);
10260f1702c5SYu Xiangning 		}
10270f1702c5SYu Xiangning 
10280f1702c5SYu Xiangning 		/*
10290f1702c5SYu Xiangning 		 * Sockets can be non-stream or stream, they have to be dealed
10300f1702c5SYu Xiangning 		 * with differently.
10310f1702c5SYu Xiangning 		 */
10320f1702c5SYu Xiangning 		if (v_sock.v_stream == NULL) {
10330f1702c5SYu Xiangning 			if (pfiles_get_sonode(&v_sock, &so) == -1)
10340f1702c5SYu Xiangning 				return (DCMD_ERR);
10350f1702c5SYu Xiangning 
10360f1702c5SYu Xiangning 			/* Pick the proper methods. */
10370f1702c5SYu Xiangning 			for (i = 0; i <= NUM_SOCK_PRINTS; i++) {
10380f1702c5SYu Xiangning 				if ((sock_prints[i].family == so.so_family &&
10390f1702c5SYu Xiangning 				    sock_prints[i].type == so.so_type &&
10400f1702c5SYu Xiangning 				    sock_prints[i].pro == so.so_protocol) ||
10410f1702c5SYu Xiangning 				    (sock_prints[i].family == so.so_family &&
10420f1702c5SYu Xiangning 				    sock_prints[i].type == so.so_type &&
10430f1702c5SYu Xiangning 				    so.so_type == SOCK_RAW)) {
10440f1702c5SYu Xiangning 					if ((*sock_prints[i].print)(&so) == -1)
10450f1702c5SYu Xiangning 						return (DCMD_ERR);
10460f1702c5SYu Xiangning 				}
10470f1702c5SYu Xiangning 			}
10480f1702c5SYu Xiangning 		} else {
10490f1702c5SYu Xiangning 			sotpi_sonode_t sotpi_sonode;
10500f1702c5SYu Xiangning 
10510f1702c5SYu Xiangning 			if (pfiles_get_sonode(&v_sock, &so) == -1)
10527c478bd9Sstevel@tonic-gate 				return (DCMD_ERR);
10537c478bd9Sstevel@tonic-gate 
10547c478bd9Sstevel@tonic-gate 			/*
10550f1702c5SYu Xiangning 			 * If the socket is a fallback socket, read its related
10560f1702c5SYu Xiangning 			 * information separately; otherwise, read it as a whole
10570f1702c5SYu Xiangning 			 * tpi socket.
10587c478bd9Sstevel@tonic-gate 			 */
10590f1702c5SYu Xiangning 			if (so.so_state & SS_FALLBACK_COMP) {
10600f1702c5SYu Xiangning 				sotpi_sonode.st_sonode = so;
10610f1702c5SYu Xiangning 
10620f1702c5SYu Xiangning 				if (mdb_vread(&(sotpi_sonode.st_info),
10630f1702c5SYu Xiangning 				    sizeof (sotpi_info_t),
10640f1702c5SYu Xiangning 				    (uintptr_t)so.so_priv) == -1)
10650f1702c5SYu Xiangning 					return (DCMD_ERR);
10660f1702c5SYu Xiangning 			} else {
10670f1702c5SYu Xiangning 				if (pfiles_get_tpi_sonode(&v_sock,
10680f1702c5SYu Xiangning 				    &sotpi_sonode) == -1)
10697c478bd9Sstevel@tonic-gate 					return (DCMD_ERR);
10707c478bd9Sstevel@tonic-gate 			}
10717c478bd9Sstevel@tonic-gate 
10720f1702c5SYu Xiangning 			if (tpi_sock_print(&sotpi_sonode) == -1)
10737c478bd9Sstevel@tonic-gate 				return (DCMD_ERR);
10747c478bd9Sstevel@tonic-gate 		}
10757c478bd9Sstevel@tonic-gate 
10767c478bd9Sstevel@tonic-gate 		break;
10777c478bd9Sstevel@tonic-gate 	}
10787c478bd9Sstevel@tonic-gate 
10797c478bd9Sstevel@tonic-gate 	case VPORT:
10807c478bd9Sstevel@tonic-gate 		mdb_printf("[event port (port=%p)]", v.v_data);
10817c478bd9Sstevel@tonic-gate 		break;
10827c478bd9Sstevel@tonic-gate 
10837c478bd9Sstevel@tonic-gate 	case VPROC:
10847c478bd9Sstevel@tonic-gate 	{
10857c478bd9Sstevel@tonic-gate 		prnode_t prnode;
10867c478bd9Sstevel@tonic-gate 		prcommon_t prcommon;
10877c478bd9Sstevel@tonic-gate 
10887c478bd9Sstevel@tonic-gate 		if (mdb_vread(&prnode, sizeof (prnode),
10897c478bd9Sstevel@tonic-gate 		    (uintptr_t)layer_vn.v_data) == -1) {
10907c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read prnode");
10917c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
10927c478bd9Sstevel@tonic-gate 		}
10937c478bd9Sstevel@tonic-gate 
10947c478bd9Sstevel@tonic-gate 		if (mdb_vread(&prcommon, sizeof (prcommon),
10957c478bd9Sstevel@tonic-gate 		    (uintptr_t)prnode.pr_common) == -1) {
10967c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read prcommon %p",
10977c478bd9Sstevel@tonic-gate 			    prnode.pr_common);
10987c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
10997c478bd9Sstevel@tonic-gate 		}
11007c478bd9Sstevel@tonic-gate 
11017c478bd9Sstevel@tonic-gate 		mdb_printf("(proc=%p)", prcommon.prc_proc);
11027c478bd9Sstevel@tonic-gate 		break;
11037c478bd9Sstevel@tonic-gate 	}
11047c478bd9Sstevel@tonic-gate 
11057c478bd9Sstevel@tonic-gate 	default:
11067c478bd9Sstevel@tonic-gate 		break;
11077c478bd9Sstevel@tonic-gate 	}
11087c478bd9Sstevel@tonic-gate 
11097c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
11107c478bd9Sstevel@tonic-gate 
11117c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
11127c478bd9Sstevel@tonic-gate }
11137c478bd9Sstevel@tonic-gate 
11147c478bd9Sstevel@tonic-gate static int
11157c478bd9Sstevel@tonic-gate file_t_callback(uintptr_t addr, const struct file *f, struct pfiles_cbdata *cb)
11167c478bd9Sstevel@tonic-gate {
11177c478bd9Sstevel@tonic-gate 	int myfd = cb->fd;
11187c478bd9Sstevel@tonic-gate 
11197c478bd9Sstevel@tonic-gate 	cb->fd++;
11207c478bd9Sstevel@tonic-gate 
11217c478bd9Sstevel@tonic-gate 	if (addr == NULL) {
11227c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
11237c478bd9Sstevel@tonic-gate 	}
11247c478bd9Sstevel@tonic-gate 
11257c478bd9Sstevel@tonic-gate 	/*
11267c478bd9Sstevel@tonic-gate 	 * We really need 20 digits to print a 64-bit offset_t, but this
11277c478bd9Sstevel@tonic-gate 	 * is exceedingly rare, so we cheat and assume a column width of 10
11287c478bd9Sstevel@tonic-gate 	 * digits, in order to fit everything cleanly into 80 columns.
11297c478bd9Sstevel@tonic-gate 	 */
11307c478bd9Sstevel@tonic-gate 	mdb_printf("%?0p %4d %8x %?0p %10lld %?0p %4d\n",
11317c478bd9Sstevel@tonic-gate 	    addr, myfd, f->f_flag, f->f_vnode, f->f_offset, f->f_cred,
11327c478bd9Sstevel@tonic-gate 	    f->f_count);
11337c478bd9Sstevel@tonic-gate 
11347c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
11357c478bd9Sstevel@tonic-gate }
11367c478bd9Sstevel@tonic-gate 
11377c478bd9Sstevel@tonic-gate int
11387c478bd9Sstevel@tonic-gate pfiles(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
11397c478bd9Sstevel@tonic-gate {
11407c478bd9Sstevel@tonic-gate 	int opt_f = 0;
11417c478bd9Sstevel@tonic-gate 
11427c478bd9Sstevel@tonic-gate 	struct pfiles_cbdata cb;
11437c478bd9Sstevel@tonic-gate 
11447c478bd9Sstevel@tonic-gate 	bzero(&cb, sizeof (cb));
11457c478bd9Sstevel@tonic-gate 
11467c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC))
11477c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
11487c478bd9Sstevel@tonic-gate 
11497c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv,
11507c478bd9Sstevel@tonic-gate 	    'p', MDB_OPT_SETBITS, TRUE, &cb.opt_p,
11517c478bd9Sstevel@tonic-gate 	    'f', MDB_OPT_SETBITS, TRUE, &opt_f, NULL) != argc)
11527c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
11537c478bd9Sstevel@tonic-gate 
11547c478bd9Sstevel@tonic-gate 	if (opt_f) {
11557c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%?s %4s %8s %?s %10s %?s %4s%</u>\n", "FILE",
11567c478bd9Sstevel@tonic-gate 		    "FD", "FLAG", "VNODE", "OFFSET", "CRED", "CNT");
11577c478bd9Sstevel@tonic-gate 		if (mdb_pwalk("allfile", (mdb_walk_cb_t)file_t_callback, &cb,
11587c478bd9Sstevel@tonic-gate 		    addr) == -1) {
11597c478bd9Sstevel@tonic-gate 			mdb_warn("failed to walk 'allfile'");
11607c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
11617c478bd9Sstevel@tonic-gate 		}
11627c478bd9Sstevel@tonic-gate 	} else {
11637c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-4s %4s %?s ", "FD", "TYPE", "VNODE");
11647c478bd9Sstevel@tonic-gate 		if (cb.opt_p)
11657c478bd9Sstevel@tonic-gate 			mdb_printf("PATH");
11667c478bd9Sstevel@tonic-gate 		else
11677c478bd9Sstevel@tonic-gate 			mdb_printf("INFO");
11687c478bd9Sstevel@tonic-gate 		mdb_printf("%</u>\n");
11697c478bd9Sstevel@tonic-gate 
11707c478bd9Sstevel@tonic-gate 		if (mdb_pwalk("allfile", (mdb_walk_cb_t)pfile_callback, &cb,
11717c478bd9Sstevel@tonic-gate 		    addr) == -1) {
11727c478bd9Sstevel@tonic-gate 			mdb_warn("failed to walk 'allfile'");
11737c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
11747c478bd9Sstevel@tonic-gate 		}
11757c478bd9Sstevel@tonic-gate 	}
11767c478bd9Sstevel@tonic-gate 
11777c478bd9Sstevel@tonic-gate 
11787c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
11797c478bd9Sstevel@tonic-gate }
11807c478bd9Sstevel@tonic-gate 
11817c478bd9Sstevel@tonic-gate void
11827c478bd9Sstevel@tonic-gate pfiles_help(void)
11837c478bd9Sstevel@tonic-gate {
11847c478bd9Sstevel@tonic-gate 	mdb_printf(
11857c478bd9Sstevel@tonic-gate 	    "Given the address of a process, print information about files\n"
11867c478bd9Sstevel@tonic-gate 	    "which the process has open.  By default, this includes decoded\n"
11877c478bd9Sstevel@tonic-gate 	    "information about the file depending on file and filesystem type\n"
11887c478bd9Sstevel@tonic-gate 	    "\n"
11897c478bd9Sstevel@tonic-gate 	    "\t-p\tPathnames; omit decoded information.  Only display "
11907c478bd9Sstevel@tonic-gate 	    "pathnames\n"
11917c478bd9Sstevel@tonic-gate 	    "\t-f\tfile_t view; show the file_t structure corresponding to "
11927c478bd9Sstevel@tonic-gate 	    "the fd\n");
11937c478bd9Sstevel@tonic-gate }
1194