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