4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <mdb/mdb_modapi.h>
27 #include <mdb/mdb_ks.h>
30 #include <sys/types.h>
31 #include <sys/strsubr.h>
32 #include <sys/stream.h>
33 #include <sys/modctl.h>
34 #include <sys/strft.h>
35 #include <sys/strsun.h>
36 #include <sys/sysmacros.h>
40 typedef struct str_flags
{
42 const char *strf_name
;
43 const char *strf_descr
;
46 typedef struct str_types
{
47 const char *strt_name
;
49 const char *strt_descr
;
52 typedef struct ftblk_data
{
53 ftblk_t ft_data
; /* Copy of ftblk */
54 int ft_ix
; /* Index in event list */
55 boolean_t ft_in_evlist
; /* Iterating through evlist */
58 typedef void qprint_func(queue_t
*, queue_t
*);
59 typedef void sdprint_func(stdata_t
*, stdata_t
*);
61 #define SF(flag) flag, #flag
66 static const strflags_t qf
[] = {
67 { SF(QENAB
), "Queue is already enabled to run" },
68 { SF(QWANTR
), "Someone wants to read Q" },
69 { SF(QWANTW
), "Someone wants to write Q" },
70 { SF(QFULL
), "Q is considered full" },
71 { SF(QREADR
), "This is the reader (first) Q" },
72 { SF(QUSE
), "This queue in use (allocation)" },
73 { SF(QNOENB
), "Don't enable Q via putq" },
74 { SF(QWANTRMQSYNC
), "Want to remove sync stream Q" },
75 { SF(QBACK
), "queue has been back-enabled" },
76 { SF(0x00000200), "unused (was QHLIST)" },
77 { SF(0x00000400), "unused (was QUNSAFE)" },
78 { SF(QPAIR
), "per queue-pair syncq" },
79 { SF(QPERQ
), "per queue-instance syncq" },
80 { SF(QPERMOD
), "per module syncq" },
81 { SF(QMTSAFE
), "stream module is MT-safe" },
82 { SF(QMTOUTPERIM
), "Has outer perimeter" },
83 { SF(QINSERVICE
), "service routine executing" },
84 { SF(QWCLOSE
), "will not be enabled" },
85 { SF(QEND
), "last queue in stream" },
86 { SF(QWANTWSYNC
), "Streamhead wants to write Q" },
87 { SF(QSYNCSTR
), "Q supports Synchronous STREAMS" },
88 { SF(QISDRV
), "the Queue is attached to a driver" },
89 { SF(0x00400000), "unused (was QHOT)" },
90 { SF(0x00800000), "unused (was QNEXTHOT)" },
91 { SF(0x01000000), "unused (was _QNEXTLESS)" },
92 { SF(0x02000000), "unused" },
93 { SF(_QINSERTING
), "module is inserted with _I_INSERT" },
94 { SF(_QREMOVING
) "module is removed with _I_REMOVE" },
95 { SF(_QASSOCIATED
), "queue is associated with a device" },
102 static const struct str_flags sqf
[] = {
103 { SF(SQ_EXCL
), "Exclusive access to inner perimeter" },
104 { SF(SQ_BLOCKED
), "qprocsoff in progress" },
105 { SF(SQ_FROZEN
), "freezestr in progress" },
106 { SF(SQ_WRITER
), "qwriter(OUTER) pending or running" },
107 { SF(SQ_MESSAGES
), "There are messages on syncq" },
108 { SF(SQ_WANTWAKEUP
) "Thread waiting on sq_wait" },
109 { SF(SQ_WANTEXWAKEUP
), "Thread waiting on sq_exwait" },
110 { SF(SQ_EVENTS
), "There are events on syncq" },
117 static const struct str_flags sqt
[] = {
118 { SF(SQ_CIPUT
), "Concurrent inner put procedure" },
119 { SF(SQ_CISVC
), "Concurrent inner svc procedure" },
120 { SF(SQ_CIOC
), "Concurrent inner open/close" },
121 { SF(SQ_CICB
), "Concurrent inner callback" },
122 { SF(SQ_COPUT
), "Concurrent outer put procedure" },
123 { SF(SQ_COSVC
), "Concurrent outer svc procedure" },
124 { SF(SQ_COOC
), "Concurrent outer open/close" },
125 { SF(SQ_COCB
), "Concurrent outer callback" },
132 static const struct str_flags stdf
[] = {
133 { SF(IOCWAIT
), "someone is doing an ioctl" },
134 { SF(RSLEEP
), "someone wants to read/recv msg" },
135 { SF(WSLEEP
), "someone wants to write" },
136 { SF(STRPRI
), "an M_PCPROTO is at stream head" },
137 { SF(STRHUP
), "device has vanished" },
138 { SF(STWOPEN
), "waiting for 1st open" },
139 { SF(STPLEX
), "stream is being multiplexed" },
140 { SF(STRISTTY
), "stream is a terminal" },
141 { SF(STRGETINPROG
), "(k)strgetmsg is running" },
142 { SF(IOCWAITNE
), "STR_NOERROR ioctl running" },
143 { SF(STRDERR
), "fatal read error from M_ERROR" },
144 { SF(STWRERR
), "fatal write error from M_ERROR" },
145 { SF(STRDERRNONPERSIST
), "nonpersistent read errors" },
146 { SF(STWRERRNONPERSIST
), "nonpersistent write errors" },
147 { SF(STRCLOSE
), "wait for a close to complete" },
148 { SF(SNDMREAD
), "used for read notification" },
149 { SF(OLDNDELAY
), "use old NDELAY TTY semantics" },
150 { SF(0x00020000), "unused" },
151 { SF(0x00040000), "unused" },
152 { SF(STRTOSTOP
), "block background writes" },
153 { SF(STRCMDWAIT
), "someone is doing an _I_CMD" },
154 { SF(0x00200000), "unused" },
155 { SF(STRMOUNT
), "stream is mounted" },
156 { SF(STRNOTATMARK
), "Not at mark (when empty read q)" },
157 { SF(STRDELIM
), "generate delimited messages" },
158 { SF(STRATMARK
), "at mark (due to MSGMARKNEXT)" },
159 { SF(STZCNOTIFY
), "wait for zerocopy mblk to be acked" },
160 { SF(STRPLUMB
), "stream plumbing changes in progress" },
161 { SF(STREOF
), "End-of-file indication" },
162 { SF(STREOPENFAIL
), "re-open has failed" },
163 { SF(STRMATE
), "this stream is a mate" },
164 { SF(STRHASLINKS
), "there are I_LINKs under this stream" },
168 static const struct str_flags mbf
[] = {
169 { SF(MSGMARK
), "last byte of message is marked" },
170 { SF(MSGNOLOOP
), "don't loop message to write side" },
171 { SF(MSGDELIM
), "message is delimited" },
172 { SF(0x08), "unused" },
173 { SF(MSGMARKNEXT
), "Private: b_next's first byte marked" },
174 { SF(MSGNOTMARKNEXT
), "Private: ... not marked" },
178 #define M_DATA_T 0xff
180 static const strtypes_t mbt
[] = {
181 { "M_DATA", M_DATA_T
, "regular data" },
182 { "M_PROTO", M_PROTO
, "protocol control" },
183 { "M_MULTIDATA", M_MULTIDATA
, "multidata" },
184 { "M_BREAK", M_BREAK
, "line break" },
185 { "M_PASSFP", M_PASSFP
, "pass file pointer" },
186 { "M_EVENT", M_EVENT
, "Obsoleted: do not use" },
187 { "M_SIG", M_SIG
, "generate process signal" },
188 { "M_DELAY", M_DELAY
, "real-time xmit delay" },
189 { "M_CTL", M_CTL
, "device-specific control message" },
190 { "M_IOCTL", M_IOCTL
, "ioctl; set/get params" },
191 { "M_SETOPTS", M_SETOPTS
, "set stream head options" },
192 { "M_RSE", M_RSE
, "reserved for RSE use only" },
193 { "M_IOCACK", M_IOCACK
, "acknowledge ioctl" },
194 { "M_IOCNAK", M_IOCNAK
, "negative ioctl acknowledge" },
195 { "M_PCPROTO", M_PCPROTO
, "priority proto message" },
196 { "M_PCSIG", M_PCSIG
, "generate process signal" },
197 { "M_READ", M_READ
, "generate read notification" },
198 { "M_FLUSH", M_FLUSH
, "flush your queues" },
199 { "M_STOP", M_STOP
, "stop transmission immediately" },
200 { "M_START", M_START
, "restart transmission after stop" },
201 { "M_HANGUP", M_HANGUP
, "line disconnect" },
202 { "M_ERROR", M_ERROR
, "send error to stream head" },
203 { "M_COPYIN", M_COPYIN
, "request to copyin data" },
204 { "M_COPYOUT", M_COPYOUT
, "request to copyout data" },
205 { "M_IOCDATA", M_IOCDATA
, "response to M_COPYIN and M_COPYOUT" },
206 { "M_PCRSE", M_PCRSE
, "reserved for RSE use only" },
207 { "M_STOPI", M_STOPI
, "stop reception immediately" },
208 { "M_STARTI", M_STARTI
, "restart reception after stop" },
209 { "M_PCEVENT", M_PCEVENT
, "Obsoleted: do not use" },
210 { "M_UNHANGUP", M_UNHANGUP
, "line reconnect" },
211 { "M_CMD", M_CMD
, "out-of-band ioctl command" },
215 /* Allocation flow trace events, starting from 0 */
216 static const char *ftev_alloc
[] = {
221 /* 4 */ "desballoca",
230 #define FTEV_PROC_START FTEV_PUT
232 /* Procedures recorded by flow tracing, starting from 0x100 */
233 static const char *ftev_proc
[] = {
251 static const char *db_control_types
[] = {
254 /* 02 */ "multidata",
272 static const char *db_control_hipri_types
[] = {
294 #define A_SIZE(a) (sizeof (a) / sizeof (a[0]))
296 static void ft_printevent(ushort_t
);
299 streams_parse_flag(const strflags_t ftable
[], const char *arg
, uint32_t *flag
)
303 for (i
= 0; ftable
[i
].strf_name
!= NULL
; i
++) {
304 if (strcasecmp(arg
, ftable
[i
].strf_name
) == 0) {
314 streams_flag_usage(const strflags_t ftable
[])
318 for (i
= 0; ftable
[i
].strf_name
!= NULL
; i
++)
319 mdb_printf("%-14s %s\n",
320 ftable
[i
].strf_name
, ftable
[i
].strf_descr
);
324 streams_parse_type(const strtypes_t ftable
[], const char *arg
, uint32_t *flag
)
328 for (i
= 0; ftable
[i
].strt_name
!= NULL
; i
++) {
329 if (strcasecmp(arg
, ftable
[i
].strt_name
) == 0) {
330 *flag
= ftable
[i
].strt_value
;
339 streams_type_usage(const strtypes_t ftable
[])
343 for (i
= 0; ftable
[i
].strt_name
!= NULL
; i
++)
344 mdb_printf("%-12s %s\n",
345 ftable
[i
].strt_name
, ftable
[i
].strt_descr
);
349 queue(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
351 const int QUEUE_FLGDELT
= (int)(sizeof (uintptr_t) * 2 + 15);
353 char name
[MODMAXNAMELEN
];
359 const char *mod
= NULL
, *flag
= NULL
, *not_flag
= NULL
;
360 uint_t quiet
= FALSE
;
361 uint_t verbose
= FALSE
;
362 uint32_t mask
= 0, not_mask
= 0;
363 uintptr_t syncq
= (uintptr_t)NULL
;
365 if (!(flags
& DCMD_ADDRSPEC
)) {
366 if (mdb_walk_dcmd("genunix`queue_cache", "genunix`queue",
368 mdb_warn("failed to walk queue cache");
374 if (flags
& DCMD_PIPE_OUT
)
377 if (mdb_getopts(argc
, argv
,
378 'v', MDB_OPT_SETBITS
, TRUE
, &verbose
,
379 'q', MDB_OPT_SETBITS
, TRUE
, &quiet
,
380 'm', MDB_OPT_STR
, &mod
,
381 'f', MDB_OPT_STR
, &flag
,
382 'F', MDB_OPT_STR
, ¬_flag
,
383 's', MDB_OPT_UINTPTR
, &syncq
,
388 * If any of the filtering flags is specified, don't print anything
389 * except the matching pointer.
391 if (flag
!= NULL
|| not_flag
!= NULL
|| mod
!= NULL
||
392 syncq
!= (uintptr_t)NULL
)
395 if (DCMD_HDRSPEC(flags
) && !quiet
) {
396 mdb_printf("%?s %-13s %6s %4s\n",
397 "ADDR", "MODULE", "FLAGS", "NBLK");
400 if (flag
!= NULL
&& streams_parse_flag(qf
, flag
, &mask
) == -1) {
401 mdb_warn("unrecognized queue flag '%s'\n", flag
);
402 streams_flag_usage(qf
);
406 if (not_flag
!= NULL
&&
407 streams_parse_flag(qf
, not_flag
, ¬_mask
) == -1) {
408 mdb_warn("unrecognized queue flag '%s'\n", flag
);
409 streams_flag_usage(qf
);
413 if (mdb_vread(&q
, sizeof (q
), addr
) == -1) {
414 mdb_warn("couldn't read queue at %p", addr
);
418 for (maddr
= (uintptr_t)q
.q_first
; maddr
!= (uintptr_t)NULL
; nblks
++) {
419 if (mdb_vread(&mblk
, sizeof (mblk
), maddr
) == -1) {
420 mdb_warn("couldn't read mblk %p for queue %p",
424 maddr
= (uintptr_t)mblk
.b_next
;
427 (void) mdb_qname(&q
, name
, sizeof (name
));
430 * If queue doesn't pass filtering criteria, don't print anything and
434 if (mod
!= NULL
&& strcmp(mod
, name
) != 0)
437 if (mask
!= 0 && !(q
.q_flag
& mask
))
440 if (not_mask
!= 0 && (q
.q_flag
& not_mask
))
443 if (syncq
!= 0 && q
.q_syncq
!= (syncq_t
*)syncq
)
447 * Options are specified for filtering, so If any option is specified on
448 * the command line, just print address and exit.
451 mdb_printf("%0?p\n", addr
);
455 mdb_printf("%0?p %-13s %06x %4d %0?p\n",
456 addr
, name
, q
.q_flag
, nblks
, q
.q_first
);
461 for (i
= 0; qf
[i
].strf_name
!= NULL
; i
++) {
462 if (!(q
.q_flag
& (1 << i
)))
465 mdb_printf("%*s|\n%*s+--> ",
466 QUEUE_FLGDELT
, "", QUEUE_FLGDELT
, "");
469 mdb_printf("%*s ", QUEUE_FLGDELT
, "");
471 mdb_printf("%-12s %s\n",
472 qf
[i
].strf_name
, qf
[i
].strf_descr
);
480 syncq(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
482 const int SYNC_FLGDELT
= (int)(sizeof (uintptr_t) * 2 + 1);
483 const int SYNC_TYPDELT
= (int)(sizeof (uintptr_t) * 2 + 5);
486 const char *flag
= NULL
, *not_flag
= NULL
;
487 const char *typ
= NULL
, *not_typ
= NULL
;
488 uint_t verbose
= FALSE
;
489 uint_t quiet
= FALSE
;
490 uint32_t mask
= 0, not_mask
= 0;
491 uint32_t tmask
= 0, not_tmask
= 0;
494 if (!(flags
& DCMD_ADDRSPEC
)) {
495 if (mdb_walk_dcmd("genunix`syncq_cache", "genunix`syncq",
497 mdb_warn("failed to walk syncq cache");
503 if (flags
& DCMD_PIPE_OUT
)
506 if (mdb_getopts(argc
, argv
,
507 'v', MDB_OPT_SETBITS
, TRUE
, &verbose
,
508 'q', MDB_OPT_SETBITS
, TRUE
, &quiet
,
509 'f', MDB_OPT_STR
, &flag
,
510 'F', MDB_OPT_STR
, ¬_flag
,
511 't', MDB_OPT_STR
, &typ
,
512 'T', MDB_OPT_STR
, ¬_typ
,
517 * If any of the filtering flags is specified, don't print anything
518 * except the matching pointer.
520 if (flag
!= NULL
|| not_flag
!= NULL
|| typ
!= NULL
|| not_typ
!= NULL
)
523 if (DCMD_HDRSPEC(flags
) && !quiet
) {
524 mdb_printf("%?s %s %s %s %s %?s %s %s\n",
525 "ADDR", "FLG", "TYP", "CNT", "NQS", "OUTER", "SF", "PRI");
528 if (flag
!= NULL
&& streams_parse_flag(sqf
, flag
, &mask
) == -1) {
529 mdb_warn("unrecognized syncq flag '%s'\n", flag
);
530 streams_flag_usage(sqf
);
534 if (typ
!= NULL
&& streams_parse_flag(sqt
, typ
, &tmask
) == -1) {
535 mdb_warn("unrecognized syncq type '%s'\n", typ
);
536 streams_flag_usage(sqt
);
540 if (not_flag
!= NULL
&& streams_parse_flag(sqf
, not_flag
, ¬_mask
)
542 mdb_warn("unrecognized syncq flag '%s'\n", not_flag
);
543 streams_flag_usage(sqf
);
547 if (not_typ
!= NULL
&& streams_parse_flag(sqt
, not_typ
, ¬_tmask
)
549 mdb_warn("unrecognized syncq type '%s'\n", not_typ
);
550 streams_flag_usage(sqt
);
554 if (mdb_vread(&sq
, sizeof (sq
), addr
) == -1) {
555 mdb_warn("couldn't read syncq at %p", addr
);
559 if (mask
!= 0 && !(sq
.sq_flags
& mask
))
562 if (not_mask
!= 0 && (sq
.sq_flags
& not_mask
))
565 sqtype
= (sq
.sq_type
>> 8) & 0xff;
567 if (tmask
!= 0 && !(sqtype
& tmask
))
570 if (not_tmask
!= 0 && (sqtype
& not_tmask
))
574 * Options are specified for filtering, so If any option is specified on
575 * the command line, just print address and exit.
578 mdb_printf("%0?p\n", addr
);
582 mdb_printf("%0?p %02x %02x %-3u %-3u %0?p %1x %-3d\n",
583 addr
, sq
.sq_flags
& 0xff, sqtype
, sq
.sq_count
,
584 sq
.sq_nqueues
, sq
.sq_outer
, sq
.sq_svcflags
, sq
.sq_pri
);
589 for (i
= 0; sqf
[i
].strf_name
!= NULL
; i
++) {
590 if (!(sq
.sq_flags
& (1 << i
)))
593 mdb_printf("%*s|\n%*s+--> ",
594 SYNC_FLGDELT
, "", SYNC_FLGDELT
, "");
597 mdb_printf("%*s ", SYNC_FLGDELT
, "");
599 mdb_printf("%-12s %s\n",
600 sqf
[i
].strf_name
, sqf
[i
].strf_descr
);
603 for (i
= 0; sqt
[i
].strf_name
!= NULL
; i
++) {
604 if (!(sqtype
& (1 << i
)))
607 mdb_printf("%*s|\n%*s+--> ",
608 SYNC_TYPDELT
, "", SYNC_TYPDELT
, "");
611 mdb_printf("%*s ", SYNC_TYPDELT
, "");
613 mdb_printf("%-12s %s\n",
614 sqt
[i
].strf_name
, sqt
[i
].strf_descr
);
622 stdata(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
624 const int STREAM_FLGDELT
= (int)(sizeof (uintptr_t) * 2 + 10);
628 const char *flag
= NULL
, *not_flag
= NULL
;
629 uint_t verbose
= FALSE
;
630 uint_t quiet
= FALSE
;
631 uint32_t mask
= 0, not_mask
= 0;
633 if (!(flags
& DCMD_ADDRSPEC
)) {
634 if (mdb_walk_dcmd("genunix`stream_head_cache",
635 "genunix`stdata", argc
, argv
) == -1) {
636 mdb_warn("failed to walk stream head cache");
642 if (flags
& DCMD_PIPE_OUT
)
645 if (mdb_getopts(argc
, argv
,
646 'v', MDB_OPT_SETBITS
, TRUE
, &verbose
,
647 'q', MDB_OPT_SETBITS
, TRUE
, &quiet
,
648 'f', MDB_OPT_STR
, &flag
,
649 'F', MDB_OPT_STR
, ¬_flag
,
654 * If any of the filtering flags is specified, don't print anything
655 * except the matching pointer.
657 if (flag
!= NULL
|| not_flag
!= NULL
)
660 if (DCMD_HDRSPEC(flags
) && !quiet
) {
661 mdb_printf("%?s %?s %8s %?s %s %s\n",
662 "ADDR", "WRQ", "FLAGS", "VNODE", "N/A", "REF");
665 if (flag
!= NULL
&& streams_parse_flag(stdf
, flag
, &mask
) == -1) {
666 mdb_warn("unrecognized stream flag '%s'\n", flag
);
667 streams_flag_usage(stdf
);
671 if (not_flag
!= NULL
&&
672 streams_parse_flag(stdf
, not_flag
, ¬_mask
) == -1) {
673 mdb_warn("unrecognized stream flag '%s'\n", flag
);
674 streams_flag_usage(stdf
);
678 if (mdb_vread(&sd
, sizeof (sd
), addr
) == -1) {
679 mdb_warn("couldn't read stdata at %p", addr
);
684 * If stream doesn't pass filtering criteria, don't print anything and
688 if (mask
!= 0 && !(sd
.sd_flag
& mask
))
691 if (not_mask
!= 0 && (sd
.sd_flag
& not_mask
))
695 * Options are specified for filtering, so If any option is specified on
696 * the command line, just print address and exit.
699 mdb_printf("%0?p\n", addr
);
703 mdb_printf("%0?p %0?p %08x %0?p %d/%d %d\n",
704 addr
, sd
.sd_wrq
, sd
.sd_flag
, sd
.sd_vnode
,
705 sd
.sd_pushcnt
, sd
.sd_anchor
, sd
.sd_refcnt
);
710 for (i
= 0; stdf
[i
].strf_name
!= NULL
; i
++) {
711 if (!(sd
.sd_flag
& (1 << i
)))
714 mdb_printf("%*s|\n%*s+--> ",
715 STREAM_FLGDELT
, "", STREAM_FLGDELT
, "");
718 mdb_printf("%*s ", STREAM_FLGDELT
, "");
720 mdb_printf("%-12s %s\n",
721 stdf
[i
].strf_name
, stdf
[i
].strf_descr
);
730 qprint_syncq(queue_t
*addr
, queue_t
*q
)
732 mdb_printf("%p\n", q
->q_syncq
);
737 qprint_stream(queue_t
*addr
, queue_t
*q
)
739 mdb_printf("%p\n", q
->q_stream
);
743 qprint_wrq(queue_t
*addr
, queue_t
*q
)
745 mdb_printf("%p\n", ((q
)->q_flag
& QREADR
? (addr
)+1: (addr
)));
749 qprint_rdq(queue_t
*addr
, queue_t
*q
)
751 mdb_printf("%p\n", ((q
)->q_flag
& QREADR
? (addr
): (addr
)-1));
755 qprint_otherq(queue_t
*addr
, queue_t
*q
)
757 mdb_printf("%p\n", ((q
)->q_flag
& QREADR
? (addr
)+1: (addr
)-1));
761 q2x(uintptr_t addr
, int argc
, qprint_func prfunc
)
768 if (mdb_vread(&q
, sizeof (q
), addr
) == -1) {
769 mdb_warn("couldn't read queue at %p", addr
);
773 prfunc((queue_t
*)addr
, &q
);
780 q2syncq(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
782 return (q2x(addr
, argc
, qprint_syncq
));
787 q2stream(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
789 return (q2x(addr
, argc
, qprint_stream
));
794 q2rdq(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
796 return (q2x(addr
, argc
, qprint_rdq
));
801 q2wrq(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
803 return (q2x(addr
, argc
, qprint_wrq
));
808 q2otherq(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
810 return (q2x(addr
, argc
, qprint_otherq
));
814 sd2x(uintptr_t addr
, int argc
, sdprint_func prfunc
)
821 if (mdb_vread(&sd
, sizeof (sd
), addr
) == -1) {
822 mdb_warn("couldn't read stream head at %p", addr
);
826 prfunc((stdata_t
*)addr
, &sd
);
833 sdprint_wrq(stdata_t
*addr
, stdata_t
*sd
)
835 mdb_printf("%p\n", sd
->sd_wrq
);
839 sdprint_mate(stdata_t
*addr
, stdata_t
*sd
)
841 mdb_printf("%p\n", sd
->sd_mate
? sd
->sd_mate
: addr
);
846 str2mate(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
848 return (sd2x(addr
, argc
, sdprint_mate
));
853 str2wrq(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
855 return (sd2x(addr
, argc
, sdprint_wrq
));
859 * If this syncq is a part of the queue pair structure, find the queue for it.
863 syncq2q(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
872 if (mdb_vread(&sq
, sizeof (sq
), addr
) == -1) {
873 mdb_warn("couldn't read syncq at %p", addr
);
877 /* Try to find its queue */
878 qp
= (queue_t
*)addr
- 2;
880 if ((mdb_vread(&q
, sizeof (q
), (uintptr_t)qp
) == -1) ||
881 (q
.q_syncq
!= (syncq_t
*)addr
)) {
882 mdb_warn("syncq2q: %p is not part of any queue\n", addr
);
885 mdb_printf("%p\n", qp
);
891 queue_walk_init(mdb_walk_state_t
*wsp
)
893 if (wsp
->walk_addr
== (uintptr_t)NULL
&&
894 mdb_readvar(&wsp
->walk_addr
, "qhead") == -1) {
895 mdb_warn("failed to read 'qhead'");
899 wsp
->walk_data
= mdb_alloc(sizeof (queue_t
), UM_SLEEP
);
904 queue_link_step(mdb_walk_state_t
*wsp
)
908 if (wsp
->walk_addr
== (uintptr_t)NULL
)
911 if (mdb_vread(wsp
->walk_data
, sizeof (queue_t
), wsp
->walk_addr
) == -1) {
912 mdb_warn("failed to read queue at %p", wsp
->walk_addr
);
916 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
919 wsp
->walk_addr
= (uintptr_t)(((queue_t
*)wsp
->walk_data
)->q_link
);
924 queue_next_step(mdb_walk_state_t
*wsp
)
928 if (wsp
->walk_addr
== (uintptr_t)NULL
)
931 if (mdb_vread(wsp
->walk_data
, sizeof (queue_t
), wsp
->walk_addr
) == -1) {
932 mdb_warn("failed to read queue at %p", wsp
->walk_addr
);
936 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
939 wsp
->walk_addr
= (uintptr_t)(((queue_t
*)wsp
->walk_data
)->q_next
);
944 queue_walk_fini(mdb_walk_state_t
*wsp
)
946 mdb_free(wsp
->walk_data
, sizeof (queue_t
));
950 str_walk_init(mdb_walk_state_t
*wsp
)
954 if (wsp
->walk_addr
== (uintptr_t)NULL
) {
955 mdb_warn("walk must begin at address of stdata_t\n");
959 if (mdb_vread(&s
, sizeof (s
), wsp
->walk_addr
) == -1) {
960 mdb_warn("failed to read stdata at %p", wsp
->walk_addr
);
964 wsp
->walk_addr
= (uintptr_t)s
.sd_wrq
;
965 wsp
->walk_data
= mdb_alloc(sizeof (queue_t
) * 2, UM_SLEEP
);
971 strr_walk_step(mdb_walk_state_t
*wsp
)
973 queue_t
*rq
= wsp
->walk_data
, *wq
= rq
+ 1;
976 if (wsp
->walk_addr
== (uintptr_t)NULL
)
979 if (mdb_vread(wsp
->walk_data
, sizeof (queue_t
) * 2,
980 wsp
->walk_addr
- sizeof (queue_t
)) == -1) {
981 mdb_warn("failed to read queue pair at %p",
982 wsp
->walk_addr
- sizeof (queue_t
));
986 status
= wsp
->walk_callback(wsp
->walk_addr
- sizeof (queue_t
),
987 rq
, wsp
->walk_cbdata
);
989 if (wq
->q_next
!= NULL
)
990 wsp
->walk_addr
= (uintptr_t)wq
->q_next
;
992 wsp
->walk_addr
= mdb_qwnext(wq
);
998 strw_walk_step(mdb_walk_state_t
*wsp
)
1000 queue_t
*rq
= wsp
->walk_data
, *wq
= rq
+ 1;
1003 if (wsp
->walk_addr
== (uintptr_t)NULL
)
1006 if (mdb_vread(wsp
->walk_data
, sizeof (queue_t
) * 2,
1007 wsp
->walk_addr
- sizeof (queue_t
)) == -1) {
1008 mdb_warn("failed to read queue pair at %p",
1009 wsp
->walk_addr
- sizeof (queue_t
));
1013 status
= wsp
->walk_callback(wsp
->walk_addr
, wq
, wsp
->walk_cbdata
);
1015 if (wq
->q_next
!= NULL
)
1016 wsp
->walk_addr
= (uintptr_t)wq
->q_next
;
1018 wsp
->walk_addr
= mdb_qwnext(wq
);
1024 str_walk_fini(mdb_walk_state_t
*wsp
)
1026 mdb_free(wsp
->walk_data
, sizeof (queue_t
) * 2);
1030 print_qpair(uintptr_t addr
, const queue_t
*q
, uint_t
*depth
)
1032 static const char box_lid
[] =
1033 "+-----------------------+-----------------------+\n";
1034 static const char box_sep
[] =
1037 char wname
[32], rname
[32], info1
[256], *info2
;
1040 mdb_printf(" | ^\n");
1041 mdb_printf(" v |\n");
1045 (void) mdb_qname(_WR(q
), wname
, sizeof (wname
));
1046 (void) mdb_qname(_RD(q
), rname
, sizeof (rname
));
1048 mdb_qinfo(_WR(q
), info1
, sizeof (info1
));
1049 if ((info2
= strchr(info1
, '\n')) != NULL
)
1054 mdb_printf(box_lid
);
1055 mdb_printf("| 0x%-19p | 0x%-19p | %s\n",
1056 addr
, addr
- sizeof (queue_t
), info1
);
1058 mdb_printf("| %<b>%-21s%</b> | %<b>%-21s%</b> |", wname
, rname
);
1059 mdb_flush(); /* Account for buffered terminal sequences */
1061 mdb_printf(" %s\n", info2
);
1062 mdb_printf(box_sep
);
1064 mdb_qinfo(_RD(q
), info1
, sizeof (info1
));
1065 if ((info2
= strchr(info1
, '\n')) != NULL
)
1070 mdb_printf("| cnt = 0t%-13lu | cnt = 0t%-13lu | %s\n",
1071 _WR(q
)->q_count
, _RD(q
)->q_count
, info1
);
1073 mdb_printf("| flg = 0x%08x | flg = 0x%08x | %s\n",
1074 _WR(q
)->q_flag
, _RD(q
)->q_flag
, info2
);
1076 mdb_printf(box_lid
);
1083 stream(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1085 uint_t d
= 0; /* Depth counter for print_qpair */
1087 if (argc
!= 0 || !(flags
& DCMD_ADDRSPEC
))
1088 return (DCMD_USAGE
);
1090 if (mdb_pwalk("writeq", (mdb_walk_cb_t
)print_qpair
, &d
, addr
) == -1) {
1091 mdb_warn("failed to walk writeq");
1099 mblk_walk_init(mdb_walk_state_t
*wsp
)
1101 wsp
->walk_data
= mdb_alloc(sizeof (mblk_t
), UM_SLEEP
);
1106 b_cont_step(mdb_walk_state_t
*wsp
)
1110 if (wsp
->walk_addr
== (uintptr_t)NULL
)
1113 if (mdb_vread(wsp
->walk_data
, sizeof (mblk_t
), wsp
->walk_addr
) == -1) {
1114 mdb_warn("failed to read mblk at %p", wsp
->walk_addr
);
1118 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
1121 wsp
->walk_addr
= (uintptr_t)(((mblk_t
*)wsp
->walk_data
)->b_cont
);
1126 b_next_step(mdb_walk_state_t
*wsp
)
1130 if (wsp
->walk_addr
== (uintptr_t)NULL
)
1133 if (mdb_vread(wsp
->walk_data
, sizeof (mblk_t
), wsp
->walk_addr
) == -1) {
1134 mdb_warn("failed to read mblk at %p", wsp
->walk_addr
);
1138 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
1141 wsp
->walk_addr
= (uintptr_t)(((mblk_t
*)wsp
->walk_data
)->b_next
);
1146 mblk_walk_fini(mdb_walk_state_t
*wsp
)
1148 mdb_free(wsp
->walk_data
, sizeof (mblk_t
));
1153 mblk2dblk(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1158 return (DCMD_USAGE
);
1160 if (mdb_vread(&mb
, sizeof (mb
), addr
) == -1) {
1161 mdb_warn("couldn't read mblk at %p", addr
);
1165 mdb_printf("%p\n", mb
.b_datap
);
1170 mblk_error(int *error
, uintptr_t addr
, char *message
)
1173 mdb_printf("%?lx: ", addr
);
1176 mdb_printf("%s", message
);
1181 mblk_verify(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1187 if (!(flags
& DCMD_ADDRSPEC
)) {
1188 if (mdb_walk_dcmd("streams_mblk", "mblk_verify", argc
, argv
) ==
1190 mdb_warn("can't walk mblk cache");
1196 if (mdb_vread(&mb
, sizeof (mblk_t
), addr
) == -1) {
1197 mdb_warn("can't read mblk_t at 0x%lx", addr
);
1201 if (mdb_vread(&db
, sizeof (dblk_t
), (uintptr_t)mb
.b_datap
) == -1) {
1202 mdb_warn("%?lx: invalid b_datap pointer\n", addr
);
1206 if (mb
.b_rptr
< db
.db_base
|| mb
.b_rptr
> db
.db_lim
)
1207 mblk_error(&error
, addr
, "b_rptr out of range");
1209 if (mb
.b_wptr
< db
.db_base
|| mb
.b_wptr
> db
.db_lim
)
1210 mblk_error(&error
, addr
, "b_wptr out of range");
1215 return (error
? DCMD_ERR
: DCMD_OK
);
1219 mblk_prt(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1221 const int MBLK_FLGDELT
= (int)(sizeof (uintptr_t) * 2 + 15);
1227 uint64_t len
= ~0UL;
1228 uint64_t glen
= ~0UL;
1229 uint64_t llen
= ~0UL;
1230 uint64_t blen
= ~0UL;
1232 const char *flag
= NULL
, *not_flag
= NULL
;
1233 const char *typ
= NULL
, *not_typ
= NULL
;
1234 uintptr_t dbaddr
= (uintptr_t)NULL
;
1235 uint32_t tmask
= 0, not_tmask
= 0;
1236 uint32_t mask
= 0, not_mask
= 0;
1237 uint_t quiet
= FALSE
;
1238 uint_t verbose
= FALSE
;
1240 if (!(flags
& DCMD_ADDRSPEC
)) {
1241 if (mdb_walk_dcmd("genunix`streams_mblk", "genunix`mblk",
1242 argc
, argv
) == -1) {
1243 mdb_warn("failed to walk mblk cache");
1249 if (flags
& DCMD_PIPE_OUT
)
1252 if (mdb_getopts(argc
, argv
,
1253 'v', MDB_OPT_SETBITS
, TRUE
, &verbose
,
1254 'q', MDB_OPT_SETBITS
, TRUE
, &quiet
,
1255 'f', MDB_OPT_STR
, &flag
,
1256 'F', MDB_OPT_STR
, ¬_flag
,
1257 't', MDB_OPT_STR
, &typ
,
1258 'T', MDB_OPT_STR
, ¬_typ
,
1259 'l', MDB_OPT_UINT64
, &len
,
1260 'L', MDB_OPT_UINT64
, &llen
,
1261 'G', MDB_OPT_UINT64
, &glen
,
1262 'b', MDB_OPT_UINT64
, &blen
,
1263 'd', MDB_OPT_UINTPTR
, &dbaddr
,
1265 return (DCMD_USAGE
);
1268 * If any of the filtering flags is specified, don't print anything
1269 * except the matching pointer.
1271 if ((flag
!= NULL
) || (not_flag
!= NULL
) || (typ
!= NULL
) ||
1272 (not_typ
!= NULL
) || (len
!= ~0UL) || (glen
!= ~0UL) ||
1273 (llen
!= ~0UL) || (blen
!= ~0UL) || (dbaddr
!= (uintptr_t)NULL
))
1276 if (flag
!= NULL
&& streams_parse_flag(mbf
, flag
, &mask
) == -1) {
1277 mdb_warn("unrecognized mblk flag '%s'\n", flag
);
1278 streams_flag_usage(mbf
);
1279 return (DCMD_USAGE
);
1282 if (not_flag
!= NULL
&&
1283 streams_parse_flag(mbf
, not_flag
, ¬_mask
) == -1) {
1284 mdb_warn("unrecognized mblk flag '%s'\n", flag
);
1285 streams_flag_usage(mbf
);
1286 return (DCMD_USAGE
);
1289 if (typ
!= NULL
&& streams_parse_type(mbt
, typ
, &tmask
) == -1) {
1290 mdb_warn("unrecognized dblk type '%s'\n", typ
);
1291 streams_type_usage(mbt
);
1292 return (DCMD_USAGE
);
1295 if (not_typ
!= NULL
&& streams_parse_type(mbt
, not_typ
, ¬_tmask
)
1297 mdb_warn("unrecognized dblk type '%s'\n", not_typ
);
1298 streams_type_usage(mbt
);
1299 return (DCMD_USAGE
);
1302 if (DCMD_HDRSPEC(flags
) && !quiet
) {
1303 mdb_printf("%?s %2s %-7s %-5s %-5s %?s %?s\n",
1304 "ADDR", "FL", "TYPE", "LEN", "BLEN", "RPTR", "DBLK");
1307 if (mdb_vread(&mblk
, sizeof (mblk
), addr
) == -1) {
1308 mdb_warn("couldn't read mblk at %p", addr
);
1311 b_flag
= mblk
.b_flag
;
1313 if (mask
!= 0 && !(b_flag
& mask
))
1316 if (not_mask
!= 0 && (b_flag
& not_mask
))
1319 if (mdb_vread(&dblk
, sizeof (dblk
), (uintptr_t)(mblk
.b_datap
)) == -1) {
1320 mdb_warn("couldn't read dblk at %p/%p", addr
, mblk
.b_datap
);
1323 db_type
= dblk
.db_type
;
1325 /* M_DATA is 0, so tmask has special value 0xff for it */
1327 if ((tmask
== M_DATA_T
&& db_type
!= M_DATA
) ||
1328 (tmask
!= M_DATA_T
&& db_type
!= tmask
))
1332 if (not_tmask
!= 0) {
1333 if ((not_tmask
== M_DATA_T
&& db_type
== M_DATA
) ||
1334 (db_type
== not_tmask
))
1338 if (dbaddr
!= (uintptr_t)NULL
&& (uintptr_t)mblk
.b_datap
!= dbaddr
)
1341 mblklen
= MBLKL(&mblk
);
1343 if ((len
!= ~0UL) && (len
!= mblklen
))
1346 if ((llen
!= ~0Ul) && (mblklen
> (int)llen
))
1349 if ((glen
!= ~0Ul) && (mblklen
< (int)glen
))
1352 if ((blen
!= ~0UL) && (blen
!= (dblk
.db_lim
- dblk
.db_base
)))
1356 * Options are specified for filtering, so If any option is specified on
1357 * the command line, just print address and exit.
1360 mdb_printf("%0?p\n", addr
);
1364 /* Figure out symbolic DB_TYPE */
1365 if (db_type
< A_SIZE(db_control_types
)) {
1366 dbtype
= db_control_types
[db_type
];
1369 * Must be a high-priority message -- adjust so that
1370 * "QPCTL + 1" corresponds to db_control_hipri_types[0]
1372 db_type
-= (QPCTL
+ 1);
1373 if (db_type
>= 0 && db_type
< A_SIZE(db_control_hipri_types
))
1374 dbtype
= db_control_hipri_types
[db_type
];
1379 mdb_printf("%0?p %-2x %-7s %-5d %-5d %0?p %0?p\n",
1380 addr
, b_flag
, dbtype
, mblklen
, dblk
.db_lim
- dblk
.db_base
,
1381 mblk
.b_rptr
, mblk
.b_datap
);
1386 for (i
= 0; mbf
[i
].strf_name
!= NULL
; i
++) {
1387 if (!(b_flag
& (1 << i
)))
1390 mdb_printf("%*s|\n%*s+--> ",
1391 MBLK_FLGDELT
, "", MBLK_FLGDELT
, "");
1394 mdb_printf("%*s ", MBLK_FLGDELT
, "");
1396 mdb_printf("%-12s %s\n",
1397 mbf
[i
].strf_name
, mbf
[i
].strf_descr
);
1404 * Streams flow trace walkers.
1408 strftblk_walk_init(mdb_walk_state_t
*wsp
)
1413 /* Get the dblock from the address */
1414 if (mdb_vread(&db
, sizeof (dblk_t
), wsp
->walk_addr
) == -1) {
1415 mdb_warn("failed to read dblk at %p", wsp
->walk_addr
);
1419 /* Is there any flow trace data? */
1420 if (db
.db_fthdr
== NULL
) {
1424 wsp
->walk_addr
= (uintptr_t)((char *)db
.db_fthdr
+
1425 offsetof(fthdr_t
, first
));
1427 ftd
= mdb_alloc(sizeof (ftblkdata_t
), UM_SLEEP
);
1429 ftd
->ft_in_evlist
= B_FALSE
;
1430 wsp
->walk_data
= ftd
;
1436 strftblk_step(mdb_walk_state_t
*wsp
)
1440 int status
= WALK_NEXT
;
1442 if (wsp
->walk_addr
== (uintptr_t)NULL
)
1445 ftd
= (ftblkdata_t
*)wsp
->walk_data
;
1446 ftbp
= &(ftd
->ft_data
);
1448 if (! ftd
->ft_in_evlist
) {
1449 /* Read a new ft block */
1450 if (mdb_vread(ftbp
, sizeof (ftblk_t
),
1451 wsp
->walk_addr
) == -1) {
1452 mdb_warn("failed to read ftblk at %p", wsp
->walk_addr
);
1456 * Check correctness of the index field.
1458 if (ftbp
->ix
< 0 || ftbp
->ix
> FTBLK_EVNTS
) {
1459 mdb_warn("ftblk: incorrect index value %i\n", ftbp
->ix
);
1463 ftd
->ft_in_evlist
= B_TRUE
;
1466 if (ftd
->ft_ix
> ftbp
->ix
) {
1467 ftd
->ft_in_evlist
= B_FALSE
;
1468 /* End of event list reached - move to the next event block */
1469 wsp
->walk_addr
= (uintptr_t)ftbp
->nxt
;
1471 /* Print event address */
1472 status
= wsp
->walk_callback((uintptr_t)((char *)wsp
->walk_addr
+
1473 offsetof(ftblk_t
, ev
) +
1474 (ftd
->ft_ix
- 1) * sizeof (struct ftevnt
)),
1475 wsp
->walk_data
, wsp
->walk_cbdata
);
1483 strftblk_walk_fini(mdb_walk_state_t
*wsp
)
1485 mdb_free(wsp
->walk_data
, sizeof (ftblkdata_t
));
1489 getqname(const void *nameptr
, char *buf
, uint_t bufsize
)
1493 if (mdb_readstr(buf
, bufsize
, (uintptr_t)nameptr
) == -1)
1497 * Sanity-check the name we read. This is needed because the pointer
1498 * value may have been recycled for some other purpose in the kernel
1499 * (e.g., if the STREAMS module was unloaded).
1501 for (cp
= buf
; *cp
!= '\0'; cp
++) {
1507 return (strncpy(buf
, "?", bufsize
));
1512 strftevent(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1517 char name
[FMNAMESZ
+ 1];
1518 boolean_t havestk
= B_FALSE
;
1520 if (!(flags
& DCMD_ADDRSPEC
))
1521 return (DCMD_USAGE
);
1523 if (DCMD_HDRSPEC(flags
)) {
1524 mdb_printf("%?s %-18s %-9s %-18s %4s %s\n",
1525 "ADDR", "Q/CALLER", "QNEXT", "STACK", "DATA", "EVENT");
1528 if (mdb_vread(&ev
, sizeof (ev
), addr
) == -1) {
1529 mdb_warn("couldn't read struct ftevnt at %p", addr
);
1533 mdb_printf("%0?p", addr
);
1535 if (ev
.evnt
& FTEV_QMASK
)
1536 mdb_printf(" %-18s", getqname(ev
.mid
, name
, sizeof (name
)));
1538 mdb_printf(" %-18a", ev
.mid
);
1540 if ((ev
.evnt
& FTEV_MASK
) == FTEV_PUTNEXT
)
1541 mdb_printf(" %-9s", getqname(ev
.midnext
, name
, sizeof (name
)));
1543 mdb_printf(" %-9s", "--");
1545 if (ev
.stk
== NULL
) {
1546 mdb_printf(" %-18s", "--");
1547 } else if (mdb_vread(&stk
, sizeof (stk
), (uintptr_t)ev
.stk
) == -1) {
1548 mdb_printf(" %-18s", "?");
1550 mdb_printf(" %-18a", stk
.fs_stk
[0]);
1554 mdb_printf(" %4x", ev
.data
);
1555 ft_printevent(ev
.evnt
);
1559 for (i
= 1; i
< stk
.fs_depth
; i
++) {
1560 mdb_printf("%?s %-18s %-9s %-18a\n", "", "", "",
1569 ft_printevent(ushort_t ev
)
1571 ushort_t proc_ev
= (ev
& (FTEV_PROC_START
| 0xFF)) - FTEV_PROC_START
;
1572 ushort_t alloc_ev
= ev
& FTEV_CALLER
;
1574 /* Get event class first */
1575 if (ev
& FTEV_PROC_START
) {
1576 if (proc_ev
>= A_SIZE(ftev_proc
))
1577 mdb_printf(" undefined");
1579 mdb_printf(" %s", ftev_proc
[proc_ev
]);
1580 } else if (alloc_ev
>= A_SIZE(ftev_alloc
)) {
1581 mdb_printf(" undefined");
1583 mdb_printf(" %s", ftev_alloc
[alloc_ev
]);
1586 /* Print event modifiers, if any */
1587 if (ev
& (FTEV_PS
| FTEV_CS
| FTEV_ISWR
)) {
1599 * Help functions for STREAMS debugging facilities.
1604 mdb_printf("Print queue information for a given queue pointer.\n"
1605 "\nWithout the address of a \"queue_t\" structure given, print "
1606 "information about all\n"
1607 "queues in the \"queue_cache\".\n\n"
1609 " -v:\t\tbe verbose - print symbolic flags falues\n"
1610 " -q:\t\tbe quiet - print queue pointer only\n"
1611 " -f flag:\tprint only queues with flag set\n"
1612 " -F flag:\tprint only queues with flag NOT set\n"
1613 " -m modname:\tprint only queues with specified module name\n"
1614 " -s syncq_addr:\tprint only queues which use specified syncq\n\n"
1615 "Available conversions:\n"
1616 " q2rdq: given a queue addr print read queue pointer\n"
1617 " q2wrq: given a queue addr print write queue pointer\n"
1618 " q2otherq: given a queue addr print other queue pointer\n"
1619 " q2syncq: given a queue addr print syncq pointer"
1621 " q2stream: given a queue addr print its stream pointer\n"
1622 "\t\t(see ::help stream and ::help stdata)\n\n"
1623 "To walk q_next pointer of the queue use\n"
1624 " queue_addr::walk qnext\n");
1630 mdb_printf("Print syncq information for a given syncq pointer.\n"
1631 "\nWithout the address of a \"syncq_t\" structure given, print "
1632 "information about all\n"
1633 "syncqs in the \"syncq_cache\".\n\n"
1635 " -v:\t\tbe verbose - print symbolic flags falues\n"
1636 " -q:\t\tbe quiet - print syncq pointer only\n"
1637 " -f flag:\tprint only syncqs with flag set\n"
1638 " -F flag:\tprint only syncqs with flag NOT set\n"
1639 " -t type:\tprint only syncqs with specified type\n"
1640 " -T type:\tprint only syncqs with do NOT have specified type\n\n"
1641 "Available conversions:\n"
1642 " syncq2q:\tgiven a syncq addr print queue address of the\n"
1643 "\t\t\tenclosing queue, if it is part of a queue\n\n"
1644 "See also: \"::help queue\" and \"::help stdata\"\n");
1650 mdb_printf("Print stdata information for a given stdata pointer.\n"
1651 "\nWithout the address of a \"stdata_t\" structure given, print "
1652 "information about all\n"
1653 "stream head pointers from the \"stream_head_cache\".\n\n"
1655 " ADDR:\tstream head address\n"
1656 " WRQ:\twrite queue pointer\n"
1657 " FLAGS:\tstream head flags (use -v to show in symbolic form)\n"
1658 " VNODE:\tstream vnode pointer\n"
1659 " N/A:\tpushcount and anchor positions\n"
1660 " REF:\tstream head reference counter\n\n"
1662 " -v:\t\tbe verbose - print symbolic flags falues\n"
1663 " -q:\t\tbe quiet - print stdata pointer only\n"
1664 " -f flag:\tprint only stdatas with flag set\n"
1665 " -F flag:\tprint only stdatas with flag NOT set\n\n"
1666 "Available conversions:\n"
1667 " str2mate:\tgiven a stream head addr print its mate\n"
1668 " str2wrq:\tgiven a stream head addr print its write queue\n\n"
1669 "See also: \"::help queue\" and \"::help syncq\"\n");
1675 mdb_printf("Print mblock information for a given mblk pointer.\n"
1676 "Without the address, print information about all mblocks.\n\n"
1678 " ADDR:\tmblk address\n"
1680 " TYPE:\tType of corresponding dblock\n"
1681 " LEN:\tData length as b_wptr - b_rptr\n"
1682 " BLEN:\tDblock space as db_lim - db_base\n"
1683 " RPTR:\tRead pointer\n"
1684 " DBLK:\tDblock pointer\n\n"
1686 " -v:\t\tbe verbose - print symbolic flags falues\n"
1687 " -q:\t\tbe quiet - print mblk pointer only\n"
1688 " -d dbaddr:\t\tprint mblks with specified dblk address\n"
1689 " -f flag:\tprint only mblks with flag set\n"
1690 " -F flag:\tprint only mblks with flag NOT set\n"
1691 " -t type:\tprint only mblks of specified db_type\n"
1692 " -T type:\tprint only mblks other then the specified db_type\n"
1693 " -l len:\t\ttprint only mblks with MBLKL == len\n"
1694 " -L len:\t\tprint only mblks with MBLKL <= len \n"
1695 " -G len:\t\tprint only mblks with MBLKL >= len \n"
1696 " -b len:\t\tprint only mblks with db_lim - db_base == len\n"