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 5*d3d50737SRafael Vanoni * Common Development and Distribution License (the "License"). 6*d3d50737SRafael Vanoni * 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 /* 22*d3d50737SRafael Vanoni * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * NCA mdb module. Provides a collection of dcmds and walkers that 287c478bd9Sstevel@tonic-gate * operate on core NCA data structures. Dependencies on NCA internals 297c478bd9Sstevel@tonic-gate * are described in $SRC/uts/common/inet/nca/nca.h. 307c478bd9Sstevel@tonic-gate */ 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 337c478bd9Sstevel@tonic-gate #include <mdb/mdb_ks.h> 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #include <ctype.h> 367c478bd9Sstevel@tonic-gate #include <sys/types.h> 377c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 387c478bd9Sstevel@tonic-gate #include <sys/processor.h> 397c478bd9Sstevel@tonic-gate #include <netinet/in.h> 407c478bd9Sstevel@tonic-gate #include <netinet/ip6.h> /* must come before common.h */ 417c478bd9Sstevel@tonic-gate #include <inet/common.h> /* must come before led.h */ 427c478bd9Sstevel@tonic-gate #include <inet/led.h> /* must come before ip.h */ 437c478bd9Sstevel@tonic-gate #include <inet/ip.h> /* must come before tcp.h */ 447c478bd9Sstevel@tonic-gate #include <inet/tcp.h> /* must come before nca/nca.h */ 457c478bd9Sstevel@tonic-gate #include <inet/nca/nca.h> 467c478bd9Sstevel@tonic-gate #include <inet/nca/ncadoorhdr.h> 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate #define NCA_WALK_PLRU (void *)1 497c478bd9Sstevel@tonic-gate #define NCA_WALK_VLRU (void *)2 507c478bd9Sstevel@tonic-gate #define NCA_ADDR_WIDTH 11 /* kernel addresses *shouldn't* be wider */ 517c478bd9Sstevel@tonic-gate #define YESNO(bool) ((bool) ? 'Y' : 'n') 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate /* 547c478bd9Sstevel@tonic-gate * Structure for assigning a name to a region of memory. 557c478bd9Sstevel@tonic-gate */ 567c478bd9Sstevel@tonic-gate typedef struct { 577c478bd9Sstevel@tonic-gate const char *nm_name; /* name of region */ 587c478bd9Sstevel@tonic-gate int nm_len; /* length to region */ 597c478bd9Sstevel@tonic-gate uintptr_t nm_addr; /* starting address of region */ 607c478bd9Sstevel@tonic-gate } namedmem_t; 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate /* 637c478bd9Sstevel@tonic-gate * Structure for giving a name to a constant. 647c478bd9Sstevel@tonic-gate */ 657c478bd9Sstevel@tonic-gate typedef struct { 667c478bd9Sstevel@tonic-gate const char *const_name; /* name of constant */ 677c478bd9Sstevel@tonic-gate int const_value; /* constant itself */ 687c478bd9Sstevel@tonic-gate } constname_t; 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate /* 717c478bd9Sstevel@tonic-gate * Structure for mapping a bit to a name and a description. Instances 727c478bd9Sstevel@tonic-gate * of this datatype should always be arrays which decode bits in a 737c478bd9Sstevel@tonic-gate * number, and the index into the array should contain the description 747c478bd9Sstevel@tonic-gate * of a bit at position "index" in the number being decoded. The list 757c478bd9Sstevel@tonic-gate * must be terminated by an entry with a NULL `bit_name'. 767c478bd9Sstevel@tonic-gate */ 777c478bd9Sstevel@tonic-gate typedef struct { 787c478bd9Sstevel@tonic-gate const char *bit_name; /* name of bit */ 797c478bd9Sstevel@tonic-gate const char *bit_descr; /* description of bit's purpose */ 807c478bd9Sstevel@tonic-gate } bitname_t; 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate /* 837c478bd9Sstevel@tonic-gate * Note: These should be defined in upside down order to their 847c478bd9Sstevel@tonic-gate * definitions in nca.h 857c478bd9Sstevel@tonic-gate * (Assumes that current ordering convention in nca.h will 867c478bd9Sstevel@tonic-gate * prevail for future additions) 877c478bd9Sstevel@tonic-gate */ 887c478bd9Sstevel@tonic-gate static const bitname_t node_refs[] = { 897c478bd9Sstevel@tonic-gate { "REF_UNUSED", "0x00000001" }, 907c478bd9Sstevel@tonic-gate { "REF_UNUSED", "0x00000002" }, 917c478bd9Sstevel@tonic-gate { "REF_UNUSED", "0x00000004" }, 927c478bd9Sstevel@tonic-gate { "REF_UNUSED", "0x00000008" }, 937c478bd9Sstevel@tonic-gate { "REF_UNUSED", "0x00000010" }, 947c478bd9Sstevel@tonic-gate { "REF_UNUSED", "0x00000020" }, 957c478bd9Sstevel@tonic-gate { "REF_UNUSED", "0x00000040" }, 967c478bd9Sstevel@tonic-gate { "REF_UNUSED", "0x00000080" }, 977c478bd9Sstevel@tonic-gate { "REF_UNUSED", "0x00000100" }, 987c478bd9Sstevel@tonic-gate { "REF_UNUSED", "0x00000200" }, 997c478bd9Sstevel@tonic-gate { "REF_UNUSED", "0x00000400" }, 1007c478bd9Sstevel@tonic-gate { "REF_SEGMAP", "segmapped (PHYS|VIRT)" }, 1017c478bd9Sstevel@tonic-gate { "REF_NCAFS", "NCAfs required" }, 1027c478bd9Sstevel@tonic-gate { "REF_VNODE", "vnode hashed" }, 1037c478bd9Sstevel@tonic-gate { "REF_ERROR", "errored" }, 1047c478bd9Sstevel@tonic-gate { "REF_OWNED", "owned (won't be freed)" }, 1057c478bd9Sstevel@tonic-gate { "REF_UPCALL", "upcall not completed yet" }, 1067c478bd9Sstevel@tonic-gate { "REF_CTAG", "CTAG hashed" }, 1077c478bd9Sstevel@tonic-gate { "REF_PREEMPT", "processing preempted" }, 1087c478bd9Sstevel@tonic-gate { "REF_ONVLRU", "on virtual memory LRU list" }, 1097c478bd9Sstevel@tonic-gate { "REF_ONPLRU", "on physical memory LRU list" }, 1107c478bd9Sstevel@tonic-gate { "REF_MISS", "in miss processing" }, 1117c478bd9Sstevel@tonic-gate { "REF_NOLRU", "not safe for LRU reclaim" }, 1127c478bd9Sstevel@tonic-gate { "REF_RESP", "done parsing response header" }, 1137c478bd9Sstevel@tonic-gate { "REF_FILE", "reachable through filename hash" }, 1147c478bd9Sstevel@tonic-gate { "REF_SAFED", "not safe for use" }, 1157c478bd9Sstevel@tonic-gate { "REF_DONE", "done with miss processing" }, 1167c478bd9Sstevel@tonic-gate { "REF_KMEM", "content-backed via kmem_alloc()" }, 1177c478bd9Sstevel@tonic-gate { "REF_CKSUM", "checksum mapping in-use" }, 1187c478bd9Sstevel@tonic-gate { "REF_VIRT", "virtually mapped (data valid)" }, 1197c478bd9Sstevel@tonic-gate { "REF_PHYS", "physically mapped (pp valid)" }, 1207c478bd9Sstevel@tonic-gate { "REF_URI", "reachable through URI hash" }, 1217c478bd9Sstevel@tonic-gate { NULL } 1227c478bd9Sstevel@tonic-gate }; 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate static const bitname_t advise_types[] = { 1257c478bd9Sstevel@tonic-gate { "ADVISE", "" }, 1267c478bd9Sstevel@tonic-gate { "ADVISE_REPLACE", "replace cached object with provided object" }, 1277c478bd9Sstevel@tonic-gate { "ADVISE_FLUSH", "flush cached object" }, 1287c478bd9Sstevel@tonic-gate { "ADVISE_TEMP", "return this object; keep cached object" }, 1297c478bd9Sstevel@tonic-gate { NULL } 1307c478bd9Sstevel@tonic-gate }; 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate /* 1337c478bd9Sstevel@tonic-gate * Print `len' bytes of buffer `buf'. Handle nonprintable characters 1347c478bd9Sstevel@tonic-gate * specially. 1357c478bd9Sstevel@tonic-gate */ 1367c478bd9Sstevel@tonic-gate static void 1377c478bd9Sstevel@tonic-gate printbuf(uint8_t *buf, size_t len) 1387c478bd9Sstevel@tonic-gate { 1397c478bd9Sstevel@tonic-gate size_t i; 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate /* 1427c478bd9Sstevel@tonic-gate * TODO: display octal form of unprintable characters in dim mode 1437c478bd9Sstevel@tonic-gate * once mdb pager bug is fixed. 1447c478bd9Sstevel@tonic-gate */ 1457c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++) 1467c478bd9Sstevel@tonic-gate mdb_printf(isgraph(buf[i]) ? "%c" : "\\%#o", buf[i]); 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate mdb_printf("\n"); 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate /* 1527c478bd9Sstevel@tonic-gate * Convert HTTP method operation `method' to a name. 1537c478bd9Sstevel@tonic-gate */ 1547c478bd9Sstevel@tonic-gate static const char * 1557c478bd9Sstevel@tonic-gate method2name(unsigned int method) 1567c478bd9Sstevel@tonic-gate { 1577c478bd9Sstevel@tonic-gate unsigned int i; 1587c478bd9Sstevel@tonic-gate static constname_t http_methods[] = { 1597c478bd9Sstevel@tonic-gate { "NCA_UNKNOWN", NCA_UNKNOWN }, 1607c478bd9Sstevel@tonic-gate { "NCA_OPTIONS", NCA_OPTIONS }, 1617c478bd9Sstevel@tonic-gate { "NCA_GET", NCA_GET }, 1627c478bd9Sstevel@tonic-gate { "NCA_HEAD", NCA_HEAD }, 1637c478bd9Sstevel@tonic-gate { "NCA_POST", NCA_POST }, 1647c478bd9Sstevel@tonic-gate { "NCA_PUT", NCA_PUT }, 1657c478bd9Sstevel@tonic-gate { "NCA_DELETE", NCA_DELETE }, 1667c478bd9Sstevel@tonic-gate { "NCA_TRACE", NCA_TRACE }, 1677c478bd9Sstevel@tonic-gate { "NCA_RAW", NCA_RAW }, 1687c478bd9Sstevel@tonic-gate { NULL } 1697c478bd9Sstevel@tonic-gate }; 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate for (i = 0; http_methods[i].const_name != NULL; i++) { 1727c478bd9Sstevel@tonic-gate if (method == http_methods[i].const_value) 1737c478bd9Sstevel@tonic-gate return (http_methods[i].const_name); 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate return ("<unknown>"); 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate /* 1807c478bd9Sstevel@tonic-gate * Convert TCP state `state' to a name. 1817c478bd9Sstevel@tonic-gate */ 1827c478bd9Sstevel@tonic-gate static const char * 1837c478bd9Sstevel@tonic-gate state2name(int state) 1847c478bd9Sstevel@tonic-gate { 1857c478bd9Sstevel@tonic-gate unsigned int i; 1867c478bd9Sstevel@tonic-gate static constname_t tcp_states[] = { 1877c478bd9Sstevel@tonic-gate { "CLOSED", TCPS_CLOSED }, 1887c478bd9Sstevel@tonic-gate { "IDLE", TCPS_IDLE }, 1897c478bd9Sstevel@tonic-gate { "BOUND", TCPS_BOUND }, 1907c478bd9Sstevel@tonic-gate { "LISTEN", TCPS_LISTEN }, 1917c478bd9Sstevel@tonic-gate { "SYN_SENT", TCPS_SYN_SENT }, 1927c478bd9Sstevel@tonic-gate { "SYN_RCVD", TCPS_SYN_RCVD }, 1937c478bd9Sstevel@tonic-gate { "ESTABLISHED", TCPS_ESTABLISHED }, 1947c478bd9Sstevel@tonic-gate { "CLOSE_WAIT", TCPS_CLOSE_WAIT }, 1957c478bd9Sstevel@tonic-gate { "FIN_WAIT1", TCPS_FIN_WAIT_1 }, 1967c478bd9Sstevel@tonic-gate { "FIN_WAIT2", TCPS_FIN_WAIT_2 }, 1977c478bd9Sstevel@tonic-gate { "CLOSING", TCPS_CLOSING }, 1987c478bd9Sstevel@tonic-gate { "LAST_ACK", TCPS_LAST_ACK }, 1997c478bd9Sstevel@tonic-gate { "TIME_WAIT", TCPS_TIME_WAIT }, 2007c478bd9Sstevel@tonic-gate { NULL } 2017c478bd9Sstevel@tonic-gate }; 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate for (i = 0; tcp_states[i].const_name != NULL; i++) { 2047c478bd9Sstevel@tonic-gate if (state == tcp_states[i].const_value) 2057c478bd9Sstevel@tonic-gate return (tcp_states[i].const_name); 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate return ("<unknown>"); 2097c478bd9Sstevel@tonic-gate } 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate /* 2127c478bd9Sstevel@tonic-gate * Convert an nca_io2_t direct_type into a name. 2137c478bd9Sstevel@tonic-gate */ 2147c478bd9Sstevel@tonic-gate static const char * 2157c478bd9Sstevel@tonic-gate direct2name(unsigned int type) 2167c478bd9Sstevel@tonic-gate { 2177c478bd9Sstevel@tonic-gate unsigned int i; 2187c478bd9Sstevel@tonic-gate static const constname_t direct_types[] = { 2197c478bd9Sstevel@tonic-gate { "DIRECT_NONE", NCA_IO_DIRECT_NONE }, 2207c478bd9Sstevel@tonic-gate { "DIRECT_FILENAME", NCA_IO_DIRECT_FILENAME }, 2217c478bd9Sstevel@tonic-gate { "DIRECT_SHMSEG", NCA_IO_DIRECT_SHMSEG }, 2227c478bd9Sstevel@tonic-gate { "DIRECT_FILEDESC", NCA_IO_DIRECT_FILEDESC }, 2237c478bd9Sstevel@tonic-gate { "DIRECT_CTAG", NCA_IO_DIRECT_CTAG }, 2247c478bd9Sstevel@tonic-gate { "DIRECT_SPLICE", NCA_IO_DIRECT_SPLICE }, 2257c478bd9Sstevel@tonic-gate { "DIRECT_TEE", NCA_IO_DIRECT_TEE }, 2267c478bd9Sstevel@tonic-gate { "DIRECT_FILE_FD", NCA_IO_DIRECT_FILE_FD }, 2277c478bd9Sstevel@tonic-gate { NULL, 0 } 2287c478bd9Sstevel@tonic-gate }; 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate for (i = 0; direct_types[i].const_name != NULL; i++) { 2317c478bd9Sstevel@tonic-gate if (type == direct_types[i].const_value) 2327c478bd9Sstevel@tonic-gate return (direct_types[i].const_name); 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate return ("<unknown>"); 2367c478bd9Sstevel@tonic-gate } 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate /* 2397c478bd9Sstevel@tonic-gate * Convert an nca_io2_t operation into a name. 2407c478bd9Sstevel@tonic-gate */ 2417c478bd9Sstevel@tonic-gate static const char * 2427c478bd9Sstevel@tonic-gate op2name(nca_op_t op) 2437c478bd9Sstevel@tonic-gate { 2447c478bd9Sstevel@tonic-gate unsigned int i; 2457c478bd9Sstevel@tonic-gate static const constname_t op_types[] = { 2467c478bd9Sstevel@tonic-gate { "http", http_op }, 2477c478bd9Sstevel@tonic-gate { "error", error_op }, 2487c478bd9Sstevel@tonic-gate { "error_retry", error_retry_op }, 2497c478bd9Sstevel@tonic-gate { "resource", resource_op }, 2507c478bd9Sstevel@tonic-gate { "timeout", timeout_op }, 2517c478bd9Sstevel@tonic-gate { "door_attach", door_attach_op }, 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate { "log", log_op }, 2547c478bd9Sstevel@tonic-gate { "log_ok", log_ok_op }, 2557c478bd9Sstevel@tonic-gate { "log_error", log_error_op }, 2567c478bd9Sstevel@tonic-gate { "log_op_fiov", log_op_fiov }, 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate { NULL, 0 } 2597c478bd9Sstevel@tonic-gate }; 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate for (i = 0; op_types[i].const_name != NULL; i++) { 2627c478bd9Sstevel@tonic-gate if (op == op_types[i].const_value) 2637c478bd9Sstevel@tonic-gate return (op_types[i].const_name); 2647c478bd9Sstevel@tonic-gate } 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate return ("<unknown>"); 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate /* 2707c478bd9Sstevel@tonic-gate * Convert from ticks to milliseconds. 2717c478bd9Sstevel@tonic-gate */ 2727c478bd9Sstevel@tonic-gate static uint64_t 2737c478bd9Sstevel@tonic-gate tick2msec(uint64_t tick) 2747c478bd9Sstevel@tonic-gate { 2757c478bd9Sstevel@tonic-gate static int tick_per_msec; 2767c478bd9Sstevel@tonic-gate static int msec_per_tick; 2777c478bd9Sstevel@tonic-gate static int once; 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate if (once == 0) { 2807c478bd9Sstevel@tonic-gate if (mdb_readvar(&tick_per_msec, "tick_per_msec") == -1) { 2817c478bd9Sstevel@tonic-gate mdb_warn("cannot read symbol tick_per_msec"); 2827c478bd9Sstevel@tonic-gate return (0); 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate if (mdb_readvar(&msec_per_tick, "msec_per_tick") == -1) { 2857c478bd9Sstevel@tonic-gate mdb_warn("cannot read symbol msec_per_tick"); 2867c478bd9Sstevel@tonic-gate return (0); 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate once++; 2897c478bd9Sstevel@tonic-gate } 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate return (tick_per_msec ? tick / tick_per_msec : tick * msec_per_tick); 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate /* 2957c478bd9Sstevel@tonic-gate * Print the core fields in an nca_io2_t. With the "-v" argument, 2967c478bd9Sstevel@tonic-gate * provide more verbose output. With the "-p" argument, print payload 2977c478bd9Sstevel@tonic-gate * information. 2987c478bd9Sstevel@tonic-gate */ 2997c478bd9Sstevel@tonic-gate static int 3007c478bd9Sstevel@tonic-gate nca_io2(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 3017c478bd9Sstevel@tonic-gate { 3027c478bd9Sstevel@tonic-gate unsigned int i; 3037c478bd9Sstevel@tonic-gate unsigned int payload_len; 3047c478bd9Sstevel@tonic-gate uint64_t payload_output_max = 0; 3057c478bd9Sstevel@tonic-gate unsigned int verbose = FALSE; 3067c478bd9Sstevel@tonic-gate const int IO2_ADVDELT = NCA_ADDR_WIDTH + 1; 3077c478bd9Sstevel@tonic-gate boolean_t arm; 3087c478bd9Sstevel@tonic-gate nca_io2_t io2; 3097c478bd9Sstevel@tonic-gate uint8_t *buf; 3107c478bd9Sstevel@tonic-gate namedmem_t area[3]; 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 3137c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, 3167c478bd9Sstevel@tonic-gate 'p', MDB_OPT_UINT64, &payload_output_max, NULL) != argc) 3177c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate if (!DCMD_HDRSPEC(flags) && verbose) 3207c478bd9Sstevel@tonic-gate mdb_printf("\n\n"); 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) || verbose) { 3237c478bd9Sstevel@tonic-gate mdb_printf("%<u>%-*s %2s %4s %8s %*s %8s %16s %-12s%</u>\n", 3247c478bd9Sstevel@tonic-gate NCA_ADDR_WIDTH, "ADDR", "AV", "MFNP", "TID", 3257c478bd9Sstevel@tonic-gate NCA_ADDR_WIDTH, "CONN", "CONN_TAG", "CACHE_TAG", 3267c478bd9Sstevel@tonic-gate "OPERATION"); 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate if (mdb_vread(&io2, sizeof (nca_io2_t), addr) == -1) { 3307c478bd9Sstevel@tonic-gate mdb_warn("cannot read nca_io2_t at %p", addr); 3317c478bd9Sstevel@tonic-gate return (DCMD_ERR); 3327c478bd9Sstevel@tonic-gate } 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate if (io2.version != NCA_HTTP_VERSION2) 3357c478bd9Sstevel@tonic-gate mdb_warn("nca_io2_t at %p has incorrect version `%u'\n", addr, 3367c478bd9Sstevel@tonic-gate io2.version); 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate mdb_printf("%0*p %02x %c%c%c%c %08x %0*llx %08x %016llx %s\n", 3397c478bd9Sstevel@tonic-gate NCA_ADDR_WIDTH, addr, io2.advisory, YESNO(io2.more), 3407c478bd9Sstevel@tonic-gate YESNO(io2.first), YESNO(io2.nocache), YESNO(io2.preempt), 3417c478bd9Sstevel@tonic-gate (uint32_t)io2.tid, NCA_ADDR_WIDTH, io2.cid, io2.tag, io2.ctag, 3427c478bd9Sstevel@tonic-gate op2name(io2.op)); 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate if (verbose) { 3457c478bd9Sstevel@tonic-gate arm = B_TRUE; 3467c478bd9Sstevel@tonic-gate for (i = 0; advise_types[i].bit_name != NULL; i++) { 3477c478bd9Sstevel@tonic-gate if ((io2.advisory & (1 << i)) == 0) 3487c478bd9Sstevel@tonic-gate continue; 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate if (arm) { 3517c478bd9Sstevel@tonic-gate mdb_printf("%*s|\n", IO2_ADVDELT, ""); 3527c478bd9Sstevel@tonic-gate mdb_printf("%*s+--> ", IO2_ADVDELT, ""); 3537c478bd9Sstevel@tonic-gate arm = B_FALSE; 3547c478bd9Sstevel@tonic-gate } else 3557c478bd9Sstevel@tonic-gate mdb_printf("%*s ", IO2_ADVDELT, ""); 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate mdb_printf("%-15s %s\n", advise_types[i].bit_name, 3587c478bd9Sstevel@tonic-gate advise_types[i].bit_descr); 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate } 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate payload_len = io2.data_len + io2.direct_len + io2.trailer_len; 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate if (payload_output_max == 0 || payload_len == 0) 3657c478bd9Sstevel@tonic-gate return (DCMD_OK); 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate mdb_inc_indent(4); 3687c478bd9Sstevel@tonic-gate mdb_printf("\n%u byte payload consists of:\n", payload_len); 3697c478bd9Sstevel@tonic-gate mdb_inc_indent(4); 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate buf = mdb_alloc(payload_output_max, UM_SLEEP); 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate area[0].nm_name = "data"; 3747c478bd9Sstevel@tonic-gate area[0].nm_addr = addr + io2.data; 3757c478bd9Sstevel@tonic-gate area[0].nm_len = io2.data_len; 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate area[1].nm_name = direct2name(io2.direct_type); 3787c478bd9Sstevel@tonic-gate area[1].nm_addr = addr + io2.direct; 3797c478bd9Sstevel@tonic-gate area[1].nm_len = io2.direct_len; 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate area[2].nm_name = "trailer"; 3827c478bd9Sstevel@tonic-gate area[2].nm_addr = addr + io2.trailer; 3837c478bd9Sstevel@tonic-gate area[2].nm_len = io2.trailer_len; 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof (area) / sizeof (area[0]); i++) { 3867c478bd9Sstevel@tonic-gate if (area[i].nm_len <= 0) 3877c478bd9Sstevel@tonic-gate continue; 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate mdb_printf("%d byte %s area at %p (", area[i].nm_len, 3907c478bd9Sstevel@tonic-gate area[i].nm_name, area[i].nm_addr); 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate if (area[i].nm_len > payload_output_max) { 3937c478bd9Sstevel@tonic-gate mdb_printf("first"); 3947c478bd9Sstevel@tonic-gate area[i].nm_len = (int)payload_output_max; 3957c478bd9Sstevel@tonic-gate } else 3967c478bd9Sstevel@tonic-gate mdb_printf("all"); 3977c478bd9Sstevel@tonic-gate 3987c478bd9Sstevel@tonic-gate mdb_printf(" %u bytes follow):\n", area[i].nm_len); 3997c478bd9Sstevel@tonic-gate if (mdb_vread(buf, area[i].nm_len, area[i].nm_addr) == -1) 4007c478bd9Sstevel@tonic-gate mdb_warn("cannot read %s area at %p", area[i].nm_name, 4017c478bd9Sstevel@tonic-gate area[i].nm_addr); 4027c478bd9Sstevel@tonic-gate else { 4037c478bd9Sstevel@tonic-gate mdb_inc_indent(4); 4047c478bd9Sstevel@tonic-gate printbuf(buf, area[i].nm_len); 4057c478bd9Sstevel@tonic-gate mdb_dec_indent(4); 4067c478bd9Sstevel@tonic-gate } 4077c478bd9Sstevel@tonic-gate } 4087c478bd9Sstevel@tonic-gate mdb_dec_indent(4); 4097c478bd9Sstevel@tonic-gate mdb_dec_indent(4); 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate mdb_free(buf, payload_output_max); 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate return (DCMD_OK); 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate static void 4177c478bd9Sstevel@tonic-gate nca_io2_help(void) 4187c478bd9Sstevel@tonic-gate { 4197c478bd9Sstevel@tonic-gate mdb_printf("Print the core information for a given NCA nca_io2_t.\n"); 4207c478bd9Sstevel@tonic-gate mdb_printf("Options:\n"); 4217c478bd9Sstevel@tonic-gate mdb_printf("\t-p N\tshow up to N bytes of payload information from\n"); 4227c478bd9Sstevel@tonic-gate mdb_printf("\t\teach payload area\n"); 4237c478bd9Sstevel@tonic-gate mdb_printf("\t\t(reminder: default radix is %<b>hex%</b>)\n"); 4247c478bd9Sstevel@tonic-gate mdb_printf("\t-v\tbe verbose (more descriptive)\n"); 4257c478bd9Sstevel@tonic-gate } 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate /* 4287c478bd9Sstevel@tonic-gate * Print the core fields for one or all NCA timers. If no address is 4297c478bd9Sstevel@tonic-gate * specified, all NCA timers are printed; otherwise the specified timer 4307c478bd9Sstevel@tonic-gate * list is printed. With the "-e" argument, the "encapsulated" pointer 4317c478bd9Sstevel@tonic-gate * for each te_t in a given tb_t is shown in parentheses. 4327c478bd9Sstevel@tonic-gate */ 4337c478bd9Sstevel@tonic-gate static int 4347c478bd9Sstevel@tonic-gate nca_timer(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 4357c478bd9Sstevel@tonic-gate { 4367c478bd9Sstevel@tonic-gate unsigned int show_encap = FALSE; 4377c478bd9Sstevel@tonic-gate void *tb_addr, *te_addr; 4387c478bd9Sstevel@tonic-gate clock_t lbolt, first_exec = 0; 4397c478bd9Sstevel@tonic-gate ti_t ti; 4407c478bd9Sstevel@tonic-gate tb_t tb; 4417c478bd9Sstevel@tonic-gate te_t te; 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 4447c478bd9Sstevel@tonic-gate if (mdb_walk_dcmd("nca_timer", "nca_timer", argc, argv) == -1) { 4457c478bd9Sstevel@tonic-gate mdb_warn("cannot walk timer list"); 4467c478bd9Sstevel@tonic-gate return (DCMD_ERR); 4477c478bd9Sstevel@tonic-gate } 4487c478bd9Sstevel@tonic-gate return (DCMD_OK); 4497c478bd9Sstevel@tonic-gate } 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate if (mdb_getopts(argc, argv, 'e', MDB_OPT_SETBITS, TRUE, &show_encap, 4527c478bd9Sstevel@tonic-gate NULL) != argc) 4537c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) { 4567c478bd9Sstevel@tonic-gate mdb_printf("%<u>%-*s %-*s %-55s%</u>\n", NCA_ADDR_WIDTH, "TI", 4577c478bd9Sstevel@tonic-gate NCA_ADDR_WIDTH, "SQUEUE", "FIRELIST +MSEC"); 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate if (mdb_vread(&ti, sizeof (ti_t), addr) == -1) { 4617c478bd9Sstevel@tonic-gate mdb_warn("cannot read ti_t at %p", addr); 4627c478bd9Sstevel@tonic-gate return (DCMD_ERR); 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate 465*d3d50737SRafael Vanoni if ((lbolt = (clock_t)mdb_get_lbolt()) == -1) 4667c478bd9Sstevel@tonic-gate return (DCMD_ERR); 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate mdb_printf("%0*p %0*p", NCA_ADDR_WIDTH, addr, NCA_ADDR_WIDTH, ti.ep); 4697c478bd9Sstevel@tonic-gate mdb_inc_indent(24); 4707c478bd9Sstevel@tonic-gate for (tb_addr = ti.head; tb_addr != NULL; tb_addr = tb.next) { 4717c478bd9Sstevel@tonic-gate if (mdb_vread(&tb, sizeof (tb_t), (uintptr_t)tb_addr) == -1) { 4727c478bd9Sstevel@tonic-gate mdb_warn("cannot read tb_t at %p", tb_addr); 4737c478bd9Sstevel@tonic-gate return (DCMD_ERR); 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate if (first_exec == 0) { 4767c478bd9Sstevel@tonic-gate mdb_printf(" %ld", tick2msec(tb.exec - lbolt)); 4777c478bd9Sstevel@tonic-gate first_exec = tb.exec; 4787c478bd9Sstevel@tonic-gate } else 4797c478bd9Sstevel@tonic-gate mdb_printf(" %+lld", tick2msec(tb.exec - first_exec)); 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate if (!show_encap || tb.head == NULL) 4827c478bd9Sstevel@tonic-gate continue; 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate mdb_printf("("); 4857c478bd9Sstevel@tonic-gate for (te_addr = tb.head; te_addr != NULL; te_addr = te.next) { 4867c478bd9Sstevel@tonic-gate if (mdb_vread(&te, sizeof (te_t), (uintptr_t)te_addr) 4877c478bd9Sstevel@tonic-gate == -1) { 4887c478bd9Sstevel@tonic-gate mdb_warn("cannot read te_t at %p", te_addr); 4897c478bd9Sstevel@tonic-gate return (DCMD_ERR); 4907c478bd9Sstevel@tonic-gate } 4917c478bd9Sstevel@tonic-gate mdb_printf("%0p%s", te.ep, te.next == NULL ? "" : " "); 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate mdb_printf(")"); 4947c478bd9Sstevel@tonic-gate } 4957c478bd9Sstevel@tonic-gate mdb_printf("\n"); 4967c478bd9Sstevel@tonic-gate mdb_dec_indent(24); 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate return (DCMD_OK); 4997c478bd9Sstevel@tonic-gate } 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate static void 5027c478bd9Sstevel@tonic-gate nca_timer_help(void) 5037c478bd9Sstevel@tonic-gate { 5047c478bd9Sstevel@tonic-gate mdb_printf("Print the core information for one or all NCA timer\n"); 5057c478bd9Sstevel@tonic-gate mdb_printf("lists. If no timer list is given, then all timer lists\n"); 5067c478bd9Sstevel@tonic-gate mdb_printf("are shown. For each timer list, the list of timers to\n"); 5077c478bd9Sstevel@tonic-gate mdb_printf("fire on that list are shown, the first in absolute\n"); 5087c478bd9Sstevel@tonic-gate mdb_printf("ticks and the rest in ticks relative to the first.\n\n"); 5097c478bd9Sstevel@tonic-gate mdb_printf("Options:\n"); 5107c478bd9Sstevel@tonic-gate mdb_printf("\t-e\tshow the encapsulating pointer for each event "); 5117c478bd9Sstevel@tonic-gate mdb_printf("at each fire time\n"); 5127c478bd9Sstevel@tonic-gate } 5137c478bd9Sstevel@tonic-gate 5147c478bd9Sstevel@tonic-gate /* 5157c478bd9Sstevel@tonic-gate * Print the core fields in an NCA node_t. With the "-r" argument, 5167c478bd9Sstevel@tonic-gate * provide additional information about the request; with "-v", 5177c478bd9Sstevel@tonic-gate * provide more verbose output. 5187c478bd9Sstevel@tonic-gate */ 5197c478bd9Sstevel@tonic-gate static int 5207c478bd9Sstevel@tonic-gate nca_node(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 5217c478bd9Sstevel@tonic-gate { 5227c478bd9Sstevel@tonic-gate unsigned int i, max; 5237c478bd9Sstevel@tonic-gate unsigned int verbose = FALSE; 5247c478bd9Sstevel@tonic-gate unsigned int request = FALSE; 5257c478bd9Sstevel@tonic-gate const int NODE_REFDELT = NCA_ADDR_WIDTH + 4 + 2; 5267c478bd9Sstevel@tonic-gate boolean_t arm; 5277c478bd9Sstevel@tonic-gate node_t node; 5287c478bd9Sstevel@tonic-gate char *buf; 5297c478bd9Sstevel@tonic-gate namedmem_t hdr[4]; 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 5327c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 5337c478bd9Sstevel@tonic-gate 5347c478bd9Sstevel@tonic-gate if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, 5357c478bd9Sstevel@tonic-gate 'r', MDB_OPT_SETBITS, TRUE, &request, 'p', NULL) != argc) 5367c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 5377c478bd9Sstevel@tonic-gate 5387c478bd9Sstevel@tonic-gate if (!DCMD_HDRSPEC(flags) && verbose) 5397c478bd9Sstevel@tonic-gate mdb_printf("\n\n"); 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) || verbose) { 5427c478bd9Sstevel@tonic-gate mdb_printf("%<u>%-*s %4s %5s %8s %-*s %-*s %-*s %-*s%</u>\n", 5437c478bd9Sstevel@tonic-gate NCA_ADDR_WIDTH, "ADDR", "REF", "STATE", "DATASIZE", 5447c478bd9Sstevel@tonic-gate NCA_ADDR_WIDTH, "SQUEUE", NCA_ADDR_WIDTH, "REQUEST", 5457c478bd9Sstevel@tonic-gate NCA_ADDR_WIDTH, "PLRUN", NCA_ADDR_WIDTH, "VLRUN"); 5467c478bd9Sstevel@tonic-gate } 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate if (mdb_vread(&node, sizeof (node_t), addr) == -1) { 5497c478bd9Sstevel@tonic-gate mdb_warn("cannot read node_t at %p", addr); 5507c478bd9Sstevel@tonic-gate return (DCMD_ERR); 5517c478bd9Sstevel@tonic-gate } 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate mdb_printf("%0*p %4d %05x %8d %0*p %0*p %0*p %0*p\n", 5547c478bd9Sstevel@tonic-gate NCA_ADDR_WIDTH, addr, node.cnt, node.ref, 5557c478bd9Sstevel@tonic-gate node.datasz, NCA_ADDR_WIDTH, node.sqp, NCA_ADDR_WIDTH, 5567c478bd9Sstevel@tonic-gate node.req, NCA_ADDR_WIDTH, node.plrunn, NCA_ADDR_WIDTH, node.vlrunn); 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate if (verbose) { 5597c478bd9Sstevel@tonic-gate arm = B_TRUE; 5607c478bd9Sstevel@tonic-gate for (i = 0; node_refs[i].bit_name != NULL; i++) { 5617c478bd9Sstevel@tonic-gate if ((node.ref & (1 << i)) == 0) 5627c478bd9Sstevel@tonic-gate continue; 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate if (arm) { 5657c478bd9Sstevel@tonic-gate mdb_printf("%*s|\n", NODE_REFDELT, ""); 5667c478bd9Sstevel@tonic-gate mdb_printf("%*s+--> ", NODE_REFDELT, ""); 5677c478bd9Sstevel@tonic-gate arm = B_FALSE; 5687c478bd9Sstevel@tonic-gate } else 5697c478bd9Sstevel@tonic-gate mdb_printf("%*s ", NODE_REFDELT, ""); 5707c478bd9Sstevel@tonic-gate 5717c478bd9Sstevel@tonic-gate mdb_printf("%-12s %s\n", node_refs[i].bit_name, 5727c478bd9Sstevel@tonic-gate node_refs[i].bit_descr); 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate } 5757c478bd9Sstevel@tonic-gate 5767c478bd9Sstevel@tonic-gate if (!request || node.req == NULL) 5777c478bd9Sstevel@tonic-gate return (DCMD_OK); 5787c478bd9Sstevel@tonic-gate 5797c478bd9Sstevel@tonic-gate mdb_inc_indent(4); 5807c478bd9Sstevel@tonic-gate mdb_printf("\n%u byte HTTP/%u.%u %s request (%u bytes in header, " 5817c478bd9Sstevel@tonic-gate "%u in content)\n", node.reqsz, node.version >> 16, 5827c478bd9Sstevel@tonic-gate node.version & 0xff, method2name(node.method), node.reqhdrsz, 5837c478bd9Sstevel@tonic-gate node.reqcontl); 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate hdr[0].nm_name = "URI"; 5867c478bd9Sstevel@tonic-gate hdr[0].nm_addr = (uintptr_t)node.path; 5877c478bd9Sstevel@tonic-gate hdr[0].nm_len = node.pathsz; 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate hdr[1].nm_name = "Accept"; 5907c478bd9Sstevel@tonic-gate hdr[1].nm_addr = (uintptr_t)node.reqaccept; 5917c478bd9Sstevel@tonic-gate hdr[1].nm_len = node.reqacceptsz; 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate hdr[2].nm_name = "Accept-Language"; 5947c478bd9Sstevel@tonic-gate hdr[2].nm_addr = (uintptr_t)node.reqacceptl; 5957c478bd9Sstevel@tonic-gate hdr[2].nm_len = node.reqacceptlsz; 5967c478bd9Sstevel@tonic-gate 5977c478bd9Sstevel@tonic-gate hdr[3].nm_name = "Host"; 5987c478bd9Sstevel@tonic-gate hdr[3].nm_addr = (uintptr_t)node.reqhost; 5997c478bd9Sstevel@tonic-gate hdr[3].nm_len = node.reqhostsz; 6007c478bd9Sstevel@tonic-gate 6017c478bd9Sstevel@tonic-gate /* 6027c478bd9Sstevel@tonic-gate * A little optimization. Allocate all of the necessary memory here, 6037c478bd9Sstevel@tonic-gate * so we don't have to allocate on each loop iteration. 6047c478bd9Sstevel@tonic-gate */ 6057c478bd9Sstevel@tonic-gate 6067c478bd9Sstevel@tonic-gate max = node.reqhdrsz; 6077c478bd9Sstevel@tonic-gate for (i = 0; i < 4; i++) 6087c478bd9Sstevel@tonic-gate max = MAX(max, hdr[i].nm_len); 6097c478bd9Sstevel@tonic-gate max++; 6107c478bd9Sstevel@tonic-gate 6117c478bd9Sstevel@tonic-gate buf = mdb_alloc(max, UM_SLEEP); 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate mdb_inc_indent(4); 6147c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof (hdr) / sizeof (hdr[0]); i++) { 6157c478bd9Sstevel@tonic-gate if (hdr[i].nm_len <= 0) 6167c478bd9Sstevel@tonic-gate continue; 6177c478bd9Sstevel@tonic-gate 6187c478bd9Sstevel@tonic-gate if (mdb_vread(buf, hdr[i].nm_len, hdr[i].nm_addr) == -1) { 6197c478bd9Sstevel@tonic-gate mdb_warn("cannot read \"%s\" header field at %p", 6207c478bd9Sstevel@tonic-gate hdr[i].nm_name, hdr[i].nm_addr); 6217c478bd9Sstevel@tonic-gate continue; 6227c478bd9Sstevel@tonic-gate } 6237c478bd9Sstevel@tonic-gate buf[hdr[i].nm_len] = '\0'; 6247c478bd9Sstevel@tonic-gate 6257c478bd9Sstevel@tonic-gate mdb_printf("%s: ", hdr[i].nm_name); 6267c478bd9Sstevel@tonic-gate mdb_inc_indent(4); 6277c478bd9Sstevel@tonic-gate mdb_printf("%s\n", buf); 6287c478bd9Sstevel@tonic-gate mdb_dec_indent(4); 6297c478bd9Sstevel@tonic-gate } 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate if (node.reqhdrsz > 0 && verbose) { 6327c478bd9Sstevel@tonic-gate if (mdb_vread(buf, node.reqhdrsz, (uintptr_t)node.reqhdr) == -1) 6337c478bd9Sstevel@tonic-gate mdb_warn("cannot read header at %p", node.reqhdr); 6347c478bd9Sstevel@tonic-gate else { 6357c478bd9Sstevel@tonic-gate mdb_printf("Raw header: "); 6367c478bd9Sstevel@tonic-gate mdb_inc_indent(4); 6377c478bd9Sstevel@tonic-gate printbuf((uint8_t *)buf, node.reqhdrsz); 6387c478bd9Sstevel@tonic-gate mdb_dec_indent(4); 6397c478bd9Sstevel@tonic-gate } 6407c478bd9Sstevel@tonic-gate } 6417c478bd9Sstevel@tonic-gate mdb_dec_indent(4); 6427c478bd9Sstevel@tonic-gate mdb_dec_indent(4); 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate mdb_free(buf, max); 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate return (DCMD_OK); 6477c478bd9Sstevel@tonic-gate } 6487c478bd9Sstevel@tonic-gate 6497c478bd9Sstevel@tonic-gate static void 6507c478bd9Sstevel@tonic-gate nca_node_help(void) 6517c478bd9Sstevel@tonic-gate { 6527c478bd9Sstevel@tonic-gate mdb_printf("Print the core information for a given NCA node_t.\n\n"); 6537c478bd9Sstevel@tonic-gate mdb_printf("Options:\n"); 6547c478bd9Sstevel@tonic-gate mdb_printf("\t-r\tdisplay HTTP request information\n"); 6557c478bd9Sstevel@tonic-gate mdb_printf("\t-v\tbe verbose (more descriptive)\n"); 6567c478bd9Sstevel@tonic-gate } 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate /* 6597c478bd9Sstevel@tonic-gate * Print the core fields in an NCA nca_conn_t. With the "-t" argument, skip 6607c478bd9Sstevel@tonic-gate * all nca_conn_t's that are in the TIME_WAIT state. With the "-x" argument, 6617c478bd9Sstevel@tonic-gate * show the xmit data. 6627c478bd9Sstevel@tonic-gate */ 6637c478bd9Sstevel@tonic-gate static int 6647c478bd9Sstevel@tonic-gate nca_conn(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 6657c478bd9Sstevel@tonic-gate { 6667c478bd9Sstevel@tonic-gate unsigned int i; 6677c478bd9Sstevel@tonic-gate nca_conn_t conn; 6687c478bd9Sstevel@tonic-gate unsigned int show_timewait = TRUE; 6697c478bd9Sstevel@tonic-gate unsigned int show_xmit = FALSE; 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 6727c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 6737c478bd9Sstevel@tonic-gate 6747c478bd9Sstevel@tonic-gate if (mdb_getopts(argc, argv, 'x', MDB_OPT_SETBITS, TRUE, &show_xmit, 6757c478bd9Sstevel@tonic-gate 't', MDB_OPT_CLRBITS, TRUE, &show_timewait, NULL) != argc) 6767c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 6777c478bd9Sstevel@tonic-gate 6787c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) { 6797c478bd9Sstevel@tonic-gate mdb_printf("%<u>%-*s %3s %8s %15s %15s %-*s %-10s%</u>\n", 6807c478bd9Sstevel@tonic-gate NCA_ADDR_WIDTH, "ADDR", "REF", "CREATE", "LOCAL_ADDR", 6817c478bd9Sstevel@tonic-gate "REMOTE_ADDR", NCA_ADDR_WIDTH, "NODE", "STATE"); 6827c478bd9Sstevel@tonic-gate } 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate if (mdb_vread(&conn, sizeof (nca_conn_t), addr) == -1) { 6857c478bd9Sstevel@tonic-gate mdb_warn("cannot read nca_conn_t at %p", addr); 6867c478bd9Sstevel@tonic-gate return (DCMD_ERR); 6877c478bd9Sstevel@tonic-gate } 6887c478bd9Sstevel@tonic-gate 6897c478bd9Sstevel@tonic-gate if (!show_timewait && conn.tcp_state == TCPS_TIME_WAIT) 6907c478bd9Sstevel@tonic-gate return (DCMD_OK); 6917c478bd9Sstevel@tonic-gate 6927c478bd9Sstevel@tonic-gate mdb_printf("%0*p %3d %8lx %15I %15I %0*p %s\n", NCA_ADDR_WIDTH, addr, 6937c478bd9Sstevel@tonic-gate conn.ref, conn.create, conn.laddr, conn.faddr, NCA_ADDR_WIDTH, 6947c478bd9Sstevel@tonic-gate conn.req_np, state2name(conn.tcp_state)); 6957c478bd9Sstevel@tonic-gate 6967c478bd9Sstevel@tonic-gate if (show_xmit) { 6977c478bd9Sstevel@tonic-gate mdb_inc_indent(4); 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate for (i = 0; i < TCP_XMIT_MAX_IX; i++) { 7007c478bd9Sstevel@tonic-gate mdb_printf("xmit[%d]\n", i); 7017c478bd9Sstevel@tonic-gate mdb_printf("\tref pointer\t\t%p\n", conn.xmit[i].np); 7027c478bd9Sstevel@tonic-gate mdb_printf("\tdata pointer\t\t%p\n", conn.xmit[i].dp); 7037c478bd9Sstevel@tonic-gate mdb_printf("\tcksum array\t\t%p\n", conn.xmit[i].cp); 7047c478bd9Sstevel@tonic-gate mdb_printf("\tremaining xmit data\t%d\n", 7057c478bd9Sstevel@tonic-gate conn.xmit[i].sz); 7067c478bd9Sstevel@tonic-gate mdb_printf("\tref to node_t\t\t%p\n", 7077c478bd9Sstevel@tonic-gate conn.xmit[i].refed); 7087c478bd9Sstevel@tonic-gate mdb_printf("\tremaining segment data\t%d\n", 7097c478bd9Sstevel@tonic-gate conn.xmit[i].dsz); 7107c478bd9Sstevel@tonic-gate mdb_printf("\tvirtual pointer\t\t%p\n", 7117c478bd9Sstevel@tonic-gate conn.xmit[i].dvp); 7127c478bd9Sstevel@tonic-gate } 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate mdb_dec_indent(4); 7157c478bd9Sstevel@tonic-gate } 7167c478bd9Sstevel@tonic-gate 7177c478bd9Sstevel@tonic-gate return (DCMD_OK); 7187c478bd9Sstevel@tonic-gate } 7197c478bd9Sstevel@tonic-gate 7207c478bd9Sstevel@tonic-gate static void 7217c478bd9Sstevel@tonic-gate nca_conn_help(void) 7227c478bd9Sstevel@tonic-gate { 7237c478bd9Sstevel@tonic-gate mdb_printf("Print the core information for a given NCA " 7247c478bd9Sstevel@tonic-gate "nca_conn_t.\n\n"); 7257c478bd9Sstevel@tonic-gate mdb_printf("Options:\n"); 7267c478bd9Sstevel@tonic-gate mdb_printf("\t-t\tskip connections in the TIME_WAIT state\n"); 7277c478bd9Sstevel@tonic-gate mdb_printf("\t-x\tshow TCP XMIT information\n"); 7287c478bd9Sstevel@tonic-gate } 7297c478bd9Sstevel@tonic-gate 7307c478bd9Sstevel@tonic-gate /* 7317c478bd9Sstevel@tonic-gate * Print the core TCP-related fields in an NCA nca_conn_t. With the "-t" 7327c478bd9Sstevel@tonic-gate * argument, skips all nca_conn_t's that are in the TIME_WAIT state. 7337c478bd9Sstevel@tonic-gate */ 7347c478bd9Sstevel@tonic-gate static int 7357c478bd9Sstevel@tonic-gate nca_tcpconn(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 7367c478bd9Sstevel@tonic-gate { 7377c478bd9Sstevel@tonic-gate nca_conn_t conn; 7387c478bd9Sstevel@tonic-gate unsigned int show_timewait = TRUE; 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 7417c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 7427c478bd9Sstevel@tonic-gate 7437c478bd9Sstevel@tonic-gate if (mdb_getopts(argc, argv, 't', MDB_OPT_CLRBITS, TRUE, &show_timewait, 7447c478bd9Sstevel@tonic-gate NULL) != argc) 7457c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 7467c478bd9Sstevel@tonic-gate 7477c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) { 7487c478bd9Sstevel@tonic-gate mdb_printf("%<u>%-*s %21s %5s %8s %5s %8s %5s %-9s%</u>\n", 7497c478bd9Sstevel@tonic-gate NCA_ADDR_WIDTH, "ADDR", "REMOTE_ADDR", "SWIND", "SUNASEQ", 7507c478bd9Sstevel@tonic-gate "SNSEQ", "RACKSEQ", "RNSEQ", "STATE"); 7517c478bd9Sstevel@tonic-gate } 7527c478bd9Sstevel@tonic-gate 7537c478bd9Sstevel@tonic-gate if (mdb_vread(&conn, sizeof (nca_conn_t), addr) == -1) { 7547c478bd9Sstevel@tonic-gate mdb_warn("cannot read nca_conn_t at %p", addr); 7557c478bd9Sstevel@tonic-gate return (DCMD_ERR); 7567c478bd9Sstevel@tonic-gate } 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate if (!show_timewait && conn.tcp_state == TCPS_TIME_WAIT) 7597c478bd9Sstevel@tonic-gate return (DCMD_OK); 7607c478bd9Sstevel@tonic-gate 7617c478bd9Sstevel@tonic-gate mdb_nhconvert(&conn.conn_fport, &conn.conn_fport, sizeof (in_port_t)); 7627c478bd9Sstevel@tonic-gate 7637c478bd9Sstevel@tonic-gate mdb_printf("%0*p %15I:%05hu %5u %08x %+5d %08x %+5d %-9s\n", 7647c478bd9Sstevel@tonic-gate NCA_ADDR_WIDTH, addr, conn.faddr, conn.conn_fport, conn.tcp_swnd, 7657c478bd9Sstevel@tonic-gate conn.tcp_suna, conn.tcp_snxt - conn.tcp_suna, conn.tcp_rack, 7667c478bd9Sstevel@tonic-gate conn.tcp_rnxt - conn.tcp_rack, state2name(conn.tcp_state)); 7677c478bd9Sstevel@tonic-gate 7687c478bd9Sstevel@tonic-gate return (DCMD_OK); 7697c478bd9Sstevel@tonic-gate } 7707c478bd9Sstevel@tonic-gate 7717c478bd9Sstevel@tonic-gate static void 7727c478bd9Sstevel@tonic-gate nca_tcpconn_help(void) 7737c478bd9Sstevel@tonic-gate { 7747c478bd9Sstevel@tonic-gate mdb_printf("Print the core TCP-related information for a given "); 7757c478bd9Sstevel@tonic-gate mdb_printf("NCA nca_conn_t.\n\n"); 7767c478bd9Sstevel@tonic-gate mdb_printf("Options:\n"); 7777c478bd9Sstevel@tonic-gate mdb_printf("\t-t\tskip connections in the TIME_WAIT state\n"); 7787c478bd9Sstevel@tonic-gate } 7797c478bd9Sstevel@tonic-gate 7807c478bd9Sstevel@tonic-gate /* 7817c478bd9Sstevel@tonic-gate * Initialize a walk for the NCA connection fanout table. Note that 7827c478bd9Sstevel@tonic-gate * local walks are not supported since they're more trouble than 7837c478bd9Sstevel@tonic-gate * they're worth. 7847c478bd9Sstevel@tonic-gate */ 7857c478bd9Sstevel@tonic-gate static int 7867c478bd9Sstevel@tonic-gate nca_connf_walk_init(mdb_walk_state_t *wsp) 7877c478bd9Sstevel@tonic-gate { 7887c478bd9Sstevel@tonic-gate int fanout_size; 7897c478bd9Sstevel@tonic-gate 7907c478bd9Sstevel@tonic-gate if (wsp->walk_addr != 0) { 7917c478bd9Sstevel@tonic-gate mdb_warn("nca_connf_walk does not support local walks\n"); 7927c478bd9Sstevel@tonic-gate return (WALK_DONE); 7937c478bd9Sstevel@tonic-gate } 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate if (mdb_readvar(&wsp->walk_addr, "nca_conn_fanout") == -1) { 7967c478bd9Sstevel@tonic-gate mdb_warn("cannot read symbol nca_conn_fanout"); 7977c478bd9Sstevel@tonic-gate return (WALK_ERR); 7987c478bd9Sstevel@tonic-gate } 7997c478bd9Sstevel@tonic-gate 8007c478bd9Sstevel@tonic-gate if (mdb_readvar(&fanout_size, "nca_conn_fanout_size") == -1) { 8017c478bd9Sstevel@tonic-gate mdb_warn("cannot read symbol nca_conn_fanout_size"); 8027c478bd9Sstevel@tonic-gate return (WALK_ERR); 8037c478bd9Sstevel@tonic-gate } 8047c478bd9Sstevel@tonic-gate 8057c478bd9Sstevel@tonic-gate wsp->walk_data = (void *)(uintptr_t)fanout_size; 8067c478bd9Sstevel@tonic-gate 8077c478bd9Sstevel@tonic-gate return (WALK_NEXT); 8087c478bd9Sstevel@tonic-gate } 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate /* 8117c478bd9Sstevel@tonic-gate * Walk the NCA connection fanout table; `wsp->walk_data' is used to keep 8127c478bd9Sstevel@tonic-gate * track of the number of indicies that are left to walk so we know when 8137c478bd9Sstevel@tonic-gate * to stop. 8147c478bd9Sstevel@tonic-gate */ 8157c478bd9Sstevel@tonic-gate static int 8167c478bd9Sstevel@tonic-gate nca_connf_walk_step(mdb_walk_state_t *wsp) 8177c478bd9Sstevel@tonic-gate { 8187c478bd9Sstevel@tonic-gate connf_t connf; 8197c478bd9Sstevel@tonic-gate nca_conn_t conn; 8207c478bd9Sstevel@tonic-gate int status; 8217c478bd9Sstevel@tonic-gate intptr_t i = (intptr_t)wsp->walk_data; 8227c478bd9Sstevel@tonic-gate 8237c478bd9Sstevel@tonic-gate if (i-- <= 0) 8247c478bd9Sstevel@tonic-gate return (WALK_DONE); 8257c478bd9Sstevel@tonic-gate 8267c478bd9Sstevel@tonic-gate if (mdb_vread(&connf, sizeof (connf_t), wsp->walk_addr) == -1) { 8277c478bd9Sstevel@tonic-gate mdb_warn("cannot read connf_t at %p", wsp->walk_addr); 8287c478bd9Sstevel@tonic-gate return (WALK_ERR); 8297c478bd9Sstevel@tonic-gate } 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate /* 8327c478bd9Sstevel@tonic-gate * No point in walking the fanout if there are no 8337c478bd9Sstevel@tonic-gate * connections in it. 8347c478bd9Sstevel@tonic-gate */ 8357c478bd9Sstevel@tonic-gate if (connf.head != NULL) { 8367c478bd9Sstevel@tonic-gate /* 8377c478bd9Sstevel@tonic-gate * Point to the nca_conn_t instead of the connf_t so that output 8387c478bd9Sstevel@tonic-gate * can be piped to ::nca_conn dcmd. 8397c478bd9Sstevel@tonic-gate */ 8407c478bd9Sstevel@tonic-gate if (mdb_vread(&conn, sizeof (nca_conn_t), 8417c478bd9Sstevel@tonic-gate (uintptr_t)connf.head) == -1) { 8427c478bd9Sstevel@tonic-gate mdb_warn("cannot read nca_conn_t at %p", connf.head); 8437c478bd9Sstevel@tonic-gate return (WALK_ERR); 8447c478bd9Sstevel@tonic-gate } 8457c478bd9Sstevel@tonic-gate status = wsp->walk_callback((uintptr_t)connf.head, &conn, 8467c478bd9Sstevel@tonic-gate wsp->walk_cbdata); 8477c478bd9Sstevel@tonic-gate } else { 8487c478bd9Sstevel@tonic-gate status = WALK_NEXT; 8497c478bd9Sstevel@tonic-gate } 8507c478bd9Sstevel@tonic-gate 8517c478bd9Sstevel@tonic-gate wsp->walk_data = (void *)i; 8527c478bd9Sstevel@tonic-gate wsp->walk_addr += sizeof (connf_t); 8537c478bd9Sstevel@tonic-gate 8547c478bd9Sstevel@tonic-gate return (status); 8557c478bd9Sstevel@tonic-gate } 8567c478bd9Sstevel@tonic-gate 8577c478bd9Sstevel@tonic-gate /* 8587c478bd9Sstevel@tonic-gate * Initialize a walk for the NCA node fanout tables. Note that local 8597c478bd9Sstevel@tonic-gate * walks are not supported since they're more trouble than they're 8607c478bd9Sstevel@tonic-gate * worth. 8617c478bd9Sstevel@tonic-gate */ 8627c478bd9Sstevel@tonic-gate static int 8637c478bd9Sstevel@tonic-gate nca_nodef_walk_init(mdb_walk_state_t *wsp) 8647c478bd9Sstevel@tonic-gate { 8657c478bd9Sstevel@tonic-gate char varname[256]; 8667c478bd9Sstevel@tonic-gate uint32_t size; 8677c478bd9Sstevel@tonic-gate 8687c478bd9Sstevel@tonic-gate if (wsp->walk_addr != 0) { 8697c478bd9Sstevel@tonic-gate mdb_warn("nca_nodef_walk does not support local walks\n"); 8707c478bd9Sstevel@tonic-gate return (WALK_DONE); 8717c478bd9Sstevel@tonic-gate } 8727c478bd9Sstevel@tonic-gate 8737c478bd9Sstevel@tonic-gate if (mdb_readvar(&wsp->walk_addr, wsp->walk_arg) == -1) { 8747c478bd9Sstevel@tonic-gate mdb_warn("cannot read symbol %s", wsp->walk_arg); 8757c478bd9Sstevel@tonic-gate return (WALK_ERR); 8767c478bd9Sstevel@tonic-gate } 8777c478bd9Sstevel@tonic-gate 8787c478bd9Sstevel@tonic-gate mdb_snprintf(varname, sizeof (varname), "%s_sz", wsp->walk_arg); 8797c478bd9Sstevel@tonic-gate 8807c478bd9Sstevel@tonic-gate if (mdb_readvar(&size, varname) == -1) { 8817c478bd9Sstevel@tonic-gate mdb_warn("cannot read symbol %s", varname); 8827c478bd9Sstevel@tonic-gate return (WALK_ERR); 8837c478bd9Sstevel@tonic-gate } 8847c478bd9Sstevel@tonic-gate 8857c478bd9Sstevel@tonic-gate wsp->walk_data = (void *)(uintptr_t)size; 8867c478bd9Sstevel@tonic-gate 8877c478bd9Sstevel@tonic-gate return (WALK_NEXT); 8887c478bd9Sstevel@tonic-gate } 8897c478bd9Sstevel@tonic-gate 8907c478bd9Sstevel@tonic-gate /* 8917c478bd9Sstevel@tonic-gate * Walk the NCA node fanout table; `wsp->walk_data' is used to keep 8927c478bd9Sstevel@tonic-gate * track of the number of indicies that are left to walk so we know 8937c478bd9Sstevel@tonic-gate * when to stop. 8947c478bd9Sstevel@tonic-gate */ 8957c478bd9Sstevel@tonic-gate static int 8967c478bd9Sstevel@tonic-gate nca_nodef_walk_step(mdb_walk_state_t *wsp) 8977c478bd9Sstevel@tonic-gate { 8987c478bd9Sstevel@tonic-gate nodef_t nodef; 8997c478bd9Sstevel@tonic-gate node_t node; 9007c478bd9Sstevel@tonic-gate int status; 9017c478bd9Sstevel@tonic-gate intptr_t i = (intptr_t)wsp->walk_data; 9027c478bd9Sstevel@tonic-gate 9037c478bd9Sstevel@tonic-gate if (i-- <= 0) 9047c478bd9Sstevel@tonic-gate return (WALK_DONE); 9057c478bd9Sstevel@tonic-gate 9067c478bd9Sstevel@tonic-gate if (mdb_vread(&nodef, sizeof (nodef_t), wsp->walk_addr) == -1) { 9077c478bd9Sstevel@tonic-gate mdb_warn("cannot read nodef_t at %p", wsp->walk_addr); 9087c478bd9Sstevel@tonic-gate return (WALK_ERR); 9097c478bd9Sstevel@tonic-gate } 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, &nodef, wsp->walk_cbdata); 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate wsp->walk_data = (void *)i; 9147c478bd9Sstevel@tonic-gate wsp->walk_addr += sizeof (nodef_t); 9157c478bd9Sstevel@tonic-gate 9167c478bd9Sstevel@tonic-gate if (nodef.head != NULL) { 9177c478bd9Sstevel@tonic-gate /* 9187c478bd9Sstevel@tonic-gate * Point to the node_t instead of the nodef_t so that output 9197c478bd9Sstevel@tonic-gate * can be piped to ::nca_node dcmd. 9207c478bd9Sstevel@tonic-gate */ 9217c478bd9Sstevel@tonic-gate if (mdb_vread(&node, sizeof (node), 9227c478bd9Sstevel@tonic-gate (uintptr_t)nodef.head) == -1) { 9237c478bd9Sstevel@tonic-gate mdb_warn("cannot read node_t at %p", nodef.head); 9247c478bd9Sstevel@tonic-gate return (WALK_ERR); 9257c478bd9Sstevel@tonic-gate } 9267c478bd9Sstevel@tonic-gate 9277c478bd9Sstevel@tonic-gate status = wsp->walk_callback((uintptr_t)nodef.head, 9287c478bd9Sstevel@tonic-gate &node, wsp->walk_cbdata); 9297c478bd9Sstevel@tonic-gate } else { 9307c478bd9Sstevel@tonic-gate status = WALK_NEXT; 9317c478bd9Sstevel@tonic-gate } 9327c478bd9Sstevel@tonic-gate 9337c478bd9Sstevel@tonic-gate return (status); 9347c478bd9Sstevel@tonic-gate } 9357c478bd9Sstevel@tonic-gate 9367c478bd9Sstevel@tonic-gate /* 9377c478bd9Sstevel@tonic-gate * Initialize a walk for the NCA CPU table. Note that local walks 9387c478bd9Sstevel@tonic-gate * are not supported since they're more trouble than they're worth. 9397c478bd9Sstevel@tonic-gate */ 9407c478bd9Sstevel@tonic-gate static int 9417c478bd9Sstevel@tonic-gate nca_cpu_walk_init(mdb_walk_state_t *wsp) 9427c478bd9Sstevel@tonic-gate { 9437c478bd9Sstevel@tonic-gate int ncpus; 9447c478bd9Sstevel@tonic-gate 9457c478bd9Sstevel@tonic-gate if (wsp->walk_addr != 0) { 9467c478bd9Sstevel@tonic-gate mdb_warn("nca_cpu_walk does not support local walks\n"); 9477c478bd9Sstevel@tonic-gate return (WALK_DONE); 9487c478bd9Sstevel@tonic-gate } 9497c478bd9Sstevel@tonic-gate 9507c478bd9Sstevel@tonic-gate if (mdb_readvar(&wsp->walk_addr, "nca_gv") == -1) { 9517c478bd9Sstevel@tonic-gate mdb_warn("cannot read symbol nca_gv"); 9527c478bd9Sstevel@tonic-gate return (WALK_ERR); 9537c478bd9Sstevel@tonic-gate } 9547c478bd9Sstevel@tonic-gate 9557c478bd9Sstevel@tonic-gate if (mdb_readvar(&ncpus, "ncpus") == -1) { 9567c478bd9Sstevel@tonic-gate mdb_warn("cannot read symbol ncpus"); 9577c478bd9Sstevel@tonic-gate return (WALK_ERR); 9587c478bd9Sstevel@tonic-gate } 9597c478bd9Sstevel@tonic-gate wsp->walk_data = (void *)(uintptr_t)ncpus; 9607c478bd9Sstevel@tonic-gate 9617c478bd9Sstevel@tonic-gate return (WALK_NEXT); 9627c478bd9Sstevel@tonic-gate } 9637c478bd9Sstevel@tonic-gate 9647c478bd9Sstevel@tonic-gate /* 9657c478bd9Sstevel@tonic-gate * Walk the NCA CPU table; `wsp->walk_data' is used to keep track of the 9667c478bd9Sstevel@tonic-gate * number of CPUs that are left to walk so we know when to stop. 9677c478bd9Sstevel@tonic-gate */ 9687c478bd9Sstevel@tonic-gate static int 9697c478bd9Sstevel@tonic-gate nca_cpu_walk_step(mdb_walk_state_t *wsp) 9707c478bd9Sstevel@tonic-gate { 9717c478bd9Sstevel@tonic-gate nca_cpu_t cpu; 9727c478bd9Sstevel@tonic-gate int status; 9737c478bd9Sstevel@tonic-gate intptr_t curcpu = (intptr_t)wsp->walk_data; 9747c478bd9Sstevel@tonic-gate 9757c478bd9Sstevel@tonic-gate if (curcpu-- <= 0) 9767c478bd9Sstevel@tonic-gate return (WALK_DONE); 9777c478bd9Sstevel@tonic-gate 9787c478bd9Sstevel@tonic-gate if (mdb_vread(&cpu, sizeof (nca_cpu_t), wsp->walk_addr) == -1) { 9797c478bd9Sstevel@tonic-gate mdb_warn("cannot read nca_cpu_t at %p", wsp->walk_addr); 9807c478bd9Sstevel@tonic-gate return (WALK_ERR); 9817c478bd9Sstevel@tonic-gate } 9827c478bd9Sstevel@tonic-gate 9837c478bd9Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, &cpu, wsp->walk_cbdata); 9847c478bd9Sstevel@tonic-gate 9857c478bd9Sstevel@tonic-gate wsp->walk_data = (void *)curcpu; 9867c478bd9Sstevel@tonic-gate wsp->walk_addr += sizeof (nca_cpu_t); 9877c478bd9Sstevel@tonic-gate 9887c478bd9Sstevel@tonic-gate return (status); 9897c478bd9Sstevel@tonic-gate } 9907c478bd9Sstevel@tonic-gate 9917c478bd9Sstevel@tonic-gate /* 9927c478bd9Sstevel@tonic-gate * Initialize a walk for the NCA timer list. Note that local walks 9937c478bd9Sstevel@tonic-gate * are not supported since this walk is layered on top of "nca_cpu" 9947c478bd9Sstevel@tonic-gate * which doesn't support them (and they're not too useful here anyway). 9957c478bd9Sstevel@tonic-gate */ 9967c478bd9Sstevel@tonic-gate static int 9977c478bd9Sstevel@tonic-gate nca_timer_walk_init(mdb_walk_state_t *wsp) 9987c478bd9Sstevel@tonic-gate { 9997c478bd9Sstevel@tonic-gate if (wsp->walk_addr != 0) { 10007c478bd9Sstevel@tonic-gate mdb_warn("nca_timer_walk does not support local walks\n"); 10017c478bd9Sstevel@tonic-gate return (WALK_DONE); 10027c478bd9Sstevel@tonic-gate } 10037c478bd9Sstevel@tonic-gate 10047c478bd9Sstevel@tonic-gate if (mdb_layered_walk("nca_cpu", wsp) == -1) { 10057c478bd9Sstevel@tonic-gate mdb_warn("cannot walk nca_cpu"); 10067c478bd9Sstevel@tonic-gate return (WALK_ERR); 10077c478bd9Sstevel@tonic-gate } 10087c478bd9Sstevel@tonic-gate 10097c478bd9Sstevel@tonic-gate return (WALK_NEXT); 10107c478bd9Sstevel@tonic-gate } 10117c478bd9Sstevel@tonic-gate 10127c478bd9Sstevel@tonic-gate /* 10137c478bd9Sstevel@tonic-gate * Walk the NCA timer list; done as a layered walk on top of "nca_cpu". 10147c478bd9Sstevel@tonic-gate */ 10157c478bd9Sstevel@tonic-gate static int 10167c478bd9Sstevel@tonic-gate nca_timer_walk_step(mdb_walk_state_t *wsp) 10177c478bd9Sstevel@tonic-gate { 10187c478bd9Sstevel@tonic-gate const nca_cpu_t *nca_cpu = wsp->walk_layer; 10197c478bd9Sstevel@tonic-gate ti_t ti; 10207c478bd9Sstevel@tonic-gate 10217c478bd9Sstevel@tonic-gate /* 10227c478bd9Sstevel@tonic-gate * Just skip CPUs that don't have any timers running. 10237c478bd9Sstevel@tonic-gate */ 10247c478bd9Sstevel@tonic-gate if (nca_cpu->tcp_ti == NULL) 10257c478bd9Sstevel@tonic-gate return (WALK_NEXT); 10267c478bd9Sstevel@tonic-gate 10277c478bd9Sstevel@tonic-gate if (mdb_vread(&ti, sizeof (ti_t), (uintptr_t)nca_cpu->tcp_ti) == -1) { 10287c478bd9Sstevel@tonic-gate mdb_warn("cannot read ti_t at %p", nca_cpu->tcp_ti); 10297c478bd9Sstevel@tonic-gate return (WALK_ERR); 10307c478bd9Sstevel@tonic-gate } 10317c478bd9Sstevel@tonic-gate 10327c478bd9Sstevel@tonic-gate return (wsp->walk_callback((uintptr_t)nca_cpu->tcp_ti, &ti, 10337c478bd9Sstevel@tonic-gate wsp->walk_cbdata)); 10347c478bd9Sstevel@tonic-gate } 10357c478bd9Sstevel@tonic-gate 10367c478bd9Sstevel@tonic-gate /* 10377c478bd9Sstevel@tonic-gate * Initialize a walk for NCA node LRUs; the type of LRU to walk should 10387c478bd9Sstevel@tonic-gate * be specified through `wsp->walk_arg'. If no starting location for 10397c478bd9Sstevel@tonic-gate * the walk is given, `wsp->walk_addr' is set to the head of the 10407c478bd9Sstevel@tonic-gate * appropriate LRU. 10417c478bd9Sstevel@tonic-gate */ 10427c478bd9Sstevel@tonic-gate static int 10437c478bd9Sstevel@tonic-gate nca_node_lru_walk_init(mdb_walk_state_t *wsp) 10447c478bd9Sstevel@tonic-gate { 10457c478bd9Sstevel@tonic-gate GElf_Sym sym; 10467c478bd9Sstevel@tonic-gate lru_t lru; 10477c478bd9Sstevel@tonic-gate 10487c478bd9Sstevel@tonic-gate if (wsp->walk_addr != 0) 10497c478bd9Sstevel@tonic-gate return (WALK_NEXT); 10507c478bd9Sstevel@tonic-gate 10517c478bd9Sstevel@tonic-gate /* 10527c478bd9Sstevel@tonic-gate * We do this instead of mdb_readvar() so that we catch changes 10537c478bd9Sstevel@tonic-gate * in the size of the lru_t structure. 10547c478bd9Sstevel@tonic-gate */ 10557c478bd9Sstevel@tonic-gate if (mdb_lookup_by_name("nca_lru", &sym) == -1) { 10567c478bd9Sstevel@tonic-gate mdb_warn("cannot lookup symbol nca_lru"); 10577c478bd9Sstevel@tonic-gate return (WALK_ERR); 10587c478bd9Sstevel@tonic-gate } 10597c478bd9Sstevel@tonic-gate 10607c478bd9Sstevel@tonic-gate if (sym.st_size != sizeof (lru)) { 10617c478bd9Sstevel@tonic-gate mdb_warn("nca_lru object size mismatch\n"); 10627c478bd9Sstevel@tonic-gate return (WALK_ERR); 10637c478bd9Sstevel@tonic-gate } 10647c478bd9Sstevel@tonic-gate 10657c478bd9Sstevel@tonic-gate if (mdb_vread(&lru, sym.st_size, (uintptr_t)sym.st_value) == -1) { 10667c478bd9Sstevel@tonic-gate mdb_warn("cannot read nca_lru at %p", sym.st_value); 10677c478bd9Sstevel@tonic-gate return (WALK_ERR); 10687c478bd9Sstevel@tonic-gate } 10697c478bd9Sstevel@tonic-gate 10707c478bd9Sstevel@tonic-gate if (wsp->walk_arg == NCA_WALK_PLRU) 10717c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)lru.phead; 10727c478bd9Sstevel@tonic-gate else 10737c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)lru.vhead; 10747c478bd9Sstevel@tonic-gate 10757c478bd9Sstevel@tonic-gate return (WALK_NEXT); 10767c478bd9Sstevel@tonic-gate } 10777c478bd9Sstevel@tonic-gate 10787c478bd9Sstevel@tonic-gate /* 10797c478bd9Sstevel@tonic-gate * Walk the NCA node LRUs; the type of LRU to walk should be specified 10807c478bd9Sstevel@tonic-gate * through `wsp->walk_arg'. 10817c478bd9Sstevel@tonic-gate */ 10827c478bd9Sstevel@tonic-gate static int 10837c478bd9Sstevel@tonic-gate nca_node_lru_walk_step(mdb_walk_state_t *wsp) 10847c478bd9Sstevel@tonic-gate { 10857c478bd9Sstevel@tonic-gate node_t node; 10867c478bd9Sstevel@tonic-gate int status; 10877c478bd9Sstevel@tonic-gate 10887c478bd9Sstevel@tonic-gate if (wsp->walk_addr == 0) 10897c478bd9Sstevel@tonic-gate return (WALK_DONE); 10907c478bd9Sstevel@tonic-gate 10917c478bd9Sstevel@tonic-gate if (mdb_vread(&node, sizeof (node_t), wsp->walk_addr) == -1) { 10927c478bd9Sstevel@tonic-gate mdb_warn("cannot read node_t at %p", wsp->walk_addr); 10937c478bd9Sstevel@tonic-gate return (WALK_ERR); 10947c478bd9Sstevel@tonic-gate } 10957c478bd9Sstevel@tonic-gate 10967c478bd9Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, &node, wsp->walk_cbdata); 10977c478bd9Sstevel@tonic-gate 10987c478bd9Sstevel@tonic-gate if (wsp->walk_arg == NCA_WALK_PLRU) 10997c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)node.plrunn; 11007c478bd9Sstevel@tonic-gate else 11017c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)node.vlrunn; 11027c478bd9Sstevel@tonic-gate 11037c478bd9Sstevel@tonic-gate return (status); 11047c478bd9Sstevel@tonic-gate } 11057c478bd9Sstevel@tonic-gate 11067c478bd9Sstevel@tonic-gate /* 11077c478bd9Sstevel@tonic-gate * Walk the NCA node structures; follows node_t next pointers from a 11087c478bd9Sstevel@tonic-gate * given offset, specified through `wsp->walk_arg'. 11097c478bd9Sstevel@tonic-gate */ 11107c478bd9Sstevel@tonic-gate static int 11117c478bd9Sstevel@tonic-gate nca_node_walk_step(mdb_walk_state_t *wsp) 11127c478bd9Sstevel@tonic-gate { 11137c478bd9Sstevel@tonic-gate node_t node; 11147c478bd9Sstevel@tonic-gate int status; 11157c478bd9Sstevel@tonic-gate 11167c478bd9Sstevel@tonic-gate if (wsp->walk_addr == 0) { 11177c478bd9Sstevel@tonic-gate mdb_warn("nca_node_walk does not support global walks\n"); 11187c478bd9Sstevel@tonic-gate return (WALK_DONE); 11197c478bd9Sstevel@tonic-gate } 11207c478bd9Sstevel@tonic-gate 11217c478bd9Sstevel@tonic-gate if (mdb_vread(&node, sizeof (node_t), wsp->walk_addr) == -1) { 11227c478bd9Sstevel@tonic-gate mdb_warn("cannot read node_t at %p", wsp->walk_addr); 11237c478bd9Sstevel@tonic-gate return (WALK_ERR); 11247c478bd9Sstevel@tonic-gate } 11257c478bd9Sstevel@tonic-gate 11267c478bd9Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, &node, wsp->walk_cbdata); 11277c478bd9Sstevel@tonic-gate if (status != WALK_NEXT) 11287c478bd9Sstevel@tonic-gate return (status); 11297c478bd9Sstevel@tonic-gate 11307c478bd9Sstevel@tonic-gate /* LINTED */ 11317c478bd9Sstevel@tonic-gate wsp->walk_addr = *(uintptr_t *)((caddr_t)&node + 11327c478bd9Sstevel@tonic-gate (uint_t)(uintptr_t)wsp->walk_arg); 11337c478bd9Sstevel@tonic-gate 11347c478bd9Sstevel@tonic-gate if (wsp->walk_addr == 0) 11357c478bd9Sstevel@tonic-gate return (WALK_DONE); 11367c478bd9Sstevel@tonic-gate 11377c478bd9Sstevel@tonic-gate return (WALK_NEXT); 11387c478bd9Sstevel@tonic-gate } 11397c478bd9Sstevel@tonic-gate 11407c478bd9Sstevel@tonic-gate /* 11417c478bd9Sstevel@tonic-gate * Walk the NCA connection structures; follows nca_conn_t next pointers 11427c478bd9Sstevel@tonic-gate * from a given offset, specified through `wsp->walk_arg'. 11437c478bd9Sstevel@tonic-gate */ 11447c478bd9Sstevel@tonic-gate static int 11457c478bd9Sstevel@tonic-gate nca_conn_walk_step(mdb_walk_state_t *wsp) 11467c478bd9Sstevel@tonic-gate { 11477c478bd9Sstevel@tonic-gate nca_conn_t conn; 11487c478bd9Sstevel@tonic-gate int status; 11497c478bd9Sstevel@tonic-gate 11507c478bd9Sstevel@tonic-gate if (wsp->walk_addr == 0) { 11517c478bd9Sstevel@tonic-gate mdb_warn("nca_conn_walk does not support global walks\n"); 11527c478bd9Sstevel@tonic-gate return (WALK_DONE); 11537c478bd9Sstevel@tonic-gate } 11547c478bd9Sstevel@tonic-gate 11557c478bd9Sstevel@tonic-gate if (mdb_vread(&conn, sizeof (nca_conn_t), wsp->walk_addr) == -1) { 11567c478bd9Sstevel@tonic-gate mdb_warn("cannot read nca_conn_t at %p", wsp->walk_addr); 11577c478bd9Sstevel@tonic-gate return (WALK_ERR); 11587c478bd9Sstevel@tonic-gate } 11597c478bd9Sstevel@tonic-gate 11607c478bd9Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, &conn, wsp->walk_cbdata); 11617c478bd9Sstevel@tonic-gate if (status != WALK_NEXT) 11627c478bd9Sstevel@tonic-gate return (status); 11637c478bd9Sstevel@tonic-gate 11647c478bd9Sstevel@tonic-gate /* LINTED */ 11657c478bd9Sstevel@tonic-gate wsp->walk_addr = *(uintptr_t *)((caddr_t)&conn + 11667c478bd9Sstevel@tonic-gate (uint_t)(uintptr_t)wsp->walk_arg); 11677c478bd9Sstevel@tonic-gate 11687c478bd9Sstevel@tonic-gate if (wsp->walk_addr == 0) 11697c478bd9Sstevel@tonic-gate return (WALK_DONE); 11707c478bd9Sstevel@tonic-gate 11717c478bd9Sstevel@tonic-gate return (WALK_NEXT); 11727c478bd9Sstevel@tonic-gate } 11737c478bd9Sstevel@tonic-gate 11747c478bd9Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = { 11757c478bd9Sstevel@tonic-gate { "nca_conn", ":[-tx]", "print core NCA nca_conn_t info", nca_conn, 11767c478bd9Sstevel@tonic-gate nca_conn_help }, 11777c478bd9Sstevel@tonic-gate { "nca_tcpconn", ":[-t]", "print TCP NCA nca_conn_t info", 11787c478bd9Sstevel@tonic-gate nca_tcpconn, nca_tcpconn_help }, 11797c478bd9Sstevel@tonic-gate { "nca_io2", ":[-pv]", "print core NCA io2_t info", nca_io2, 11807c478bd9Sstevel@tonic-gate nca_io2_help }, 11817c478bd9Sstevel@tonic-gate { "nca_node", ":[-rv]", "print core NCA node_t info", nca_node, 11827c478bd9Sstevel@tonic-gate nca_node_help }, 11837c478bd9Sstevel@tonic-gate { "nca_timer", "?[-e]", "print core NCA timer info", nca_timer, 11847c478bd9Sstevel@tonic-gate nca_timer_help }, 11857c478bd9Sstevel@tonic-gate { NULL } 11867c478bd9Sstevel@tonic-gate }; 11877c478bd9Sstevel@tonic-gate 11887c478bd9Sstevel@tonic-gate static const mdb_walker_t walkers[] = { 11897c478bd9Sstevel@tonic-gate { "nca_conn_hash", "walk the NCA connection hash chain", 0, 11907c478bd9Sstevel@tonic-gate nca_conn_walk_step, 0, (void *)OFFSETOF(nca_conn_t, hashnext) }, 11917c478bd9Sstevel@tonic-gate { "nca_conn_bind", "walk the NCA connection bind chain", 0, 11927c478bd9Sstevel@tonic-gate nca_conn_walk_step, 0, (void *)OFFSETOF(nca_conn_t, bindnext) }, 11937c478bd9Sstevel@tonic-gate { "nca_conn_miss", "walk the NCA connection miss chain", 0, 11947c478bd9Sstevel@tonic-gate nca_conn_walk_step, 0, (void *)OFFSETOF(nca_conn_t, nodenext) }, 11957c478bd9Sstevel@tonic-gate { "nca_conn_tw", "walk the NCA connection TIME_WAIT chain", 0, 11967c478bd9Sstevel@tonic-gate nca_conn_walk_step, 0, (void *)OFFSETOF(nca_conn_t, twnext) }, 11977c478bd9Sstevel@tonic-gate 11987c478bd9Sstevel@tonic-gate { "nca_node_file", "walk the NCA node file chain", 0, 11997c478bd9Sstevel@tonic-gate nca_node_walk_step, 0, (void *)OFFSETOF(node_t, filenext) }, 12007c478bd9Sstevel@tonic-gate { "nca_node_hash", "walk the NCA node hash chain", 0, 12017c478bd9Sstevel@tonic-gate nca_node_walk_step, 0, (void *)OFFSETOF(node_t, hashnext) }, 12027c478bd9Sstevel@tonic-gate { "nca_node_chunk", "walk the NCA node chunk chain", 0, 12037c478bd9Sstevel@tonic-gate nca_node_walk_step, 0, (void *)OFFSETOF(node_t, next) }, 12047c478bd9Sstevel@tonic-gate { "nca_node_ctag", "walk the NCA node ctag chain", 0, 12057c478bd9Sstevel@tonic-gate nca_node_walk_step, 0, (void *)OFFSETOF(node_t, ctagnext) }, 12067c478bd9Sstevel@tonic-gate 12077c478bd9Sstevel@tonic-gate { "nca_node_plru", "walk the NCA node physical LRU chain", 12087c478bd9Sstevel@tonic-gate nca_node_lru_walk_init, nca_node_lru_walk_step, 0, NCA_WALK_PLRU }, 12097c478bd9Sstevel@tonic-gate { "nca_node_vlru", "walk the NCA node virtual LRU chain", 12107c478bd9Sstevel@tonic-gate nca_node_lru_walk_init, nca_node_lru_walk_step, 0, NCA_WALK_VLRU }, 12117c478bd9Sstevel@tonic-gate 12127c478bd9Sstevel@tonic-gate { "nca_uri_hash", "walk the NCA URI node hash table", 12137c478bd9Sstevel@tonic-gate nca_nodef_walk_init, nca_nodef_walk_step, 0, "ncaurihash" }, 12147c478bd9Sstevel@tonic-gate { "nca_file_hash", "walk the NCA file node hash table", 12157c478bd9Sstevel@tonic-gate nca_nodef_walk_init, nca_nodef_walk_step, 0, "ncafilehash" }, 12167c478bd9Sstevel@tonic-gate { "nca_ctag_hash", "walk the NCA ctag node hash table", 12177c478bd9Sstevel@tonic-gate nca_nodef_walk_init, nca_nodef_walk_step, 0, "ncactaghash" }, 12187c478bd9Sstevel@tonic-gate { "nca_vnode_hash", "walk the NCA vnode node hash table", 12197c478bd9Sstevel@tonic-gate nca_nodef_walk_init, nca_nodef_walk_step, 0, "ncavnodehash" }, 12207c478bd9Sstevel@tonic-gate 12217c478bd9Sstevel@tonic-gate { "nca_cpu", "walk the NCA CPU table", 12227c478bd9Sstevel@tonic-gate nca_cpu_walk_init, nca_cpu_walk_step }, 12237c478bd9Sstevel@tonic-gate { "nca_timer", "walk the NCA timer table", 12247c478bd9Sstevel@tonic-gate nca_timer_walk_init, nca_timer_walk_step }, 12257c478bd9Sstevel@tonic-gate { "nca_connf", "walk the NCA connection fanout", 12267c478bd9Sstevel@tonic-gate nca_connf_walk_init, nca_connf_walk_step }, 12277c478bd9Sstevel@tonic-gate 12287c478bd9Sstevel@tonic-gate { NULL } 12297c478bd9Sstevel@tonic-gate }; 12307c478bd9Sstevel@tonic-gate 12317c478bd9Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers }; 12327c478bd9Sstevel@tonic-gate 12337c478bd9Sstevel@tonic-gate const mdb_modinfo_t * 12347c478bd9Sstevel@tonic-gate _mdb_init(void) 12357c478bd9Sstevel@tonic-gate { 12367c478bd9Sstevel@tonic-gate return (&modinfo); 12377c478bd9Sstevel@tonic-gate } 1238