1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 30*0Sstevel@tonic-gate #include <mdb/mdb_ks.h> 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate #include <sys/types.h> 33*0Sstevel@tonic-gate #include <sys/strsubr.h> 34*0Sstevel@tonic-gate #include <sys/stream.h> 35*0Sstevel@tonic-gate #include <sys/modctl.h> 36*0Sstevel@tonic-gate #include <sys/strft.h> 37*0Sstevel@tonic-gate #include <sys/strsun.h> 38*0Sstevel@tonic-gate #include <sys/sysmacros.h> 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate #include "streams.h" 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gate typedef struct str_flags { 43*0Sstevel@tonic-gate uint_t strf_flag; 44*0Sstevel@tonic-gate const char *strf_name; 45*0Sstevel@tonic-gate const char *strf_descr; 46*0Sstevel@tonic-gate } strflags_t; 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate typedef struct str_types { 49*0Sstevel@tonic-gate const char *strt_name; 50*0Sstevel@tonic-gate int strt_value; 51*0Sstevel@tonic-gate const char *strt_descr; 52*0Sstevel@tonic-gate } strtypes_t; 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate typedef struct ftblk_data { 55*0Sstevel@tonic-gate ftblk_t ft_data; /* Copy of ftblk */ 56*0Sstevel@tonic-gate int ft_ix; /* Index in event list */ 57*0Sstevel@tonic-gate boolean_t ft_in_evlist; /* Iterating through evlist */ 58*0Sstevel@tonic-gate } ftblkdata_t; 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate typedef void qprint_func(queue_t *, queue_t *); 61*0Sstevel@tonic-gate typedef void sdprint_func(stdata_t *, stdata_t *); 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate #define SF(flag) flag, #flag 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate /* 66*0Sstevel@tonic-gate * Queue flags 67*0Sstevel@tonic-gate */ 68*0Sstevel@tonic-gate static const strflags_t qf[] = { 69*0Sstevel@tonic-gate { SF(QENAB), "Queue is already enabled to run" }, 70*0Sstevel@tonic-gate { SF(QWANTR), "Someone wants to read Q" }, 71*0Sstevel@tonic-gate { SF(QWANTW), "Someone wants to write Q" }, 72*0Sstevel@tonic-gate { SF(QFULL), "Q is considered full" }, 73*0Sstevel@tonic-gate { SF(QREADR), "This is the reader (first) Q" }, 74*0Sstevel@tonic-gate { SF(QUSE), "This queue in use (allocation)" }, 75*0Sstevel@tonic-gate { SF(QNOENB), "Don't enable Q via putq" }, 76*0Sstevel@tonic-gate { SF(QWANTRMQSYNC), "Want to remove sync stream Q" }, 77*0Sstevel@tonic-gate { SF(QBACK), "queue has been back-enabled" }, 78*0Sstevel@tonic-gate { SF(0x00000200), "unused (was QHLIST)" }, 79*0Sstevel@tonic-gate { SF(0x00000400), "unused (was QUNSAFE)" }, 80*0Sstevel@tonic-gate { SF(QPAIR), "per queue-pair syncq" }, 81*0Sstevel@tonic-gate { SF(QPERQ), "per queue-instance syncq" }, 82*0Sstevel@tonic-gate { SF(QPERMOD), "per module syncq" }, 83*0Sstevel@tonic-gate { SF(QMTSAFE), "stream module is MT-safe" }, 84*0Sstevel@tonic-gate { SF(QMTOUTPERIM), "Has outer perimeter" }, 85*0Sstevel@tonic-gate { SF(QINSERVICE), "service routine executing" }, 86*0Sstevel@tonic-gate { SF(QWCLOSE), "will not be enabled" }, 87*0Sstevel@tonic-gate { SF(QEND), "last queue in stream" }, 88*0Sstevel@tonic-gate { SF(QWANTWSYNC), "Streamhead wants to write Q" }, 89*0Sstevel@tonic-gate { SF(QSYNCSTR), "Q supports Synchronous STREAMS" }, 90*0Sstevel@tonic-gate { SF(QISDRV), "the Queue is attached to a driver" }, 91*0Sstevel@tonic-gate { SF(0x00400000), "unused (was QHOT)" }, 92*0Sstevel@tonic-gate { SF(0x00800000), "unused (was QNEXTHOT)" }, 93*0Sstevel@tonic-gate { SF(0x01000000), "unused (was _QNEXTLESS)" }, 94*0Sstevel@tonic-gate { SF(0x02000000), "unused" }, 95*0Sstevel@tonic-gate { SF(_QINSERTING), "module is inserted with _I_INSERT" }, 96*0Sstevel@tonic-gate { SF(_QREMOVING) "module is removed with _I_REMOVE" }, 97*0Sstevel@tonic-gate { SF(_QASSOCIATED), "queue is associated with a device" }, 98*0Sstevel@tonic-gate { SF(0), NULL } 99*0Sstevel@tonic-gate }; 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate /* 102*0Sstevel@tonic-gate * Syncq flags 103*0Sstevel@tonic-gate */ 104*0Sstevel@tonic-gate static const struct str_flags sqf[] = { 105*0Sstevel@tonic-gate { SF(SQ_EXCL), "Exclusive access to inner perimeter" }, 106*0Sstevel@tonic-gate { SF(SQ_BLOCKED), "qprocsoff in progress" }, 107*0Sstevel@tonic-gate { SF(SQ_FROZEN), "freezestr in progress" }, 108*0Sstevel@tonic-gate { SF(SQ_WRITER), "qwriter(OUTER) pending or running" }, 109*0Sstevel@tonic-gate { SF(SQ_MESSAGES), "There are messages on syncq" }, 110*0Sstevel@tonic-gate { SF(SQ_WANTWAKEUP) "Thread waiting on sq_wait" }, 111*0Sstevel@tonic-gate { SF(SQ_WANTEXWAKEUP), "Thread waiting on sq_exwait" }, 112*0Sstevel@tonic-gate { SF(SQ_EVENTS), "There are events on syncq" }, 113*0Sstevel@tonic-gate { SF(0), NULL } 114*0Sstevel@tonic-gate }; 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate /* 117*0Sstevel@tonic-gate * Syncq types 118*0Sstevel@tonic-gate */ 119*0Sstevel@tonic-gate static const struct str_flags sqt[] = { 120*0Sstevel@tonic-gate { SF(SQ_CIPUT), "Concurrent inner put procedure" }, 121*0Sstevel@tonic-gate { SF(SQ_CISVC), "Concurrent inner svc procedure" }, 122*0Sstevel@tonic-gate { SF(SQ_CIOC), "Concurrent inner open/close" }, 123*0Sstevel@tonic-gate { SF(SQ_CICB), "Concurrent inner callback" }, 124*0Sstevel@tonic-gate { SF(SQ_COPUT), "Concurrent outer put procedure" }, 125*0Sstevel@tonic-gate { SF(SQ_COSVC), "Concurrent outer svc procedure" }, 126*0Sstevel@tonic-gate { SF(SQ_COOC), "Concurrent outer open/close" }, 127*0Sstevel@tonic-gate { SF(SQ_COCB), "Concurrent outer callback" }, 128*0Sstevel@tonic-gate { SF(0), NULL } 129*0Sstevel@tonic-gate }; 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate /* 132*0Sstevel@tonic-gate * Stdata flags 133*0Sstevel@tonic-gate */ 134*0Sstevel@tonic-gate static const struct str_flags stdf[] = { 135*0Sstevel@tonic-gate { SF(IOCWAIT), "someone is doing an ioctl" }, 136*0Sstevel@tonic-gate { SF(RSLEEP), "someone wants to read/recv msg" }, 137*0Sstevel@tonic-gate { SF(WSLEEP), "someone wants to write" }, 138*0Sstevel@tonic-gate { SF(STRPRI), "an M_PCPROTO is at stream head" }, 139*0Sstevel@tonic-gate { SF(STRHUP), "device has vanished" }, 140*0Sstevel@tonic-gate { SF(STWOPEN), "waiting for 1st open" }, 141*0Sstevel@tonic-gate { SF(STPLEX), "stream is being multiplexed" }, 142*0Sstevel@tonic-gate { SF(STRISTTY), "stream is a terminal" }, 143*0Sstevel@tonic-gate { SF(STRGETINPROG), "(k)strgetmsg is running" }, 144*0Sstevel@tonic-gate { SF(IOCWAITNE), "STR_NOERROR ioctl running" }, 145*0Sstevel@tonic-gate { SF(STRDERR), "fatal read error from M_ERROR" }, 146*0Sstevel@tonic-gate { SF(STWRERR), "fatal write error from M_ERROR" }, 147*0Sstevel@tonic-gate { SF(STRDERRNONPERSIST), "nonpersistent read errors" }, 148*0Sstevel@tonic-gate { SF(STWRERRNONPERSIST), "nonpersistent write errors" }, 149*0Sstevel@tonic-gate { SF(STRCLOSE), "wait for a close to complete" }, 150*0Sstevel@tonic-gate { SF(SNDMREAD), "used for read notification" }, 151*0Sstevel@tonic-gate { SF(OLDNDELAY), "use old NDELAY TTY semantics" }, 152*0Sstevel@tonic-gate { SF(0x00020000), "unused" }, 153*0Sstevel@tonic-gate { SF(0x00040000), "unused" }, 154*0Sstevel@tonic-gate { SF(STRTOSTOP), "block background writes" }, 155*0Sstevel@tonic-gate { SF(0x00100000), "unused" }, 156*0Sstevel@tonic-gate { SF(0x00200000), "unused" }, 157*0Sstevel@tonic-gate { SF(STRMOUNT), "stream is mounted" }, 158*0Sstevel@tonic-gate { SF(STRNOTATMARK), "Not at mark (when empty read q)" }, 159*0Sstevel@tonic-gate { SF(STRDELIM), "generate delimited messages" }, 160*0Sstevel@tonic-gate { SF(STRATMARK), "at mark (due to MSGMARKNEXT)" }, 161*0Sstevel@tonic-gate { SF(STZCNOTIFY), "wait for zerocopy mblk to be acked" }, 162*0Sstevel@tonic-gate { SF(STRPLUMB), "stream plumbing changes in progress" }, 163*0Sstevel@tonic-gate { SF(STREOF), "End-of-file indication" }, 164*0Sstevel@tonic-gate { SF(STREOPENFAIL), "re-open has failed" }, 165*0Sstevel@tonic-gate { SF(STRMATE), "this stream is a mate" }, 166*0Sstevel@tonic-gate { SF(STRHASLINKS), "there are I_LINKs under this stream" }, 167*0Sstevel@tonic-gate { SF(0), NULL } 168*0Sstevel@tonic-gate }; 169*0Sstevel@tonic-gate 170*0Sstevel@tonic-gate static const struct str_flags mbf[] = { 171*0Sstevel@tonic-gate { SF(MSGMARK), "last byte of message is marked" }, 172*0Sstevel@tonic-gate { SF(MSGNOLOOP), "don't loop message to write side" }, 173*0Sstevel@tonic-gate { SF(MSGDELIM), "message is delimited" }, 174*0Sstevel@tonic-gate { SF(0x08), "unused" }, 175*0Sstevel@tonic-gate { SF(MSGMARKNEXT), "Private: b_next's first byte marked" }, 176*0Sstevel@tonic-gate { SF(MSGNOTMARKNEXT), "Private: ... not marked" }, 177*0Sstevel@tonic-gate { SF(MSGHASREF), "Private: msg has reference to owner" }, 178*0Sstevel@tonic-gate { SF(0), NULL } 179*0Sstevel@tonic-gate }; 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate #define M_DATA_T 0xff 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate static const strtypes_t mbt[] = { 184*0Sstevel@tonic-gate { "M_DATA", M_DATA_T, "regular data" }, 185*0Sstevel@tonic-gate { "M_PROTO", M_PROTO, "protocol control" }, 186*0Sstevel@tonic-gate { "M_MULTIDATA", M_MULTIDATA, "multidata" }, 187*0Sstevel@tonic-gate { "M_BREAK", M_BREAK, "line break" }, 188*0Sstevel@tonic-gate { "M_PASSFP", M_PASSFP, "pass file pointer" }, 189*0Sstevel@tonic-gate { "M_EVENT", M_EVENT, "Obsoleted: do not use" }, 190*0Sstevel@tonic-gate { "M_SIG", M_SIG, "generate process signal" }, 191*0Sstevel@tonic-gate { "M_DELAY", M_DELAY, "real-time xmit delay" }, 192*0Sstevel@tonic-gate { "M_CTL", M_CTL, "device-specific control message" }, 193*0Sstevel@tonic-gate { "M_IOCTL", M_IOCTL, "ioctl; set/get params" }, 194*0Sstevel@tonic-gate { "M_SETOPTS", M_SETOPTS, "set stream head options" }, 195*0Sstevel@tonic-gate { "M_RSE", M_RSE, "reserved for RSE use only" }, 196*0Sstevel@tonic-gate { "M_IOCACK", M_IOCACK, "acknowledge ioctl" }, 197*0Sstevel@tonic-gate { "M_IOCNAK", M_IOCNAK, "negative ioctl acknowledge" }, 198*0Sstevel@tonic-gate { "M_PCPROTO", M_PCPROTO, "priority proto message" }, 199*0Sstevel@tonic-gate { "M_PCSIG", M_PCSIG, "generate process signal" }, 200*0Sstevel@tonic-gate { "M_READ", M_READ, "generate read notification" }, 201*0Sstevel@tonic-gate { "M_FLUSH", M_FLUSH, "flush your queues" }, 202*0Sstevel@tonic-gate { "M_STOP", M_STOP, "stop transmission immediately" }, 203*0Sstevel@tonic-gate { "M_START", M_START, "restart transmission after stop" }, 204*0Sstevel@tonic-gate { "M_HANGUP", M_HANGUP, "line disconnect" }, 205*0Sstevel@tonic-gate { "M_ERROR", M_ERROR, "send error to stream head" }, 206*0Sstevel@tonic-gate { "M_COPYIN", M_COPYIN, "request to copyin data" }, 207*0Sstevel@tonic-gate { "M_COPYOUT", M_COPYOUT, "request to copyout data" }, 208*0Sstevel@tonic-gate { "M_IOCDATA", M_IOCDATA, "response to M_COPYIN and M_COPYOUT" }, 209*0Sstevel@tonic-gate { "M_PCRSE", M_PCRSE, "reserved for RSE use only" }, 210*0Sstevel@tonic-gate { "M_STOPI", M_STOPI, "stop reception immediately" }, 211*0Sstevel@tonic-gate { "M_STARTI", M_STARTI, "restart reception after stop" }, 212*0Sstevel@tonic-gate { "M_PCEVENT", M_PCEVENT, "Obsoleted: do not use" }, 213*0Sstevel@tonic-gate { "M_UNHANGUP", M_UNHANGUP, "line reconnect" }, 214*0Sstevel@tonic-gate }; 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate /* Allocation flow trace events, starting from 0 */ 217*0Sstevel@tonic-gate static const char *ftev_alloc[] = { 218*0Sstevel@tonic-gate /* 0 */ ":allocb", 219*0Sstevel@tonic-gate /* 1 */ ":esballoc", 220*0Sstevel@tonic-gate /* 2 */ ":desballoc", 221*0Sstevel@tonic-gate /* 3 */ ":esballoca", 222*0Sstevel@tonic-gate /* 4 */ ":desballoca", 223*0Sstevel@tonic-gate /* 5 */ ":allocbig", 224*0Sstevel@tonic-gate /* 6 */ ":allocbw", 225*0Sstevel@tonic-gate /* 7 */ ":bcallocb", 226*0Sstevel@tonic-gate /* 8 */ ":freeb", 227*0Sstevel@tonic-gate /* 9 */ ":dupb", 228*0Sstevel@tonic-gate /* A */ ":copyb", 229*0Sstevel@tonic-gate }; 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate #define FTEV_PROC_START FTEV_PUT 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gate /* Procedures recorded by flow tracing, starting from 0x100 */ 234*0Sstevel@tonic-gate static const char *ftev_proc[] = { 235*0Sstevel@tonic-gate /* 100 */ ":put", 236*0Sstevel@tonic-gate /* 101 */ ":undefined (0x101)", 237*0Sstevel@tonic-gate /* 102 */ ":undefined (0x102)", 238*0Sstevel@tonic-gate /* 103 */ ":undefined (0x103)", 239*0Sstevel@tonic-gate /* 104 */ ":undefined (0x104)", 240*0Sstevel@tonic-gate /* 105 */ ":putq", 241*0Sstevel@tonic-gate /* 106 */ ":getq", 242*0Sstevel@tonic-gate /* 107 */ ":rmvq", 243*0Sstevel@tonic-gate /* 108 */ ":insq", 244*0Sstevel@tonic-gate /* 109 */ ":putbq", 245*0Sstevel@tonic-gate /* 10A */ ":flushq", 246*0Sstevel@tonic-gate /* 10B */ ":undefined (0x10b)", 247*0Sstevel@tonic-gate /* 10C */ ":undefined (0x10c)", 248*0Sstevel@tonic-gate /* 10D */ ":putnext", 249*0Sstevel@tonic-gate /* 10E */ ":rwnext", 250*0Sstevel@tonic-gate }; 251*0Sstevel@tonic-gate 252*0Sstevel@tonic-gate static const char *db_control_types[] = { 253*0Sstevel@tonic-gate /* 00 */ "data", 254*0Sstevel@tonic-gate /* 01 */ "proto", 255*0Sstevel@tonic-gate /* 02 */ "multidata", 256*0Sstevel@tonic-gate /* 03 */ "unused (0x03)", 257*0Sstevel@tonic-gate /* 04 */ "unused (0x04)", 258*0Sstevel@tonic-gate /* 05 */ "unused (0x05)", 259*0Sstevel@tonic-gate /* 06 */ "unused (0x06)", 260*0Sstevel@tonic-gate /* 07 */ "unused (0x07)", 261*0Sstevel@tonic-gate /* 08 */ "break", 262*0Sstevel@tonic-gate /* 09 */ "passfp", 263*0Sstevel@tonic-gate /* 0a */ "event", 264*0Sstevel@tonic-gate /* 0b */ "sig", 265*0Sstevel@tonic-gate /* 0c */ "delay", 266*0Sstevel@tonic-gate /* 0d */ "ctl", 267*0Sstevel@tonic-gate /* 0e */ "ioctl", 268*0Sstevel@tonic-gate /* 0f */ "unused", 269*0Sstevel@tonic-gate /* 10 */ "setopts", 270*0Sstevel@tonic-gate /* 11 */ "rse", 271*0Sstevel@tonic-gate }; 272*0Sstevel@tonic-gate 273*0Sstevel@tonic-gate static const char *db_control_hipri_types[] = { 274*0Sstevel@tonic-gate /* 81 */ "iocack", 275*0Sstevel@tonic-gate /* 82 */ "iocnak", 276*0Sstevel@tonic-gate /* 83 */ "pcproto", 277*0Sstevel@tonic-gate /* 84 */ "pcsig", 278*0Sstevel@tonic-gate /* 85 */ "read", 279*0Sstevel@tonic-gate /* 86 */ "flush", 280*0Sstevel@tonic-gate /* 87 */ "stop", 281*0Sstevel@tonic-gate /* 88 */ "start", 282*0Sstevel@tonic-gate /* 89 */ "hangup", 283*0Sstevel@tonic-gate /* 8a */ "error", 284*0Sstevel@tonic-gate /* 8b */ "copyin", 285*0Sstevel@tonic-gate /* 8c */ "copyout", 286*0Sstevel@tonic-gate /* 8d */ "iocdata", 287*0Sstevel@tonic-gate /* 8e */ "pcrse", 288*0Sstevel@tonic-gate /* 8f */ "stopi", 289*0Sstevel@tonic-gate /* 90 */ "starti", 290*0Sstevel@tonic-gate /* 91 */ "pcevent", 291*0Sstevel@tonic-gate /* 92 */ "unhangup", 292*0Sstevel@tonic-gate }; 293*0Sstevel@tonic-gate 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate #define A_SIZE(a) (sizeof (a) / sizeof (a[0])) 296*0Sstevel@tonic-gate 297*0Sstevel@tonic-gate static void ft_printevent(ushort_t); 298*0Sstevel@tonic-gate 299*0Sstevel@tonic-gate static int 300*0Sstevel@tonic-gate streams_parse_flag(const strflags_t ftable[], const char *arg, uint32_t *flag) 301*0Sstevel@tonic-gate { 302*0Sstevel@tonic-gate int i; 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gate for (i = 0; ftable[i].strf_name != NULL; i++) { 305*0Sstevel@tonic-gate if (strcasecmp(arg, ftable[i].strf_name) == 0) { 306*0Sstevel@tonic-gate *flag |= (1 << i); 307*0Sstevel@tonic-gate return (0); 308*0Sstevel@tonic-gate } 309*0Sstevel@tonic-gate } 310*0Sstevel@tonic-gate 311*0Sstevel@tonic-gate return (-1); 312*0Sstevel@tonic-gate } 313*0Sstevel@tonic-gate 314*0Sstevel@tonic-gate static void 315*0Sstevel@tonic-gate streams_flag_usage(const strflags_t ftable[]) 316*0Sstevel@tonic-gate { 317*0Sstevel@tonic-gate int i; 318*0Sstevel@tonic-gate 319*0Sstevel@tonic-gate for (i = 0; ftable[i].strf_name != NULL; i++) 320*0Sstevel@tonic-gate mdb_printf("%-14s %s\n", 321*0Sstevel@tonic-gate ftable[i].strf_name, ftable[i].strf_descr); 322*0Sstevel@tonic-gate } 323*0Sstevel@tonic-gate 324*0Sstevel@tonic-gate static int 325*0Sstevel@tonic-gate streams_parse_type(const strtypes_t ftable[], const char *arg, uint32_t *flag) 326*0Sstevel@tonic-gate { 327*0Sstevel@tonic-gate int i; 328*0Sstevel@tonic-gate 329*0Sstevel@tonic-gate for (i = 0; ftable[i].strt_name != NULL; i++) { 330*0Sstevel@tonic-gate if (strcasecmp(arg, ftable[i].strt_name) == 0) { 331*0Sstevel@tonic-gate *flag = ftable[i].strt_value; 332*0Sstevel@tonic-gate return (0); 333*0Sstevel@tonic-gate } 334*0Sstevel@tonic-gate } 335*0Sstevel@tonic-gate 336*0Sstevel@tonic-gate return (-1); 337*0Sstevel@tonic-gate } 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate static void 340*0Sstevel@tonic-gate streams_type_usage(const strtypes_t ftable[]) 341*0Sstevel@tonic-gate { 342*0Sstevel@tonic-gate int i; 343*0Sstevel@tonic-gate 344*0Sstevel@tonic-gate for (i = 0; ftable[i].strt_name != NULL; i++) 345*0Sstevel@tonic-gate mdb_printf("%-12s %s\n", 346*0Sstevel@tonic-gate ftable[i].strt_name, ftable[i].strt_descr); 347*0Sstevel@tonic-gate } 348*0Sstevel@tonic-gate 349*0Sstevel@tonic-gate int 350*0Sstevel@tonic-gate queue(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 351*0Sstevel@tonic-gate { 352*0Sstevel@tonic-gate const int QUEUE_FLGDELT = (int)(sizeof (uintptr_t) * 2 + 15); 353*0Sstevel@tonic-gate 354*0Sstevel@tonic-gate char name[MODMAXNAMELEN]; 355*0Sstevel@tonic-gate int nblks = 0; 356*0Sstevel@tonic-gate uintptr_t maddr; 357*0Sstevel@tonic-gate mblk_t mblk; 358*0Sstevel@tonic-gate queue_t q; 359*0Sstevel@tonic-gate 360*0Sstevel@tonic-gate const char *mod = NULL, *flag = NULL, *not_flag = NULL; 361*0Sstevel@tonic-gate uint_t quiet = FALSE; 362*0Sstevel@tonic-gate uint_t verbose = FALSE; 363*0Sstevel@tonic-gate uint32_t mask = 0, not_mask = 0; 364*0Sstevel@tonic-gate uintptr_t syncq = 0; 365*0Sstevel@tonic-gate 366*0Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 367*0Sstevel@tonic-gate if (mdb_walk_dcmd("genunix`queue_cache", "genunix`queue", 368*0Sstevel@tonic-gate argc, argv) == -1) { 369*0Sstevel@tonic-gate mdb_warn("failed to walk queue cache"); 370*0Sstevel@tonic-gate return (DCMD_ERR); 371*0Sstevel@tonic-gate } 372*0Sstevel@tonic-gate return (DCMD_OK); 373*0Sstevel@tonic-gate } 374*0Sstevel@tonic-gate 375*0Sstevel@tonic-gate if (flags & DCMD_PIPE_OUT) 376*0Sstevel@tonic-gate quiet = TRUE; 377*0Sstevel@tonic-gate 378*0Sstevel@tonic-gate if (mdb_getopts(argc, argv, 379*0Sstevel@tonic-gate 'v', MDB_OPT_SETBITS, TRUE, &verbose, 380*0Sstevel@tonic-gate 'q', MDB_OPT_SETBITS, TRUE, &quiet, 381*0Sstevel@tonic-gate 'm', MDB_OPT_STR, &mod, 382*0Sstevel@tonic-gate 'f', MDB_OPT_STR, &flag, 383*0Sstevel@tonic-gate 'F', MDB_OPT_STR, ¬_flag, 384*0Sstevel@tonic-gate 's', MDB_OPT_UINTPTR, &syncq, 385*0Sstevel@tonic-gate NULL) != argc) 386*0Sstevel@tonic-gate return (DCMD_USAGE); 387*0Sstevel@tonic-gate 388*0Sstevel@tonic-gate /* 389*0Sstevel@tonic-gate * If any of the filtering flags is specified, don't print anything 390*0Sstevel@tonic-gate * except the matching pointer. 391*0Sstevel@tonic-gate */ 392*0Sstevel@tonic-gate if (flag != NULL || not_flag != NULL || mod != NULL || syncq != NULL) 393*0Sstevel@tonic-gate quiet = TRUE; 394*0Sstevel@tonic-gate 395*0Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && !quiet) { 396*0Sstevel@tonic-gate mdb_printf("%?s %-13s %6s %4s\n", 397*0Sstevel@tonic-gate "ADDR", "MODULE", "FLAGS", "NBLK"); 398*0Sstevel@tonic-gate } 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gate if (flag != NULL && streams_parse_flag(qf, flag, &mask) == -1) { 401*0Sstevel@tonic-gate mdb_warn("unrecognized queue flag '%s'\n", flag); 402*0Sstevel@tonic-gate streams_flag_usage(qf); 403*0Sstevel@tonic-gate return (DCMD_USAGE); 404*0Sstevel@tonic-gate } 405*0Sstevel@tonic-gate 406*0Sstevel@tonic-gate if (not_flag != NULL && 407*0Sstevel@tonic-gate streams_parse_flag(qf, not_flag, ¬_mask) == -1) { 408*0Sstevel@tonic-gate mdb_warn("unrecognized queue flag '%s'\n", flag); 409*0Sstevel@tonic-gate streams_flag_usage(qf); 410*0Sstevel@tonic-gate return (DCMD_USAGE); 411*0Sstevel@tonic-gate } 412*0Sstevel@tonic-gate 413*0Sstevel@tonic-gate if (mdb_vread(&q, sizeof (q), addr) == -1) { 414*0Sstevel@tonic-gate mdb_warn("couldn't read queue at %p", addr); 415*0Sstevel@tonic-gate return (DCMD_ERR); 416*0Sstevel@tonic-gate } 417*0Sstevel@tonic-gate 418*0Sstevel@tonic-gate for (maddr = (uintptr_t)q.q_first; maddr != NULL; nblks++) { 419*0Sstevel@tonic-gate if (mdb_vread(&mblk, sizeof (mblk), maddr) == -1) { 420*0Sstevel@tonic-gate mdb_warn("couldn't read mblk %p for queue %p", 421*0Sstevel@tonic-gate maddr, addr); 422*0Sstevel@tonic-gate break; 423*0Sstevel@tonic-gate } 424*0Sstevel@tonic-gate maddr = (uintptr_t)mblk.b_next; 425*0Sstevel@tonic-gate } 426*0Sstevel@tonic-gate 427*0Sstevel@tonic-gate (void) mdb_qname(&q, name, sizeof (name)); 428*0Sstevel@tonic-gate 429*0Sstevel@tonic-gate /* 430*0Sstevel@tonic-gate * If queue doesn't pass filtering criteria, don't print anything and 431*0Sstevel@tonic-gate * just return. 432*0Sstevel@tonic-gate */ 433*0Sstevel@tonic-gate 434*0Sstevel@tonic-gate if (mod != NULL && strcmp(mod, name) != 0) 435*0Sstevel@tonic-gate return (DCMD_OK); 436*0Sstevel@tonic-gate 437*0Sstevel@tonic-gate if (mask != 0 && !(q.q_flag & mask)) 438*0Sstevel@tonic-gate return (DCMD_OK); 439*0Sstevel@tonic-gate 440*0Sstevel@tonic-gate if (not_mask != 0 && (q.q_flag & not_mask)) 441*0Sstevel@tonic-gate return (DCMD_OK); 442*0Sstevel@tonic-gate 443*0Sstevel@tonic-gate if (syncq != 0 && q.q_syncq != (syncq_t *)syncq) 444*0Sstevel@tonic-gate return (DCMD_OK); 445*0Sstevel@tonic-gate 446*0Sstevel@tonic-gate /* 447*0Sstevel@tonic-gate * Options are specified for filtering, so If any option is specified on 448*0Sstevel@tonic-gate * the command line, just print address and exit. 449*0Sstevel@tonic-gate */ 450*0Sstevel@tonic-gate if (quiet) { 451*0Sstevel@tonic-gate mdb_printf("%0?p\n", addr); 452*0Sstevel@tonic-gate return (DCMD_OK); 453*0Sstevel@tonic-gate } 454*0Sstevel@tonic-gate 455*0Sstevel@tonic-gate mdb_printf("%0?p %-13s %06x %4d %0?p\n", 456*0Sstevel@tonic-gate addr, name, q.q_flag, nblks, q.q_first); 457*0Sstevel@tonic-gate 458*0Sstevel@tonic-gate if (verbose) { 459*0Sstevel@tonic-gate int i, arm = 0; 460*0Sstevel@tonic-gate 461*0Sstevel@tonic-gate for (i = 0; qf[i].strf_name != NULL; i++) { 462*0Sstevel@tonic-gate if (!(q.q_flag & (1 << i))) 463*0Sstevel@tonic-gate continue; 464*0Sstevel@tonic-gate if (!arm) { 465*0Sstevel@tonic-gate mdb_printf("%*s|\n%*s+--> ", 466*0Sstevel@tonic-gate QUEUE_FLGDELT, "", QUEUE_FLGDELT, ""); 467*0Sstevel@tonic-gate arm = 1; 468*0Sstevel@tonic-gate } else 469*0Sstevel@tonic-gate mdb_printf("%*s ", QUEUE_FLGDELT, ""); 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate mdb_printf("%-12s %s\n", 472*0Sstevel@tonic-gate qf[i].strf_name, qf[i].strf_descr); 473*0Sstevel@tonic-gate } 474*0Sstevel@tonic-gate } 475*0Sstevel@tonic-gate 476*0Sstevel@tonic-gate return (DCMD_OK); 477*0Sstevel@tonic-gate } 478*0Sstevel@tonic-gate 479*0Sstevel@tonic-gate int 480*0Sstevel@tonic-gate syncq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 481*0Sstevel@tonic-gate { 482*0Sstevel@tonic-gate const int SYNC_FLGDELT = (int)(sizeof (uintptr_t) * 2 + 1); 483*0Sstevel@tonic-gate const int SYNC_TYPDELT = (int)(sizeof (uintptr_t) * 2 + 5); 484*0Sstevel@tonic-gate syncq_t sq; 485*0Sstevel@tonic-gate 486*0Sstevel@tonic-gate const char *flag = NULL, *not_flag = NULL; 487*0Sstevel@tonic-gate const char *typ = NULL, *not_typ = NULL; 488*0Sstevel@tonic-gate uint_t verbose = FALSE; 489*0Sstevel@tonic-gate uint_t quiet = FALSE; 490*0Sstevel@tonic-gate uint32_t mask = 0, not_mask = 0; 491*0Sstevel@tonic-gate uint32_t tmask = 0, not_tmask = 0; 492*0Sstevel@tonic-gate uint8_t sqtype = 0; 493*0Sstevel@tonic-gate 494*0Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 495*0Sstevel@tonic-gate if (mdb_walk_dcmd("genunix`syncq_cache", "genunix`syncq", 496*0Sstevel@tonic-gate argc, argv) == -1) { 497*0Sstevel@tonic-gate mdb_warn("failed to walk syncq cache"); 498*0Sstevel@tonic-gate return (DCMD_ERR); 499*0Sstevel@tonic-gate } 500*0Sstevel@tonic-gate return (DCMD_OK); 501*0Sstevel@tonic-gate } 502*0Sstevel@tonic-gate 503*0Sstevel@tonic-gate if (flags & DCMD_PIPE_OUT) 504*0Sstevel@tonic-gate quiet = TRUE; 505*0Sstevel@tonic-gate 506*0Sstevel@tonic-gate if (mdb_getopts(argc, argv, 507*0Sstevel@tonic-gate 'v', MDB_OPT_SETBITS, TRUE, &verbose, 508*0Sstevel@tonic-gate 'q', MDB_OPT_SETBITS, TRUE, &quiet, 509*0Sstevel@tonic-gate 'f', MDB_OPT_STR, &flag, 510*0Sstevel@tonic-gate 'F', MDB_OPT_STR, ¬_flag, 511*0Sstevel@tonic-gate 't', MDB_OPT_STR, &typ, 512*0Sstevel@tonic-gate 'T', MDB_OPT_STR, ¬_typ, 513*0Sstevel@tonic-gate NULL) != argc) 514*0Sstevel@tonic-gate return (DCMD_USAGE); 515*0Sstevel@tonic-gate 516*0Sstevel@tonic-gate /* 517*0Sstevel@tonic-gate * If any of the filtering flags is specified, don't print anything 518*0Sstevel@tonic-gate * except the matching pointer. 519*0Sstevel@tonic-gate */ 520*0Sstevel@tonic-gate if (flag != NULL || not_flag != NULL || typ != NULL || not_typ != NULL) 521*0Sstevel@tonic-gate quiet = TRUE; 522*0Sstevel@tonic-gate 523*0Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && !quiet) { 524*0Sstevel@tonic-gate mdb_printf("%?s %s %s %s %s %?s %s %s\n", 525*0Sstevel@tonic-gate "ADDR", "FLG", "TYP", "CNT", "NQS", "OUTER", "SF", "PRI"); 526*0Sstevel@tonic-gate } 527*0Sstevel@tonic-gate 528*0Sstevel@tonic-gate if (flag != NULL && streams_parse_flag(sqf, flag, &mask) == -1) { 529*0Sstevel@tonic-gate mdb_warn("unrecognized syncq flag '%s'\n", flag); 530*0Sstevel@tonic-gate streams_flag_usage(sqf); 531*0Sstevel@tonic-gate return (DCMD_USAGE); 532*0Sstevel@tonic-gate } 533*0Sstevel@tonic-gate 534*0Sstevel@tonic-gate if (typ != NULL && streams_parse_flag(sqt, typ, &tmask) == -1) { 535*0Sstevel@tonic-gate mdb_warn("unrecognized syncq type '%s'\n", typ); 536*0Sstevel@tonic-gate streams_flag_usage(sqt); 537*0Sstevel@tonic-gate return (DCMD_USAGE); 538*0Sstevel@tonic-gate } 539*0Sstevel@tonic-gate 540*0Sstevel@tonic-gate if (not_flag != NULL && streams_parse_flag(sqf, not_flag, ¬_mask) 541*0Sstevel@tonic-gate == -1) { 542*0Sstevel@tonic-gate mdb_warn("unrecognized syncq flag '%s'\n", not_flag); 543*0Sstevel@tonic-gate streams_flag_usage(sqf); 544*0Sstevel@tonic-gate return (DCMD_USAGE); 545*0Sstevel@tonic-gate } 546*0Sstevel@tonic-gate 547*0Sstevel@tonic-gate if (not_typ != NULL && streams_parse_flag(sqt, not_typ, ¬_tmask) 548*0Sstevel@tonic-gate == -1) { 549*0Sstevel@tonic-gate mdb_warn("unrecognized syncq type '%s'\n", not_typ); 550*0Sstevel@tonic-gate streams_flag_usage(sqt); 551*0Sstevel@tonic-gate return (DCMD_USAGE); 552*0Sstevel@tonic-gate } 553*0Sstevel@tonic-gate 554*0Sstevel@tonic-gate if (mdb_vread(&sq, sizeof (sq), addr) == -1) { 555*0Sstevel@tonic-gate mdb_warn("couldn't read syncq at %p", addr); 556*0Sstevel@tonic-gate return (DCMD_ERR); 557*0Sstevel@tonic-gate } 558*0Sstevel@tonic-gate 559*0Sstevel@tonic-gate if (mask != 0 && !(sq.sq_flags & mask)) 560*0Sstevel@tonic-gate return (DCMD_OK); 561*0Sstevel@tonic-gate 562*0Sstevel@tonic-gate if (not_mask != 0 && (sq.sq_flags & not_mask)) 563*0Sstevel@tonic-gate return (DCMD_OK); 564*0Sstevel@tonic-gate 565*0Sstevel@tonic-gate sqtype = (sq.sq_type >> 8) & 0xff; 566*0Sstevel@tonic-gate 567*0Sstevel@tonic-gate if (tmask != 0 && !(sqtype & tmask)) 568*0Sstevel@tonic-gate return (DCMD_OK); 569*0Sstevel@tonic-gate 570*0Sstevel@tonic-gate if (not_tmask != 0 && (sqtype & not_tmask)) 571*0Sstevel@tonic-gate return (DCMD_OK); 572*0Sstevel@tonic-gate 573*0Sstevel@tonic-gate /* 574*0Sstevel@tonic-gate * Options are specified for filtering, so If any option is specified on 575*0Sstevel@tonic-gate * the command line, just print address and exit. 576*0Sstevel@tonic-gate */ 577*0Sstevel@tonic-gate if (quiet) { 578*0Sstevel@tonic-gate mdb_printf("%0?p\n", addr); 579*0Sstevel@tonic-gate return (DCMD_OK); 580*0Sstevel@tonic-gate } 581*0Sstevel@tonic-gate 582*0Sstevel@tonic-gate mdb_printf("%0?p %02x %02x %-3u %-3u %0?p %1x %-3d\n", 583*0Sstevel@tonic-gate addr, sq.sq_flags & 0xff, sqtype, sq.sq_count, 584*0Sstevel@tonic-gate sq.sq_nqueues, sq.sq_outer, sq.sq_svcflags, sq.sq_pri); 585*0Sstevel@tonic-gate 586*0Sstevel@tonic-gate if (verbose) { 587*0Sstevel@tonic-gate int i, arm = 0; 588*0Sstevel@tonic-gate 589*0Sstevel@tonic-gate for (i = 0; sqf[i].strf_name != NULL; i++) { 590*0Sstevel@tonic-gate if (!(sq.sq_flags & (1 << i))) 591*0Sstevel@tonic-gate continue; 592*0Sstevel@tonic-gate if (!arm) { 593*0Sstevel@tonic-gate mdb_printf("%*s|\n%*s+--> ", 594*0Sstevel@tonic-gate SYNC_FLGDELT, "", SYNC_FLGDELT, ""); 595*0Sstevel@tonic-gate arm = 1; 596*0Sstevel@tonic-gate } else 597*0Sstevel@tonic-gate mdb_printf("%*s ", SYNC_FLGDELT, ""); 598*0Sstevel@tonic-gate 599*0Sstevel@tonic-gate mdb_printf("%-12s %s\n", 600*0Sstevel@tonic-gate sqf[i].strf_name, sqf[i].strf_descr); 601*0Sstevel@tonic-gate } 602*0Sstevel@tonic-gate 603*0Sstevel@tonic-gate for (i = 0; sqt[i].strf_name != NULL; i++) { 604*0Sstevel@tonic-gate if (!(sqtype & (1 << i))) 605*0Sstevel@tonic-gate continue; 606*0Sstevel@tonic-gate if (!arm) { 607*0Sstevel@tonic-gate mdb_printf("%*s|\n%*s+--> ", 608*0Sstevel@tonic-gate SYNC_TYPDELT, "", SYNC_TYPDELT, ""); 609*0Sstevel@tonic-gate arm = 1; 610*0Sstevel@tonic-gate } else 611*0Sstevel@tonic-gate mdb_printf("%*s ", SYNC_TYPDELT, ""); 612*0Sstevel@tonic-gate 613*0Sstevel@tonic-gate mdb_printf("%-12s %s\n", 614*0Sstevel@tonic-gate sqt[i].strf_name, sqt[i].strf_descr); 615*0Sstevel@tonic-gate } 616*0Sstevel@tonic-gate } 617*0Sstevel@tonic-gate 618*0Sstevel@tonic-gate return (DCMD_OK); 619*0Sstevel@tonic-gate } 620*0Sstevel@tonic-gate 621*0Sstevel@tonic-gate int 622*0Sstevel@tonic-gate stdata(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 623*0Sstevel@tonic-gate { 624*0Sstevel@tonic-gate const int STREAM_FLGDELT = (int)(sizeof (uintptr_t) * 2 + 10); 625*0Sstevel@tonic-gate 626*0Sstevel@tonic-gate stdata_t sd; 627*0Sstevel@tonic-gate 628*0Sstevel@tonic-gate const char *flag = NULL, *not_flag = NULL; 629*0Sstevel@tonic-gate uint_t verbose = FALSE; 630*0Sstevel@tonic-gate uint_t quiet = FALSE; 631*0Sstevel@tonic-gate uint32_t mask = 0, not_mask = 0; 632*0Sstevel@tonic-gate 633*0Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 634*0Sstevel@tonic-gate if (mdb_walk_dcmd("genunix`stream_head_cache", 635*0Sstevel@tonic-gate "genunix`stdata", argc, argv) == -1) { 636*0Sstevel@tonic-gate mdb_warn("failed to walk stream head cache"); 637*0Sstevel@tonic-gate return (DCMD_ERR); 638*0Sstevel@tonic-gate } 639*0Sstevel@tonic-gate return (DCMD_OK); 640*0Sstevel@tonic-gate } 641*0Sstevel@tonic-gate 642*0Sstevel@tonic-gate if (flags & DCMD_PIPE_OUT) 643*0Sstevel@tonic-gate quiet = TRUE; 644*0Sstevel@tonic-gate 645*0Sstevel@tonic-gate if (mdb_getopts(argc, argv, 646*0Sstevel@tonic-gate 'v', MDB_OPT_SETBITS, TRUE, &verbose, 647*0Sstevel@tonic-gate 'q', MDB_OPT_SETBITS, TRUE, &quiet, 648*0Sstevel@tonic-gate 'f', MDB_OPT_STR, &flag, 649*0Sstevel@tonic-gate 'F', MDB_OPT_STR, ¬_flag, 650*0Sstevel@tonic-gate NULL) != argc) 651*0Sstevel@tonic-gate return (DCMD_USAGE); 652*0Sstevel@tonic-gate 653*0Sstevel@tonic-gate /* 654*0Sstevel@tonic-gate * If any of the filtering flags is specified, don't print anything 655*0Sstevel@tonic-gate * except the matching pointer. 656*0Sstevel@tonic-gate */ 657*0Sstevel@tonic-gate if (flag != NULL || not_flag != NULL) 658*0Sstevel@tonic-gate quiet = TRUE; 659*0Sstevel@tonic-gate 660*0Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && !quiet) { 661*0Sstevel@tonic-gate mdb_printf("%?s %?s %8s %?s %s %s\n", 662*0Sstevel@tonic-gate "ADDR", "WRQ", "FLAGS", "VNODE", "N/A", "REF"); 663*0Sstevel@tonic-gate } 664*0Sstevel@tonic-gate 665*0Sstevel@tonic-gate if (flag != NULL && streams_parse_flag(stdf, flag, &mask) == -1) { 666*0Sstevel@tonic-gate mdb_warn("unrecognized stream flag '%s'\n", flag); 667*0Sstevel@tonic-gate streams_flag_usage(stdf); 668*0Sstevel@tonic-gate return (DCMD_USAGE); 669*0Sstevel@tonic-gate } 670*0Sstevel@tonic-gate 671*0Sstevel@tonic-gate if (not_flag != NULL && 672*0Sstevel@tonic-gate streams_parse_flag(stdf, not_flag, ¬_mask) == -1) { 673*0Sstevel@tonic-gate mdb_warn("unrecognized stream flag '%s'\n", flag); 674*0Sstevel@tonic-gate streams_flag_usage(stdf); 675*0Sstevel@tonic-gate return (DCMD_USAGE); 676*0Sstevel@tonic-gate } 677*0Sstevel@tonic-gate 678*0Sstevel@tonic-gate if (mdb_vread(&sd, sizeof (sd), addr) == -1) { 679*0Sstevel@tonic-gate mdb_warn("couldn't read stdata at %p", addr); 680*0Sstevel@tonic-gate return (DCMD_ERR); 681*0Sstevel@tonic-gate } 682*0Sstevel@tonic-gate 683*0Sstevel@tonic-gate /* 684*0Sstevel@tonic-gate * If stream doesn't pass filtering criteria, don't print anything and 685*0Sstevel@tonic-gate * just return. 686*0Sstevel@tonic-gate */ 687*0Sstevel@tonic-gate 688*0Sstevel@tonic-gate if (mask != 0 && !(sd.sd_flag & mask)) 689*0Sstevel@tonic-gate return (DCMD_OK); 690*0Sstevel@tonic-gate 691*0Sstevel@tonic-gate if (not_mask != 0 && (sd.sd_flag & not_mask)) 692*0Sstevel@tonic-gate return (DCMD_OK); 693*0Sstevel@tonic-gate 694*0Sstevel@tonic-gate /* 695*0Sstevel@tonic-gate * Options are specified for filtering, so If any option is specified on 696*0Sstevel@tonic-gate * the command line, just print address and exit. 697*0Sstevel@tonic-gate */ 698*0Sstevel@tonic-gate if (quiet) { 699*0Sstevel@tonic-gate mdb_printf("%0?p\n", addr); 700*0Sstevel@tonic-gate return (DCMD_OK); 701*0Sstevel@tonic-gate } 702*0Sstevel@tonic-gate 703*0Sstevel@tonic-gate mdb_printf("%0?p %0?p %08x %0?p %d/%d %d\n", 704*0Sstevel@tonic-gate addr, sd.sd_wrq, sd.sd_flag, sd.sd_vnode, 705*0Sstevel@tonic-gate sd.sd_pushcnt, sd.sd_anchor, sd.sd_refcnt); 706*0Sstevel@tonic-gate 707*0Sstevel@tonic-gate if (verbose) { 708*0Sstevel@tonic-gate int i, arm = 0; 709*0Sstevel@tonic-gate 710*0Sstevel@tonic-gate for (i = 0; stdf[i].strf_name != NULL; i++) { 711*0Sstevel@tonic-gate if (!(sd.sd_flag & (1 << i))) 712*0Sstevel@tonic-gate continue; 713*0Sstevel@tonic-gate if (!arm) { 714*0Sstevel@tonic-gate mdb_printf("%*s|\n%*s+--> ", 715*0Sstevel@tonic-gate STREAM_FLGDELT, "", STREAM_FLGDELT, ""); 716*0Sstevel@tonic-gate arm = 1; 717*0Sstevel@tonic-gate } else 718*0Sstevel@tonic-gate mdb_printf("%*s ", STREAM_FLGDELT, ""); 719*0Sstevel@tonic-gate 720*0Sstevel@tonic-gate mdb_printf("%-12s %s\n", 721*0Sstevel@tonic-gate stdf[i].strf_name, stdf[i].strf_descr); 722*0Sstevel@tonic-gate } 723*0Sstevel@tonic-gate } 724*0Sstevel@tonic-gate 725*0Sstevel@tonic-gate return (DCMD_OK); 726*0Sstevel@tonic-gate } 727*0Sstevel@tonic-gate 728*0Sstevel@tonic-gate /*ARGSUSED*/ 729*0Sstevel@tonic-gate static void 730*0Sstevel@tonic-gate qprint_syncq(queue_t *addr, queue_t *q) 731*0Sstevel@tonic-gate { 732*0Sstevel@tonic-gate mdb_printf("%p\n", q->q_syncq); 733*0Sstevel@tonic-gate } 734*0Sstevel@tonic-gate 735*0Sstevel@tonic-gate /*ARGSUSED*/ 736*0Sstevel@tonic-gate static void 737*0Sstevel@tonic-gate qprint_stream(queue_t *addr, queue_t *q) 738*0Sstevel@tonic-gate { 739*0Sstevel@tonic-gate mdb_printf("%p\n", q->q_stream); 740*0Sstevel@tonic-gate } 741*0Sstevel@tonic-gate 742*0Sstevel@tonic-gate static void 743*0Sstevel@tonic-gate qprint_wrq(queue_t *addr, queue_t *q) 744*0Sstevel@tonic-gate { 745*0Sstevel@tonic-gate mdb_printf("%p\n", ((q)->q_flag & QREADR? (addr)+1: (addr))); 746*0Sstevel@tonic-gate } 747*0Sstevel@tonic-gate 748*0Sstevel@tonic-gate static void 749*0Sstevel@tonic-gate qprint_rdq(queue_t *addr, queue_t *q) 750*0Sstevel@tonic-gate { 751*0Sstevel@tonic-gate mdb_printf("%p\n", ((q)->q_flag & QREADR? (addr): (addr)-1)); 752*0Sstevel@tonic-gate } 753*0Sstevel@tonic-gate 754*0Sstevel@tonic-gate static void 755*0Sstevel@tonic-gate qprint_otherq(queue_t *addr, queue_t *q) 756*0Sstevel@tonic-gate { 757*0Sstevel@tonic-gate mdb_printf("%p\n", ((q)->q_flag & QREADR? (addr)+1: (addr)-1)); 758*0Sstevel@tonic-gate } 759*0Sstevel@tonic-gate 760*0Sstevel@tonic-gate static int 761*0Sstevel@tonic-gate q2x(uintptr_t addr, int argc, qprint_func prfunc) 762*0Sstevel@tonic-gate { 763*0Sstevel@tonic-gate queue_t q; 764*0Sstevel@tonic-gate 765*0Sstevel@tonic-gate if (argc != 0) 766*0Sstevel@tonic-gate return (DCMD_USAGE); 767*0Sstevel@tonic-gate 768*0Sstevel@tonic-gate if (mdb_vread(&q, sizeof (q), addr) == -1) { 769*0Sstevel@tonic-gate mdb_warn("couldn't read queue at %p", addr); 770*0Sstevel@tonic-gate return (DCMD_ERR); 771*0Sstevel@tonic-gate } 772*0Sstevel@tonic-gate 773*0Sstevel@tonic-gate prfunc((queue_t *)addr, &q); 774*0Sstevel@tonic-gate 775*0Sstevel@tonic-gate return (DCMD_OK); 776*0Sstevel@tonic-gate } 777*0Sstevel@tonic-gate 778*0Sstevel@tonic-gate 779*0Sstevel@tonic-gate /*ARGSUSED*/ 780*0Sstevel@tonic-gate int 781*0Sstevel@tonic-gate q2syncq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 782*0Sstevel@tonic-gate { 783*0Sstevel@tonic-gate return (q2x(addr, argc, qprint_syncq)); 784*0Sstevel@tonic-gate } 785*0Sstevel@tonic-gate 786*0Sstevel@tonic-gate /*ARGSUSED*/ 787*0Sstevel@tonic-gate int 788*0Sstevel@tonic-gate q2stream(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 789*0Sstevel@tonic-gate { 790*0Sstevel@tonic-gate return (q2x(addr, argc, qprint_stream)); 791*0Sstevel@tonic-gate } 792*0Sstevel@tonic-gate 793*0Sstevel@tonic-gate /*ARGSUSED*/ 794*0Sstevel@tonic-gate int 795*0Sstevel@tonic-gate q2rdq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 796*0Sstevel@tonic-gate { 797*0Sstevel@tonic-gate return (q2x(addr, argc, qprint_rdq)); 798*0Sstevel@tonic-gate } 799*0Sstevel@tonic-gate 800*0Sstevel@tonic-gate /*ARGSUSED*/ 801*0Sstevel@tonic-gate int 802*0Sstevel@tonic-gate q2wrq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 803*0Sstevel@tonic-gate { 804*0Sstevel@tonic-gate return (q2x(addr, argc, qprint_wrq)); 805*0Sstevel@tonic-gate } 806*0Sstevel@tonic-gate 807*0Sstevel@tonic-gate /*ARGSUSED*/ 808*0Sstevel@tonic-gate int 809*0Sstevel@tonic-gate q2otherq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 810*0Sstevel@tonic-gate { 811*0Sstevel@tonic-gate return (q2x(addr, argc, qprint_otherq)); 812*0Sstevel@tonic-gate } 813*0Sstevel@tonic-gate 814*0Sstevel@tonic-gate static int 815*0Sstevel@tonic-gate sd2x(uintptr_t addr, int argc, sdprint_func prfunc) 816*0Sstevel@tonic-gate { 817*0Sstevel@tonic-gate stdata_t sd; 818*0Sstevel@tonic-gate 819*0Sstevel@tonic-gate if (argc != 0) 820*0Sstevel@tonic-gate return (DCMD_USAGE); 821*0Sstevel@tonic-gate 822*0Sstevel@tonic-gate if (mdb_vread(&sd, sizeof (sd), addr) == -1) { 823*0Sstevel@tonic-gate mdb_warn("couldn't read stream head at %p", addr); 824*0Sstevel@tonic-gate return (DCMD_ERR); 825*0Sstevel@tonic-gate } 826*0Sstevel@tonic-gate 827*0Sstevel@tonic-gate prfunc((stdata_t *)addr, &sd); 828*0Sstevel@tonic-gate 829*0Sstevel@tonic-gate return (DCMD_OK); 830*0Sstevel@tonic-gate } 831*0Sstevel@tonic-gate 832*0Sstevel@tonic-gate /*ARGSUSED*/ 833*0Sstevel@tonic-gate static void 834*0Sstevel@tonic-gate sdprint_wrq(stdata_t *addr, stdata_t *sd) 835*0Sstevel@tonic-gate { 836*0Sstevel@tonic-gate mdb_printf("%p\n", sd->sd_wrq); 837*0Sstevel@tonic-gate } 838*0Sstevel@tonic-gate 839*0Sstevel@tonic-gate static void 840*0Sstevel@tonic-gate sdprint_mate(stdata_t *addr, stdata_t *sd) 841*0Sstevel@tonic-gate { 842*0Sstevel@tonic-gate mdb_printf("%p\n", sd->sd_mate ? sd->sd_mate : addr); 843*0Sstevel@tonic-gate } 844*0Sstevel@tonic-gate 845*0Sstevel@tonic-gate /*ARGSUSED*/ 846*0Sstevel@tonic-gate int 847*0Sstevel@tonic-gate str2mate(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 848*0Sstevel@tonic-gate { 849*0Sstevel@tonic-gate return (sd2x(addr, argc, sdprint_mate)); 850*0Sstevel@tonic-gate } 851*0Sstevel@tonic-gate 852*0Sstevel@tonic-gate /*ARGSUSED*/ 853*0Sstevel@tonic-gate int 854*0Sstevel@tonic-gate str2wrq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 855*0Sstevel@tonic-gate { 856*0Sstevel@tonic-gate return (sd2x(addr, argc, sdprint_wrq)); 857*0Sstevel@tonic-gate } 858*0Sstevel@tonic-gate 859*0Sstevel@tonic-gate 860*0Sstevel@tonic-gate /* 861*0Sstevel@tonic-gate * If this syncq is a part of the queue pair structure, find the queue for it. 862*0Sstevel@tonic-gate */ 863*0Sstevel@tonic-gate /*ARGSUSED*/ 864*0Sstevel@tonic-gate int 865*0Sstevel@tonic-gate syncq2q(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 866*0Sstevel@tonic-gate { 867*0Sstevel@tonic-gate syncq_t sq; 868*0Sstevel@tonic-gate queue_t q; 869*0Sstevel@tonic-gate queue_t *qp; 870*0Sstevel@tonic-gate 871*0Sstevel@tonic-gate if (argc != 0) 872*0Sstevel@tonic-gate return (DCMD_USAGE); 873*0Sstevel@tonic-gate 874*0Sstevel@tonic-gate if (mdb_vread(&sq, sizeof (sq), addr) == -1) { 875*0Sstevel@tonic-gate mdb_warn("couldn't read syncq at %p", addr); 876*0Sstevel@tonic-gate return (DCMD_ERR); 877*0Sstevel@tonic-gate } 878*0Sstevel@tonic-gate 879*0Sstevel@tonic-gate /* Try to find its queue */ 880*0Sstevel@tonic-gate qp = (queue_t *)addr - 2; 881*0Sstevel@tonic-gate 882*0Sstevel@tonic-gate if ((mdb_vread(&q, sizeof (q), (uintptr_t)qp) == -1) || 883*0Sstevel@tonic-gate (q.q_syncq != (syncq_t *)addr)) { 884*0Sstevel@tonic-gate mdb_warn("syncq2q: %p is not part of any queue\n", addr); 885*0Sstevel@tonic-gate return (DCMD_ERR); 886*0Sstevel@tonic-gate } else 887*0Sstevel@tonic-gate mdb_printf("%p\n", qp); 888*0Sstevel@tonic-gate 889*0Sstevel@tonic-gate return (DCMD_OK); 890*0Sstevel@tonic-gate } 891*0Sstevel@tonic-gate 892*0Sstevel@tonic-gate 893*0Sstevel@tonic-gate int 894*0Sstevel@tonic-gate queue_walk_init(mdb_walk_state_t *wsp) 895*0Sstevel@tonic-gate { 896*0Sstevel@tonic-gate if (wsp->walk_addr == NULL && 897*0Sstevel@tonic-gate mdb_readvar(&wsp->walk_addr, "qhead") == -1) { 898*0Sstevel@tonic-gate mdb_warn("failed to read 'qhead'"); 899*0Sstevel@tonic-gate return (WALK_ERR); 900*0Sstevel@tonic-gate } 901*0Sstevel@tonic-gate 902*0Sstevel@tonic-gate wsp->walk_data = mdb_alloc(sizeof (queue_t), UM_SLEEP); 903*0Sstevel@tonic-gate return (WALK_NEXT); 904*0Sstevel@tonic-gate } 905*0Sstevel@tonic-gate 906*0Sstevel@tonic-gate int 907*0Sstevel@tonic-gate queue_link_step(mdb_walk_state_t *wsp) 908*0Sstevel@tonic-gate { 909*0Sstevel@tonic-gate int status; 910*0Sstevel@tonic-gate 911*0Sstevel@tonic-gate if (wsp->walk_addr == NULL) 912*0Sstevel@tonic-gate return (WALK_DONE); 913*0Sstevel@tonic-gate 914*0Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (queue_t), wsp->walk_addr) == -1) { 915*0Sstevel@tonic-gate mdb_warn("failed to read queue at %p", wsp->walk_addr); 916*0Sstevel@tonic-gate return (WALK_DONE); 917*0Sstevel@tonic-gate } 918*0Sstevel@tonic-gate 919*0Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 920*0Sstevel@tonic-gate wsp->walk_cbdata); 921*0Sstevel@tonic-gate 922*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)(((queue_t *)wsp->walk_data)->q_link); 923*0Sstevel@tonic-gate return (status); 924*0Sstevel@tonic-gate } 925*0Sstevel@tonic-gate 926*0Sstevel@tonic-gate int 927*0Sstevel@tonic-gate queue_next_step(mdb_walk_state_t *wsp) 928*0Sstevel@tonic-gate { 929*0Sstevel@tonic-gate int status; 930*0Sstevel@tonic-gate 931*0Sstevel@tonic-gate if (wsp->walk_addr == NULL) 932*0Sstevel@tonic-gate return (WALK_DONE); 933*0Sstevel@tonic-gate 934*0Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (queue_t), wsp->walk_addr) == -1) { 935*0Sstevel@tonic-gate mdb_warn("failed to read queue at %p", wsp->walk_addr); 936*0Sstevel@tonic-gate return (WALK_DONE); 937*0Sstevel@tonic-gate } 938*0Sstevel@tonic-gate 939*0Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 940*0Sstevel@tonic-gate wsp->walk_cbdata); 941*0Sstevel@tonic-gate 942*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)(((queue_t *)wsp->walk_data)->q_next); 943*0Sstevel@tonic-gate return (status); 944*0Sstevel@tonic-gate } 945*0Sstevel@tonic-gate 946*0Sstevel@tonic-gate void 947*0Sstevel@tonic-gate queue_walk_fini(mdb_walk_state_t *wsp) 948*0Sstevel@tonic-gate { 949*0Sstevel@tonic-gate mdb_free(wsp->walk_data, sizeof (queue_t)); 950*0Sstevel@tonic-gate } 951*0Sstevel@tonic-gate 952*0Sstevel@tonic-gate int 953*0Sstevel@tonic-gate str_walk_init(mdb_walk_state_t *wsp) 954*0Sstevel@tonic-gate { 955*0Sstevel@tonic-gate stdata_t s; 956*0Sstevel@tonic-gate 957*0Sstevel@tonic-gate if (wsp->walk_addr == NULL) { 958*0Sstevel@tonic-gate mdb_warn("walk must begin at address of stdata_t\n"); 959*0Sstevel@tonic-gate return (WALK_ERR); 960*0Sstevel@tonic-gate } 961*0Sstevel@tonic-gate 962*0Sstevel@tonic-gate if (mdb_vread(&s, sizeof (s), wsp->walk_addr) == -1) { 963*0Sstevel@tonic-gate mdb_warn("failed to read stdata at %p", wsp->walk_addr); 964*0Sstevel@tonic-gate return (WALK_ERR); 965*0Sstevel@tonic-gate } 966*0Sstevel@tonic-gate 967*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)s.sd_wrq; 968*0Sstevel@tonic-gate wsp->walk_data = mdb_alloc(sizeof (queue_t) * 2, UM_SLEEP); 969*0Sstevel@tonic-gate 970*0Sstevel@tonic-gate return (WALK_NEXT); 971*0Sstevel@tonic-gate } 972*0Sstevel@tonic-gate 973*0Sstevel@tonic-gate int 974*0Sstevel@tonic-gate strr_walk_step(mdb_walk_state_t *wsp) 975*0Sstevel@tonic-gate { 976*0Sstevel@tonic-gate queue_t *rq = wsp->walk_data, *wq = rq + 1; 977*0Sstevel@tonic-gate int status; 978*0Sstevel@tonic-gate 979*0Sstevel@tonic-gate if (wsp->walk_addr == NULL) 980*0Sstevel@tonic-gate return (WALK_DONE); 981*0Sstevel@tonic-gate 982*0Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (queue_t) * 2, 983*0Sstevel@tonic-gate wsp->walk_addr - sizeof (queue_t)) == -1) { 984*0Sstevel@tonic-gate mdb_warn("failed to read queue pair at %p", 985*0Sstevel@tonic-gate wsp->walk_addr - sizeof (queue_t)); 986*0Sstevel@tonic-gate return (WALK_DONE); 987*0Sstevel@tonic-gate } 988*0Sstevel@tonic-gate 989*0Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr - sizeof (queue_t), 990*0Sstevel@tonic-gate rq, wsp->walk_cbdata); 991*0Sstevel@tonic-gate 992*0Sstevel@tonic-gate if (wq->q_next != NULL) 993*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)wq->q_next; 994*0Sstevel@tonic-gate else 995*0Sstevel@tonic-gate wsp->walk_addr = mdb_qwnext(wq); 996*0Sstevel@tonic-gate 997*0Sstevel@tonic-gate return (status); 998*0Sstevel@tonic-gate } 999*0Sstevel@tonic-gate 1000*0Sstevel@tonic-gate int 1001*0Sstevel@tonic-gate strw_walk_step(mdb_walk_state_t *wsp) 1002*0Sstevel@tonic-gate { 1003*0Sstevel@tonic-gate queue_t *rq = wsp->walk_data, *wq = rq + 1; 1004*0Sstevel@tonic-gate int status; 1005*0Sstevel@tonic-gate 1006*0Sstevel@tonic-gate if (wsp->walk_addr == NULL) 1007*0Sstevel@tonic-gate return (WALK_DONE); 1008*0Sstevel@tonic-gate 1009*0Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (queue_t) * 2, 1010*0Sstevel@tonic-gate wsp->walk_addr - sizeof (queue_t)) == -1) { 1011*0Sstevel@tonic-gate mdb_warn("failed to read queue pair at %p", 1012*0Sstevel@tonic-gate wsp->walk_addr - sizeof (queue_t)); 1013*0Sstevel@tonic-gate return (WALK_DONE); 1014*0Sstevel@tonic-gate } 1015*0Sstevel@tonic-gate 1016*0Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, wq, wsp->walk_cbdata); 1017*0Sstevel@tonic-gate 1018*0Sstevel@tonic-gate if (wq->q_next != NULL) 1019*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)wq->q_next; 1020*0Sstevel@tonic-gate else 1021*0Sstevel@tonic-gate wsp->walk_addr = mdb_qwnext(wq); 1022*0Sstevel@tonic-gate 1023*0Sstevel@tonic-gate return (status); 1024*0Sstevel@tonic-gate } 1025*0Sstevel@tonic-gate 1026*0Sstevel@tonic-gate void 1027*0Sstevel@tonic-gate str_walk_fini(mdb_walk_state_t *wsp) 1028*0Sstevel@tonic-gate { 1029*0Sstevel@tonic-gate mdb_free(wsp->walk_data, sizeof (queue_t) * 2); 1030*0Sstevel@tonic-gate } 1031*0Sstevel@tonic-gate 1032*0Sstevel@tonic-gate static int 1033*0Sstevel@tonic-gate print_qpair(uintptr_t addr, const queue_t *q, uint_t *depth) 1034*0Sstevel@tonic-gate { 1035*0Sstevel@tonic-gate static const char box_lid[] = 1036*0Sstevel@tonic-gate "+-----------------------+-----------------------+\n"; 1037*0Sstevel@tonic-gate static const char box_sep[] = 1038*0Sstevel@tonic-gate "| | |\n"; 1039*0Sstevel@tonic-gate 1040*0Sstevel@tonic-gate char wname[32], rname[32], info1[256], *info2; 1041*0Sstevel@tonic-gate 1042*0Sstevel@tonic-gate if (*depth != 0) { 1043*0Sstevel@tonic-gate mdb_printf(" | ^\n"); 1044*0Sstevel@tonic-gate mdb_printf(" v |\n"); 1045*0Sstevel@tonic-gate } else 1046*0Sstevel@tonic-gate mdb_printf("\n"); 1047*0Sstevel@tonic-gate 1048*0Sstevel@tonic-gate (void) mdb_qname(_WR(q), wname, sizeof (wname)); 1049*0Sstevel@tonic-gate (void) mdb_qname(_RD(q), rname, sizeof (rname)); 1050*0Sstevel@tonic-gate 1051*0Sstevel@tonic-gate mdb_qinfo(_WR(q), info1, sizeof (info1)); 1052*0Sstevel@tonic-gate if ((info2 = strchr(info1, '\n')) != NULL) 1053*0Sstevel@tonic-gate *info2++ = '\0'; 1054*0Sstevel@tonic-gate else 1055*0Sstevel@tonic-gate info2 = ""; 1056*0Sstevel@tonic-gate 1057*0Sstevel@tonic-gate mdb_printf(box_lid); 1058*0Sstevel@tonic-gate mdb_printf("| 0x%-19p | 0x%-19p | %s\n", 1059*0Sstevel@tonic-gate addr, addr - sizeof (queue_t), info1); 1060*0Sstevel@tonic-gate 1061*0Sstevel@tonic-gate mdb_printf("| %<b>%-21s%</b> | %<b>%-21s%</b> |", wname, rname); 1062*0Sstevel@tonic-gate mdb_flush(); /* Account for buffered terminal sequences */ 1063*0Sstevel@tonic-gate 1064*0Sstevel@tonic-gate mdb_printf(" %s\n", info2); 1065*0Sstevel@tonic-gate mdb_printf(box_sep); 1066*0Sstevel@tonic-gate 1067*0Sstevel@tonic-gate mdb_qinfo(_RD(q), info1, sizeof (info1)); 1068*0Sstevel@tonic-gate if ((info2 = strchr(info1, '\n')) != NULL) 1069*0Sstevel@tonic-gate *info2++ = '\0'; 1070*0Sstevel@tonic-gate else 1071*0Sstevel@tonic-gate info2 = ""; 1072*0Sstevel@tonic-gate 1073*0Sstevel@tonic-gate mdb_printf("| cnt = 0t%-13lu | cnt = 0t%-13lu | %s\n", 1074*0Sstevel@tonic-gate _WR(q)->q_count, _RD(q)->q_count, info1); 1075*0Sstevel@tonic-gate 1076*0Sstevel@tonic-gate mdb_printf("| flg = 0x%08x | flg = 0x%08x | %s\n", 1077*0Sstevel@tonic-gate _WR(q)->q_flag, _RD(q)->q_flag, info2); 1078*0Sstevel@tonic-gate 1079*0Sstevel@tonic-gate mdb_printf(box_lid); 1080*0Sstevel@tonic-gate *depth += 1; 1081*0Sstevel@tonic-gate return (0); 1082*0Sstevel@tonic-gate } 1083*0Sstevel@tonic-gate 1084*0Sstevel@tonic-gate /*ARGSUSED*/ 1085*0Sstevel@tonic-gate int 1086*0Sstevel@tonic-gate stream(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1087*0Sstevel@tonic-gate { 1088*0Sstevel@tonic-gate uint_t d = 0; /* Depth counter for print_qpair */ 1089*0Sstevel@tonic-gate 1090*0Sstevel@tonic-gate if (argc != 0 || !(flags & DCMD_ADDRSPEC)) 1091*0Sstevel@tonic-gate return (DCMD_USAGE); 1092*0Sstevel@tonic-gate 1093*0Sstevel@tonic-gate if (mdb_pwalk("writeq", (mdb_walk_cb_t)print_qpair, &d, addr) == -1) { 1094*0Sstevel@tonic-gate mdb_warn("failed to walk writeq"); 1095*0Sstevel@tonic-gate return (DCMD_ERR); 1096*0Sstevel@tonic-gate } 1097*0Sstevel@tonic-gate 1098*0Sstevel@tonic-gate return (DCMD_OK); 1099*0Sstevel@tonic-gate } 1100*0Sstevel@tonic-gate 1101*0Sstevel@tonic-gate int 1102*0Sstevel@tonic-gate mblk_walk_init(mdb_walk_state_t *wsp) 1103*0Sstevel@tonic-gate { 1104*0Sstevel@tonic-gate wsp->walk_data = mdb_alloc(sizeof (mblk_t), UM_SLEEP); 1105*0Sstevel@tonic-gate return (WALK_NEXT); 1106*0Sstevel@tonic-gate } 1107*0Sstevel@tonic-gate 1108*0Sstevel@tonic-gate int 1109*0Sstevel@tonic-gate b_cont_step(mdb_walk_state_t *wsp) 1110*0Sstevel@tonic-gate { 1111*0Sstevel@tonic-gate int status; 1112*0Sstevel@tonic-gate 1113*0Sstevel@tonic-gate if (wsp->walk_addr == NULL) 1114*0Sstevel@tonic-gate return (WALK_DONE); 1115*0Sstevel@tonic-gate 1116*0Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (mblk_t), wsp->walk_addr) == -1) { 1117*0Sstevel@tonic-gate mdb_warn("failed to read mblk at %p", wsp->walk_addr); 1118*0Sstevel@tonic-gate return (WALK_DONE); 1119*0Sstevel@tonic-gate } 1120*0Sstevel@tonic-gate 1121*0Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 1122*0Sstevel@tonic-gate wsp->walk_cbdata); 1123*0Sstevel@tonic-gate 1124*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)(((mblk_t *)wsp->walk_data)->b_cont); 1125*0Sstevel@tonic-gate return (status); 1126*0Sstevel@tonic-gate } 1127*0Sstevel@tonic-gate 1128*0Sstevel@tonic-gate int 1129*0Sstevel@tonic-gate b_next_step(mdb_walk_state_t *wsp) 1130*0Sstevel@tonic-gate { 1131*0Sstevel@tonic-gate int status; 1132*0Sstevel@tonic-gate 1133*0Sstevel@tonic-gate if (wsp->walk_addr == NULL) 1134*0Sstevel@tonic-gate return (WALK_DONE); 1135*0Sstevel@tonic-gate 1136*0Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (mblk_t), wsp->walk_addr) == -1) { 1137*0Sstevel@tonic-gate mdb_warn("failed to read mblk at %p", wsp->walk_addr); 1138*0Sstevel@tonic-gate return (WALK_DONE); 1139*0Sstevel@tonic-gate } 1140*0Sstevel@tonic-gate 1141*0Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 1142*0Sstevel@tonic-gate wsp->walk_cbdata); 1143*0Sstevel@tonic-gate 1144*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)(((mblk_t *)wsp->walk_data)->b_next); 1145*0Sstevel@tonic-gate return (status); 1146*0Sstevel@tonic-gate } 1147*0Sstevel@tonic-gate 1148*0Sstevel@tonic-gate void 1149*0Sstevel@tonic-gate mblk_walk_fini(mdb_walk_state_t *wsp) 1150*0Sstevel@tonic-gate { 1151*0Sstevel@tonic-gate mdb_free(wsp->walk_data, sizeof (mblk_t)); 1152*0Sstevel@tonic-gate } 1153*0Sstevel@tonic-gate 1154*0Sstevel@tonic-gate /* ARGSUSED */ 1155*0Sstevel@tonic-gate int 1156*0Sstevel@tonic-gate mblk2dblk(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1157*0Sstevel@tonic-gate { 1158*0Sstevel@tonic-gate mblk_t mb; 1159*0Sstevel@tonic-gate 1160*0Sstevel@tonic-gate if (argc != 0) 1161*0Sstevel@tonic-gate return (DCMD_USAGE); 1162*0Sstevel@tonic-gate 1163*0Sstevel@tonic-gate if (mdb_vread(&mb, sizeof (mb), addr) == -1) { 1164*0Sstevel@tonic-gate mdb_warn("couldn't read mblk at %p", addr); 1165*0Sstevel@tonic-gate return (DCMD_ERR); 1166*0Sstevel@tonic-gate } 1167*0Sstevel@tonic-gate 1168*0Sstevel@tonic-gate mdb_printf("%p\n", mb.b_datap); 1169*0Sstevel@tonic-gate return (DCMD_OK); 1170*0Sstevel@tonic-gate } 1171*0Sstevel@tonic-gate 1172*0Sstevel@tonic-gate 1173*0Sstevel@tonic-gate static void 1174*0Sstevel@tonic-gate mblk_error(int *error, uintptr_t addr, char *message) 1175*0Sstevel@tonic-gate { 1176*0Sstevel@tonic-gate if (!*error) 1177*0Sstevel@tonic-gate mdb_printf("%?lx: ", addr); 1178*0Sstevel@tonic-gate else 1179*0Sstevel@tonic-gate mdb_printf(", "); 1180*0Sstevel@tonic-gate mdb_printf("%s", message); 1181*0Sstevel@tonic-gate *error = 1; 1182*0Sstevel@tonic-gate } 1183*0Sstevel@tonic-gate 1184*0Sstevel@tonic-gate int 1185*0Sstevel@tonic-gate mblk_verify(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1186*0Sstevel@tonic-gate { 1187*0Sstevel@tonic-gate mblk_t mb; 1188*0Sstevel@tonic-gate dblk_t db; 1189*0Sstevel@tonic-gate int error = 0; 1190*0Sstevel@tonic-gate 1191*0Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 1192*0Sstevel@tonic-gate if (mdb_walk_dcmd("streams_mblk", "mblk_verify", argc, argv) == 1193*0Sstevel@tonic-gate -1) { 1194*0Sstevel@tonic-gate mdb_warn("can't walk mblk cache"); 1195*0Sstevel@tonic-gate return (DCMD_ERR); 1196*0Sstevel@tonic-gate } 1197*0Sstevel@tonic-gate return (DCMD_OK); 1198*0Sstevel@tonic-gate } 1199*0Sstevel@tonic-gate 1200*0Sstevel@tonic-gate if (mdb_vread(&mb, sizeof (mblk_t), addr) == -1) { 1201*0Sstevel@tonic-gate mdb_warn("can't read mblk_t at 0x%lx", addr); 1202*0Sstevel@tonic-gate return (DCMD_ERR); 1203*0Sstevel@tonic-gate } 1204*0Sstevel@tonic-gate 1205*0Sstevel@tonic-gate if (mdb_vread(&db, sizeof (dblk_t), (uintptr_t)mb.b_datap) == -1) { 1206*0Sstevel@tonic-gate mdb_warn("%?lx: invalid b_datap pointer\n", addr); 1207*0Sstevel@tonic-gate return (DCMD_ERR); 1208*0Sstevel@tonic-gate } 1209*0Sstevel@tonic-gate 1210*0Sstevel@tonic-gate if (mb.b_rptr < db.db_base || mb.b_rptr > db.db_lim) 1211*0Sstevel@tonic-gate mblk_error(&error, addr, "b_rptr out of range"); 1212*0Sstevel@tonic-gate 1213*0Sstevel@tonic-gate if (mb.b_wptr < db.db_base || mb.b_wptr > db.db_lim) 1214*0Sstevel@tonic-gate mblk_error(&error, addr, "b_wptr out of range"); 1215*0Sstevel@tonic-gate 1216*0Sstevel@tonic-gate if (error) 1217*0Sstevel@tonic-gate mdb_printf("\n"); 1218*0Sstevel@tonic-gate 1219*0Sstevel@tonic-gate return (error ? DCMD_ERR : DCMD_OK); 1220*0Sstevel@tonic-gate } 1221*0Sstevel@tonic-gate 1222*0Sstevel@tonic-gate int 1223*0Sstevel@tonic-gate mblk_prt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1224*0Sstevel@tonic-gate { 1225*0Sstevel@tonic-gate const int MBLK_FLGDELT = (int)(sizeof (uintptr_t) * 2 + 15); 1226*0Sstevel@tonic-gate mblk_t mblk; 1227*0Sstevel@tonic-gate dblk_t dblk; 1228*0Sstevel@tonic-gate int b_flag; 1229*0Sstevel@tonic-gate int db_type; 1230*0Sstevel@tonic-gate int mblklen; 1231*0Sstevel@tonic-gate uint64_t len = ~0UL; 1232*0Sstevel@tonic-gate uint64_t glen = ~0UL; 1233*0Sstevel@tonic-gate uint64_t llen = ~0UL; 1234*0Sstevel@tonic-gate uint64_t blen = ~0UL; 1235*0Sstevel@tonic-gate const char *dbtype; 1236*0Sstevel@tonic-gate const char *flag = NULL, *not_flag = NULL; 1237*0Sstevel@tonic-gate const char *typ = NULL, *not_typ = NULL; 1238*0Sstevel@tonic-gate uintptr_t dbaddr = 0; 1239*0Sstevel@tonic-gate uint32_t tmask = 0, not_tmask = 0; 1240*0Sstevel@tonic-gate uint32_t mask = 0, not_mask = 0; 1241*0Sstevel@tonic-gate uint_t quiet = FALSE; 1242*0Sstevel@tonic-gate uint_t verbose = FALSE; 1243*0Sstevel@tonic-gate 1244*0Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 1245*0Sstevel@tonic-gate if (mdb_walk_dcmd("genunix`streams_mblk", "genunix`mblk", 1246*0Sstevel@tonic-gate argc, argv) == -1) { 1247*0Sstevel@tonic-gate mdb_warn("failed to walk mblk cache"); 1248*0Sstevel@tonic-gate return (DCMD_ERR); 1249*0Sstevel@tonic-gate } 1250*0Sstevel@tonic-gate return (DCMD_OK); 1251*0Sstevel@tonic-gate } 1252*0Sstevel@tonic-gate 1253*0Sstevel@tonic-gate if (flags & DCMD_PIPE_OUT) 1254*0Sstevel@tonic-gate quiet = TRUE; 1255*0Sstevel@tonic-gate 1256*0Sstevel@tonic-gate if (mdb_getopts(argc, argv, 1257*0Sstevel@tonic-gate 'v', MDB_OPT_SETBITS, TRUE, &verbose, 1258*0Sstevel@tonic-gate 'q', MDB_OPT_SETBITS, TRUE, &quiet, 1259*0Sstevel@tonic-gate 'f', MDB_OPT_STR, &flag, 1260*0Sstevel@tonic-gate 'F', MDB_OPT_STR, ¬_flag, 1261*0Sstevel@tonic-gate 't', MDB_OPT_STR, &typ, 1262*0Sstevel@tonic-gate 'T', MDB_OPT_STR, ¬_typ, 1263*0Sstevel@tonic-gate 'l', MDB_OPT_UINT64, &len, 1264*0Sstevel@tonic-gate 'L', MDB_OPT_UINT64, &llen, 1265*0Sstevel@tonic-gate 'G', MDB_OPT_UINT64, &glen, 1266*0Sstevel@tonic-gate 'b', MDB_OPT_UINT64, &blen, 1267*0Sstevel@tonic-gate 'd', MDB_OPT_UINTPTR, &dbaddr, 1268*0Sstevel@tonic-gate NULL) != argc) 1269*0Sstevel@tonic-gate return (DCMD_USAGE); 1270*0Sstevel@tonic-gate 1271*0Sstevel@tonic-gate /* 1272*0Sstevel@tonic-gate * If any of the filtering flags is specified, don't print anything 1273*0Sstevel@tonic-gate * except the matching pointer. 1274*0Sstevel@tonic-gate */ 1275*0Sstevel@tonic-gate if ((flag != NULL) || (not_flag != NULL) || (typ != NULL) || 1276*0Sstevel@tonic-gate (not_typ != NULL) || (len != ~0UL) || (glen != ~0UL) || 1277*0Sstevel@tonic-gate (llen != ~0UL) || (blen != ~0UL) || (dbaddr != 0)) 1278*0Sstevel@tonic-gate quiet = TRUE; 1279*0Sstevel@tonic-gate 1280*0Sstevel@tonic-gate if (flag != NULL && streams_parse_flag(mbf, flag, &mask) == -1) { 1281*0Sstevel@tonic-gate mdb_warn("unrecognized mblk flag '%s'\n", flag); 1282*0Sstevel@tonic-gate streams_flag_usage(mbf); 1283*0Sstevel@tonic-gate return (DCMD_USAGE); 1284*0Sstevel@tonic-gate } 1285*0Sstevel@tonic-gate 1286*0Sstevel@tonic-gate if (not_flag != NULL && 1287*0Sstevel@tonic-gate streams_parse_flag(mbf, not_flag, ¬_mask) == -1) { 1288*0Sstevel@tonic-gate mdb_warn("unrecognized mblk flag '%s'\n", flag); 1289*0Sstevel@tonic-gate streams_flag_usage(mbf); 1290*0Sstevel@tonic-gate return (DCMD_USAGE); 1291*0Sstevel@tonic-gate } 1292*0Sstevel@tonic-gate 1293*0Sstevel@tonic-gate if (typ != NULL && streams_parse_type(mbt, typ, &tmask) == -1) { 1294*0Sstevel@tonic-gate mdb_warn("unrecognized dblk type '%s'\n", typ); 1295*0Sstevel@tonic-gate streams_type_usage(mbt); 1296*0Sstevel@tonic-gate return (DCMD_USAGE); 1297*0Sstevel@tonic-gate } 1298*0Sstevel@tonic-gate 1299*0Sstevel@tonic-gate if (not_typ != NULL && streams_parse_type(mbt, not_typ, ¬_tmask) 1300*0Sstevel@tonic-gate == -1) { 1301*0Sstevel@tonic-gate mdb_warn("unrecognized dblk type '%s'\n", not_typ); 1302*0Sstevel@tonic-gate streams_type_usage(mbt); 1303*0Sstevel@tonic-gate return (DCMD_USAGE); 1304*0Sstevel@tonic-gate } 1305*0Sstevel@tonic-gate 1306*0Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && !quiet) { 1307*0Sstevel@tonic-gate mdb_printf("%?s %2s %-7s %-5s %-5s %?s %?s\n", 1308*0Sstevel@tonic-gate "ADDR", "FL", "TYPE", "LEN", "BLEN", "RPTR", "DBLK"); 1309*0Sstevel@tonic-gate } 1310*0Sstevel@tonic-gate 1311*0Sstevel@tonic-gate if (mdb_vread(&mblk, sizeof (mblk), addr) == -1) { 1312*0Sstevel@tonic-gate mdb_warn("couldn't read mblk at %p", addr); 1313*0Sstevel@tonic-gate return (DCMD_ERR); 1314*0Sstevel@tonic-gate } 1315*0Sstevel@tonic-gate b_flag = mblk.b_flag; 1316*0Sstevel@tonic-gate 1317*0Sstevel@tonic-gate if (mask != 0 && !(b_flag & mask)) 1318*0Sstevel@tonic-gate return (DCMD_OK); 1319*0Sstevel@tonic-gate 1320*0Sstevel@tonic-gate if (not_mask != 0 && (b_flag & not_mask)) 1321*0Sstevel@tonic-gate return (DCMD_OK); 1322*0Sstevel@tonic-gate 1323*0Sstevel@tonic-gate if (mdb_vread(&dblk, sizeof (dblk), (uintptr_t)(mblk.b_datap)) == -1) { 1324*0Sstevel@tonic-gate mdb_warn("couldn't read dblk at %p/%p", addr, mblk.b_datap); 1325*0Sstevel@tonic-gate return (DCMD_ERR); 1326*0Sstevel@tonic-gate } 1327*0Sstevel@tonic-gate db_type = dblk.db_type; 1328*0Sstevel@tonic-gate 1329*0Sstevel@tonic-gate /* M_DATA is 0, so tmask has special value 0xff for it */ 1330*0Sstevel@tonic-gate if ((tmask != 0) && 1331*0Sstevel@tonic-gate (((tmask == M_DATA_T) && (db_type != M_DATA)) || 1332*0Sstevel@tonic-gate ((tmask != M_DATA_T) && (db_type != tmask)))) 1333*0Sstevel@tonic-gate return (DCMD_OK); 1334*0Sstevel@tonic-gate 1335*0Sstevel@tonic-gate 1336*0Sstevel@tonic-gate if ((not_tmask != 0) && 1337*0Sstevel@tonic-gate (((not_tmask == M_DATA_T) && (db_type == M_DATA)) || 1338*0Sstevel@tonic-gate (db_type == not_tmask))) 1339*0Sstevel@tonic-gate return (DCMD_OK); 1340*0Sstevel@tonic-gate 1341*0Sstevel@tonic-gate if (dbaddr != 0 && (uintptr_t)mblk.b_datap != dbaddr) 1342*0Sstevel@tonic-gate return (DCMD_OK); 1343*0Sstevel@tonic-gate 1344*0Sstevel@tonic-gate mblklen = MBLKL(&mblk); 1345*0Sstevel@tonic-gate 1346*0Sstevel@tonic-gate if ((len != ~0UL) && (len != mblklen)) 1347*0Sstevel@tonic-gate return (DCMD_OK); 1348*0Sstevel@tonic-gate 1349*0Sstevel@tonic-gate if ((llen != ~0Ul) && (mblklen > (int)llen)) 1350*0Sstevel@tonic-gate return (DCMD_OK); 1351*0Sstevel@tonic-gate 1352*0Sstevel@tonic-gate if ((glen != ~0Ul) && (mblklen < (int)glen)) 1353*0Sstevel@tonic-gate return (DCMD_OK); 1354*0Sstevel@tonic-gate 1355*0Sstevel@tonic-gate if ((blen != ~0UL) && (blen != (dblk.db_lim - dblk.db_base))) 1356*0Sstevel@tonic-gate return (DCMD_OK); 1357*0Sstevel@tonic-gate 1358*0Sstevel@tonic-gate /* 1359*0Sstevel@tonic-gate * Options are specified for filtering, so If any option is specified on 1360*0Sstevel@tonic-gate * the command line, just print address and exit. 1361*0Sstevel@tonic-gate */ 1362*0Sstevel@tonic-gate if (quiet) { 1363*0Sstevel@tonic-gate mdb_printf("%0?p\n", addr); 1364*0Sstevel@tonic-gate return (DCMD_OK); 1365*0Sstevel@tonic-gate } 1366*0Sstevel@tonic-gate 1367*0Sstevel@tonic-gate /* Figure out symbolic DB_TYPE */ 1368*0Sstevel@tonic-gate if (db_type < A_SIZE(db_control_types)) { 1369*0Sstevel@tonic-gate dbtype = db_control_types[db_type]; 1370*0Sstevel@tonic-gate } else { 1371*0Sstevel@tonic-gate /* 1372*0Sstevel@tonic-gate * Must be a high-priority message -- adjust so that 1373*0Sstevel@tonic-gate * "QPCTL + 1" corresponds to db_control_hipri_types[0] 1374*0Sstevel@tonic-gate */ 1375*0Sstevel@tonic-gate db_type -= (QPCTL + 1); 1376*0Sstevel@tonic-gate if (db_type >= 0 && db_type < A_SIZE(db_control_hipri_types)) 1377*0Sstevel@tonic-gate dbtype = db_control_hipri_types[db_type]; 1378*0Sstevel@tonic-gate else 1379*0Sstevel@tonic-gate dbtype = "UNKNOWN"; 1380*0Sstevel@tonic-gate } 1381*0Sstevel@tonic-gate 1382*0Sstevel@tonic-gate mdb_printf("%0?p %-2x %-7s %-5d %-5d %0?p %0?p\n", 1383*0Sstevel@tonic-gate addr, b_flag, dbtype, mblklen, dblk.db_lim - dblk.db_base, 1384*0Sstevel@tonic-gate mblk.b_rptr, mblk.b_datap); 1385*0Sstevel@tonic-gate 1386*0Sstevel@tonic-gate if (verbose) { 1387*0Sstevel@tonic-gate int i, arm = 0; 1388*0Sstevel@tonic-gate 1389*0Sstevel@tonic-gate for (i = 0; mbf[i].strf_name != NULL; i++) { 1390*0Sstevel@tonic-gate if (!(b_flag & (1 << i))) 1391*0Sstevel@tonic-gate continue; 1392*0Sstevel@tonic-gate if (!arm) { 1393*0Sstevel@tonic-gate mdb_printf("%*s|\n%*s+--> ", 1394*0Sstevel@tonic-gate MBLK_FLGDELT, "", MBLK_FLGDELT, ""); 1395*0Sstevel@tonic-gate arm = 1; 1396*0Sstevel@tonic-gate } else 1397*0Sstevel@tonic-gate mdb_printf("%*s ", MBLK_FLGDELT, ""); 1398*0Sstevel@tonic-gate 1399*0Sstevel@tonic-gate mdb_printf("%-12s %s\n", 1400*0Sstevel@tonic-gate mbf[i].strf_name, mbf[i].strf_descr); 1401*0Sstevel@tonic-gate } 1402*0Sstevel@tonic-gate } 1403*0Sstevel@tonic-gate return (DCMD_OK); 1404*0Sstevel@tonic-gate } 1405*0Sstevel@tonic-gate 1406*0Sstevel@tonic-gate /* 1407*0Sstevel@tonic-gate * Streams flow trace walkers. 1408*0Sstevel@tonic-gate */ 1409*0Sstevel@tonic-gate 1410*0Sstevel@tonic-gate int 1411*0Sstevel@tonic-gate strftblk_walk_init(mdb_walk_state_t *wsp) 1412*0Sstevel@tonic-gate { 1413*0Sstevel@tonic-gate ftblkdata_t *ftd; 1414*0Sstevel@tonic-gate dblk_t db; 1415*0Sstevel@tonic-gate 1416*0Sstevel@tonic-gate /* Get the dblock from the address */ 1417*0Sstevel@tonic-gate if (mdb_vread(&db, sizeof (dblk_t), wsp->walk_addr) == -1) { 1418*0Sstevel@tonic-gate mdb_warn("failed to read dblk at %p", wsp->walk_addr); 1419*0Sstevel@tonic-gate return (WALK_ERR); 1420*0Sstevel@tonic-gate } 1421*0Sstevel@tonic-gate 1422*0Sstevel@tonic-gate /* Is there any flow trace data? */ 1423*0Sstevel@tonic-gate if (db.db_fthdr == NULL) { 1424*0Sstevel@tonic-gate return (WALK_DONE); 1425*0Sstevel@tonic-gate } 1426*0Sstevel@tonic-gate 1427*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)((char *)db.db_fthdr + 1428*0Sstevel@tonic-gate offsetof(fthdr_t, first)); 1429*0Sstevel@tonic-gate 1430*0Sstevel@tonic-gate ftd = mdb_alloc(sizeof (ftblkdata_t), UM_SLEEP); 1431*0Sstevel@tonic-gate ftd->ft_ix = 0; 1432*0Sstevel@tonic-gate ftd->ft_in_evlist = B_FALSE; 1433*0Sstevel@tonic-gate wsp->walk_data = ftd; 1434*0Sstevel@tonic-gate 1435*0Sstevel@tonic-gate return (WALK_NEXT); 1436*0Sstevel@tonic-gate } 1437*0Sstevel@tonic-gate 1438*0Sstevel@tonic-gate int 1439*0Sstevel@tonic-gate strftblk_step(mdb_walk_state_t *wsp) 1440*0Sstevel@tonic-gate { 1441*0Sstevel@tonic-gate ftblkdata_t *ftd; 1442*0Sstevel@tonic-gate ftblk_t *ftbp; 1443*0Sstevel@tonic-gate int status = WALK_NEXT; 1444*0Sstevel@tonic-gate 1445*0Sstevel@tonic-gate if (wsp->walk_addr == NULL) 1446*0Sstevel@tonic-gate return (WALK_DONE); 1447*0Sstevel@tonic-gate 1448*0Sstevel@tonic-gate ftd = (ftblkdata_t *)wsp->walk_data; 1449*0Sstevel@tonic-gate ftbp = &(ftd->ft_data); 1450*0Sstevel@tonic-gate 1451*0Sstevel@tonic-gate if (! ftd->ft_in_evlist) { 1452*0Sstevel@tonic-gate /* Read a new ft block */ 1453*0Sstevel@tonic-gate if (mdb_vread(ftbp, sizeof (ftblk_t), 1454*0Sstevel@tonic-gate wsp->walk_addr) == -1) { 1455*0Sstevel@tonic-gate mdb_warn("failed to read ftblk at %p", wsp->walk_addr); 1456*0Sstevel@tonic-gate return (WALK_ERR); 1457*0Sstevel@tonic-gate } 1458*0Sstevel@tonic-gate /* 1459*0Sstevel@tonic-gate * Check correctness of the index field. 1460*0Sstevel@tonic-gate */ 1461*0Sstevel@tonic-gate if (ftbp->ix < 0 || ftbp->ix > FTBLK_EVNTS) { 1462*0Sstevel@tonic-gate mdb_warn("ftblk: incorrect index value %i\n", ftbp->ix); 1463*0Sstevel@tonic-gate return (WALK_ERR); 1464*0Sstevel@tonic-gate } 1465*0Sstevel@tonic-gate ftd->ft_ix = 1; 1466*0Sstevel@tonic-gate ftd->ft_in_evlist = B_TRUE; 1467*0Sstevel@tonic-gate } 1468*0Sstevel@tonic-gate 1469*0Sstevel@tonic-gate if (ftd->ft_ix > ftbp->ix) { 1470*0Sstevel@tonic-gate ftd->ft_in_evlist = B_FALSE; 1471*0Sstevel@tonic-gate /* End of event list reached - move to the next event block */ 1472*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)ftbp->nxt; 1473*0Sstevel@tonic-gate } else { 1474*0Sstevel@tonic-gate /* Print event address */ 1475*0Sstevel@tonic-gate status = wsp->walk_callback((uintptr_t)((char *)wsp->walk_addr + 1476*0Sstevel@tonic-gate offsetof(ftblk_t, ev) + 1477*0Sstevel@tonic-gate (ftd->ft_ix - 1) * sizeof (struct ftevnt)), 1478*0Sstevel@tonic-gate wsp->walk_data, wsp->walk_cbdata); 1479*0Sstevel@tonic-gate ftd->ft_ix++; 1480*0Sstevel@tonic-gate } 1481*0Sstevel@tonic-gate 1482*0Sstevel@tonic-gate return (status); 1483*0Sstevel@tonic-gate } 1484*0Sstevel@tonic-gate 1485*0Sstevel@tonic-gate 1486*0Sstevel@tonic-gate void 1487*0Sstevel@tonic-gate strftblk_walk_fini(mdb_walk_state_t *wsp) 1488*0Sstevel@tonic-gate { 1489*0Sstevel@tonic-gate mdb_free(wsp->walk_data, sizeof (ftblkdata_t)); 1490*0Sstevel@tonic-gate } 1491*0Sstevel@tonic-gate 1492*0Sstevel@tonic-gate /*ARGSUSED*/ 1493*0Sstevel@tonic-gate int 1494*0Sstevel@tonic-gate strftevent(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1495*0Sstevel@tonic-gate { 1496*0Sstevel@tonic-gate struct ftevnt ev; 1497*0Sstevel@tonic-gate char modname[MODMAXNAMELEN]; 1498*0Sstevel@tonic-gate 1499*0Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 1500*0Sstevel@tonic-gate return (DCMD_USAGE); 1501*0Sstevel@tonic-gate 1502*0Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) { 1503*0Sstevel@tonic-gate mdb_printf("%?s %?s %s %s %-24s %s\n", 1504*0Sstevel@tonic-gate "ADDR", "MID", "EVNT", "DATA", "NAME", "EVENT"); 1505*0Sstevel@tonic-gate } 1506*0Sstevel@tonic-gate 1507*0Sstevel@tonic-gate if (mdb_vread(&ev, sizeof (ev), addr) == -1) { 1508*0Sstevel@tonic-gate mdb_warn("couldn't read ft event at %p", addr); 1509*0Sstevel@tonic-gate return (DCMD_ERR); 1510*0Sstevel@tonic-gate } 1511*0Sstevel@tonic-gate 1512*0Sstevel@tonic-gate mdb_printf("%0?p %0?p %4x %4x", 1513*0Sstevel@tonic-gate addr, ev.mid, ev.evnt, ev.data); 1514*0Sstevel@tonic-gate 1515*0Sstevel@tonic-gate if (ev.evnt & FTEV_QMASK) { 1516*0Sstevel@tonic-gate if (mdb_readstr(modname, sizeof (modname), 1517*0Sstevel@tonic-gate (uintptr_t)ev.mid) == -1) 1518*0Sstevel@tonic-gate mdb_warn("couldn't read module name at %p", ev.mid); 1519*0Sstevel@tonic-gate mdb_printf(" %-24s", modname); 1520*0Sstevel@tonic-gate } else 1521*0Sstevel@tonic-gate mdb_printf(" %-24a", ev.mid); 1522*0Sstevel@tonic-gate 1523*0Sstevel@tonic-gate ft_printevent(ev.evnt); 1524*0Sstevel@tonic-gate 1525*0Sstevel@tonic-gate mdb_printf("\n"); 1526*0Sstevel@tonic-gate 1527*0Sstevel@tonic-gate return (DCMD_OK); 1528*0Sstevel@tonic-gate } 1529*0Sstevel@tonic-gate 1530*0Sstevel@tonic-gate static void 1531*0Sstevel@tonic-gate ft_printevent(ushort_t ev) 1532*0Sstevel@tonic-gate { 1533*0Sstevel@tonic-gate ushort_t proc_ev = (ev & (FTEV_PROC_START | 0xFF)) - FTEV_PROC_START; 1534*0Sstevel@tonic-gate ushort_t alloc_ev = ev & FTEV_CALLER; 1535*0Sstevel@tonic-gate 1536*0Sstevel@tonic-gate /* Get event class first */ 1537*0Sstevel@tonic-gate if (ev & FTEV_PROC_START) { 1538*0Sstevel@tonic-gate if (proc_ev >= A_SIZE(ftev_proc)) 1539*0Sstevel@tonic-gate mdb_printf(" undefined"); 1540*0Sstevel@tonic-gate else 1541*0Sstevel@tonic-gate mdb_printf(" %s", ftev_proc[proc_ev]); 1542*0Sstevel@tonic-gate } else if (alloc_ev >= A_SIZE(ftev_alloc)) 1543*0Sstevel@tonic-gate mdb_printf(" undefined"); 1544*0Sstevel@tonic-gate else 1545*0Sstevel@tonic-gate mdb_printf(" %s", ftev_alloc[alloc_ev]); 1546*0Sstevel@tonic-gate 1547*0Sstevel@tonic-gate /* Print event modifiers, if any */ 1548*0Sstevel@tonic-gate 1549*0Sstevel@tonic-gate if (ev & FTEV_PS) 1550*0Sstevel@tonic-gate mdb_printf(" | PS"); 1551*0Sstevel@tonic-gate if (ev & FTEV_CS) 1552*0Sstevel@tonic-gate mdb_printf(" | CS"); 1553*0Sstevel@tonic-gate if (ev & FTEV_ISWR) 1554*0Sstevel@tonic-gate mdb_printf(" | ISWR"); 1555*0Sstevel@tonic-gate } 1556*0Sstevel@tonic-gate 1557*0Sstevel@tonic-gate /* 1558*0Sstevel@tonic-gate * Help functions for STREAMS debugging facilities. 1559*0Sstevel@tonic-gate */ 1560*0Sstevel@tonic-gate void 1561*0Sstevel@tonic-gate queue_help(void) 1562*0Sstevel@tonic-gate { 1563*0Sstevel@tonic-gate mdb_printf("Print queue information for a given queue pointer.\n" 1564*0Sstevel@tonic-gate "\nWithout the address of a \"queue_t\" structure given, print " 1565*0Sstevel@tonic-gate "information about all\n" 1566*0Sstevel@tonic-gate "queues in the \"queue_cache\".\n\n" 1567*0Sstevel@tonic-gate "Options:\n" 1568*0Sstevel@tonic-gate " -v:\t\tbe verbose - print symbolic flags falues\n" 1569*0Sstevel@tonic-gate " -q:\t\tbe quiet - print queue pointer only\n" 1570*0Sstevel@tonic-gate " -f flag:\tprint only queues with flag set\n" 1571*0Sstevel@tonic-gate " -F flag:\tprint only queues with flag NOT set\n" 1572*0Sstevel@tonic-gate " -m modname:\tprint only queues with specified module name\n" 1573*0Sstevel@tonic-gate " -s syncq_addr:\tprint only queues which use specified syncq\n\n" 1574*0Sstevel@tonic-gate "Available conversions:\n" 1575*0Sstevel@tonic-gate " q2rdq: given a queue addr print read queue pointer\n" 1576*0Sstevel@tonic-gate " q2wrq: given a queue addr print write queue pointer\n" 1577*0Sstevel@tonic-gate " q2otherq: given a queue addr print other queue pointer\n" 1578*0Sstevel@tonic-gate " q2syncq: given a queue addr print syncq pointer" 1579*0Sstevel@tonic-gate " (::help syncq)\n" 1580*0Sstevel@tonic-gate " q2stream: given a queue addr print its stream pointer\n" 1581*0Sstevel@tonic-gate "\t\t(see ::help stream and ::help stdata)\n\n" 1582*0Sstevel@tonic-gate "To walk q_next pointer of the queue use\n" 1583*0Sstevel@tonic-gate " queue_addr::walk qnext\n"); 1584*0Sstevel@tonic-gate } 1585*0Sstevel@tonic-gate 1586*0Sstevel@tonic-gate void 1587*0Sstevel@tonic-gate syncq_help(void) 1588*0Sstevel@tonic-gate { 1589*0Sstevel@tonic-gate mdb_printf("Print syncq information for a given syncq pointer.\n" 1590*0Sstevel@tonic-gate "\nWithout the address of a \"syncq_t\" structure given, print " 1591*0Sstevel@tonic-gate "information about all\n" 1592*0Sstevel@tonic-gate "syncqs in the \"syncq_cache\".\n\n" 1593*0Sstevel@tonic-gate "Options:\n" 1594*0Sstevel@tonic-gate " -v:\t\tbe verbose - print symbolic flags falues\n" 1595*0Sstevel@tonic-gate " -q:\t\tbe quiet - print syncq pointer only\n" 1596*0Sstevel@tonic-gate " -f flag:\tprint only syncqs with flag set\n" 1597*0Sstevel@tonic-gate " -F flag:\tprint only syncqs with flag NOT set\n" 1598*0Sstevel@tonic-gate " -t type:\tprint only syncqs with specified type\n" 1599*0Sstevel@tonic-gate " -T type:\tprint only syncqs with do NOT have specified type\n\n" 1600*0Sstevel@tonic-gate "Available conversions:\n" 1601*0Sstevel@tonic-gate " syncq2q:\tgiven a syncq addr print queue address of the\n" 1602*0Sstevel@tonic-gate "\t\t\tenclosing queue, if it is part of a queue\n\n" 1603*0Sstevel@tonic-gate "See also: \"::help queue\" and \"::help stdata\"\n"); 1604*0Sstevel@tonic-gate } 1605*0Sstevel@tonic-gate 1606*0Sstevel@tonic-gate void 1607*0Sstevel@tonic-gate stdata_help(void) 1608*0Sstevel@tonic-gate { 1609*0Sstevel@tonic-gate mdb_printf("Print stdata information for a given stdata pointer.\n" 1610*0Sstevel@tonic-gate "\nWithout the address of a \"stdata_t\" structure given, print " 1611*0Sstevel@tonic-gate "information about all\n" 1612*0Sstevel@tonic-gate "stream head pointers from the \"stream_head_cache\".\n\n" 1613*0Sstevel@tonic-gate "Fields printed:\n" 1614*0Sstevel@tonic-gate " ADDR:\tstream head address\n" 1615*0Sstevel@tonic-gate " WRQ:\twrite queue pointer\n" 1616*0Sstevel@tonic-gate " FLAGS:\tstream head flags (use -v to show in symbolic form)\n" 1617*0Sstevel@tonic-gate " VNODE:\tstream vnode pointer\n" 1618*0Sstevel@tonic-gate " N/A:\tpushcount and anchor positions\n" 1619*0Sstevel@tonic-gate " REF:\tstream head reference counter\n\n" 1620*0Sstevel@tonic-gate "Options:\n" 1621*0Sstevel@tonic-gate " -v:\t\tbe verbose - print symbolic flags falues\n" 1622*0Sstevel@tonic-gate " -q:\t\tbe quiet - print stdata pointer only\n" 1623*0Sstevel@tonic-gate " -f flag:\tprint only stdatas with flag set\n" 1624*0Sstevel@tonic-gate " -F flag:\tprint only stdatas with flag NOT set\n\n" 1625*0Sstevel@tonic-gate "Available conversions:\n" 1626*0Sstevel@tonic-gate " str2mate:\tgiven a stream head addr print its mate\n" 1627*0Sstevel@tonic-gate " str2wrq:\tgiven a stream head addr print its write queue\n\n" 1628*0Sstevel@tonic-gate "See also: \"::help queue\" and \"::help syncq\"\n"); 1629*0Sstevel@tonic-gate } 1630*0Sstevel@tonic-gate 1631*0Sstevel@tonic-gate void 1632*0Sstevel@tonic-gate mblk_help(void) 1633*0Sstevel@tonic-gate { 1634*0Sstevel@tonic-gate mdb_printf("Print mblock information for a given mblk pointer.\n" 1635*0Sstevel@tonic-gate "Without the address, print information about all mblocks.\n\n" 1636*0Sstevel@tonic-gate "Fields printed:\n" 1637*0Sstevel@tonic-gate " ADDR:\tmblk address\n" 1638*0Sstevel@tonic-gate " FL:\tFlags\n" 1639*0Sstevel@tonic-gate " TYPE:\tType of corresponding dblock\n" 1640*0Sstevel@tonic-gate " LEN:\tData length as b_wptr - b_rptr\n" 1641*0Sstevel@tonic-gate " BLEN:\tDblock space as db_lim - db_base\n" 1642*0Sstevel@tonic-gate " RPTR:\tRead pointer\n" 1643*0Sstevel@tonic-gate " DBLK:\tDblock pointer\n\n" 1644*0Sstevel@tonic-gate "Options:\n" 1645*0Sstevel@tonic-gate " -v:\t\tbe verbose - print symbolic flags falues\n" 1646*0Sstevel@tonic-gate " -q:\t\tbe quiet - print mblk pointer only\n" 1647*0Sstevel@tonic-gate " -d dbaddr:\t\tprint mblks with specified dblk address\n" 1648*0Sstevel@tonic-gate " -f flag:\tprint only mblks with flag set\n" 1649*0Sstevel@tonic-gate " -F flag:\tprint only mblks with flag NOT set\n" 1650*0Sstevel@tonic-gate " -t type:\tprint only mblks of specified db_type\n" 1651*0Sstevel@tonic-gate " -T type:\tprint only mblks other then the specified db_type\n" 1652*0Sstevel@tonic-gate " -l len:\t\ttprint only mblks with MBLKL == len\n" 1653*0Sstevel@tonic-gate " -L len:\t\tprint only mblks with MBLKL <= len \n" 1654*0Sstevel@tonic-gate " -G len:\t\tprint only mblks with MBLKL >= len \n" 1655*0Sstevel@tonic-gate " -b len:\t\tprint only mblks with db_lim - db_base == len\n" 1656*0Sstevel@tonic-gate "\n"); 1657*0Sstevel@tonic-gate } 1658