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]
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <sys/mdb_modapi.h>
29 #include <fmd_trace.h>
30 #include <fmd_module.h>
31 #include <fmd_thread.h>
32 #include <fmd_ustat.h>
33 #include <fmd_event.h>
38 #include <fmd_timerq.h>
43 typedef struct trwalk_state
{
44 struct trwalk_state
*trw_next
;
45 fmd_tracebuf_t trw_data
;
48 const fmd_tracerec_t
*trw_stop
;
49 fmd_tracerec_t
*trw_xrec
;
52 typedef struct hashwalk_data
{
62 static int fmd_stat(uintptr_t, uint_t
, int, const mdb_arg_t
*);
63 static int fmd_ustat(uintptr_t, uint_t
, int, const mdb_arg_t
*);
66 trwalk_init(mdb_walk_state_t
*wsp
)
72 if (wsp
->walk_addr
!= NULL
) {
73 mdb_warn("fmd_trace only supports global walks\n");
77 if (mdb_readvar(&F
, "fmd") != sizeof (F
)) {
78 mdb_warn("failed to read fmd meta-data");
82 for (addr
= (uintptr_t)F
.d_thr_list
.l_next
; addr
!= NULL
;
83 addr
= (uintptr_t)thr
.thr_list
.l_next
) {
85 size_t len
, ptr_off
, end_off
;
89 if (mdb_vread(&thr
, sizeof (thr
), addr
) != sizeof (thr
)) {
90 mdb_warn("failed to read thread at %p "
91 "(some trace data will be unavailable)", addr
);
95 t
= mdb_zalloc(sizeof (trwalk_state_t
), UM_SLEEP
);
96 t
->trw_next
= wsp
->walk_data
;
99 (void) mdb_vread(&t
->trw_data
,
100 sizeof (t
->trw_data
), (uintptr_t)thr
.thr_trdata
);
102 if (t
->trw_data
.tb_recs
== 0)
103 continue; /* no trace buffer allocated for thread */
105 len
= t
->trw_data
.tb_recs
* t
->trw_data
.tb_size
;
106 buf
= mdb_alloc(len
, UM_SLEEP
);
108 t
->trw_tid
= thr
.thr_tid
;
109 t
->trw_base
= (uintptr_t)t
->trw_data
.tb_buf
;
111 if (mdb_vread(buf
, len
, t
->trw_base
) == -1) {
112 mdb_warn("failed to read buffer for t%u", t
->trw_tid
);
116 end_off
= (uintptr_t)t
->trw_data
.tb_end
- t
->trw_base
;
117 ptr_off
= (uintptr_t)t
->trw_data
.tb_ptr
- t
->trw_base
;
119 t
->trw_data
.tb_buf
= buf
;
120 t
->trw_data
.tb_end
= (void *)((uintptr_t)buf
+ end_off
);
121 t
->trw_data
.tb_ptr
= (void *)((uintptr_t)buf
+ ptr_off
);
123 if (t
->trw_data
.tb_ptr
< t
->trw_data
.tb_buf
||
124 t
->trw_data
.tb_ptr
> t
->trw_data
.tb_end
) {
125 mdb_warn("trace record ptr for t%u is corrupt "
126 "(some data may be unavailable)\n", t
->trw_tid
);
127 t
->trw_data
.tb_ptr
= t
->trw_data
.tb_buf
;
130 t
->trw_stop
= t
->trw_data
.tb_ptr
;
131 t
->trw_xrec
= mdb_alloc(
132 t
->trw_data
.tb_size
+ sizeof (uintptr_t), UM_SLEEP
);
138 static fmd_tracerec_t
*
139 trwalk_nextrec(trwalk_state_t
*t
)
141 if (t
->trw_stop
== NULL
)
142 return (t
->trw_data
.tb_ptr
);
144 if (t
->trw_data
.tb_ptr
== t
->trw_data
.tb_buf
)
145 t
->trw_data
.tb_ptr
= t
->trw_data
.tb_end
;
147 t
->trw_data
.tb_ptr
= (fmd_tracerec_t
*)
148 ((uintptr_t)t
->trw_data
.tb_ptr
- t
->trw_data
.tb_size
);
150 if (t
->trw_data
.tb_ptr
== t
->trw_stop
)
151 t
->trw_stop
= NULL
; /* mark buffer as empty */
153 return (t
->trw_data
.tb_ptr
);
157 trwalk_step(mdb_walk_state_t
*wsp
)
159 trwalk_state_t
*t
, *oldest_t
;
160 hrtime_t oldest_time
= 0;
164 for (t
= wsp
->walk_data
; t
!= NULL
; t
= t
->trw_next
) {
165 for (trp
= t
->trw_data
.tb_ptr
; t
->trw_stop
!= NULL
&&
166 trp
->tr_time
== 0; trp
= trwalk_nextrec(t
))
169 if (t
->trw_stop
== NULL
)
170 continue; /* buffer has been emptied */
172 if (trp
->tr_time
> oldest_time
) {
173 oldest_time
= trp
->tr_time
;
178 if (oldest_time
== 0)
182 trp
= t
->trw_data
.tb_ptr
;
184 bcopy(trp
, t
->trw_xrec
, t
->trw_data
.tb_size
);
185 t
->trw_xrec
->tr_depth
= MIN(trp
->tr_depth
, t
->trw_data
.tb_frames
);
186 t
->trw_xrec
->tr_stack
[t
->trw_xrec
->tr_depth
] = t
->trw_tid
;
188 status
= wsp
->walk_callback((uintptr_t)trp
- (uintptr_t)
189 t
->trw_data
.tb_buf
+ t
->trw_base
, t
->trw_xrec
, wsp
->walk_cbdata
);
191 (void) trwalk_nextrec(t
);
196 trwalk_fini(mdb_walk_state_t
*wsp
)
198 trwalk_state_t
*t
, *u
;
200 for (t
= wsp
->walk_data
; t
!= NULL
; t
= u
) {
202 mdb_free(t
->trw_data
.tb_buf
,
203 t
->trw_data
.tb_recs
* t
->trw_data
.tb_size
);
204 mdb_free(t
->trw_xrec
, t
->trw_data
.tb_size
+ sizeof (uintptr_t));
205 mdb_free(t
, sizeof (trwalk_state_t
));
211 trprint_msg(uintptr_t addr
, const fmd_tracerec_t
*trp
, uintptr_t tid
)
214 mdb_printf("%3lu ", trp
->tr_stack
[trp
->tr_depth
]);
215 else if (trp
->tr_stack
[trp
->tr_depth
] != tid
)
218 mdb_printf("%016llx %04x %-5u %s\n",
219 trp
->tr_time
, 1 << trp
->tr_tag
, trp
->tr_errno
, trp
->tr_msg
);
226 trprint_cpp(uintptr_t addr
, const fmd_tracerec_t
*trp
, uintptr_t tid
)
231 mdb_printf("%3lu ", trp
->tr_stack
[trp
->tr_depth
]);
232 else if (trp
->tr_stack
[trp
->tr_depth
] != tid
)
235 if (mdb_readstr(file
, sizeof (file
), (uintptr_t)trp
->tr_file
) <= 0)
236 (void) strcpy(file
, "???");
238 mdb_printf("%016llx %04x %s: %u\n",
239 trp
->tr_time
, 1 << trp
->tr_tag
, file
, trp
->tr_line
);
245 trprint_stack(const fmd_tracerec_t
*trp
)
249 for (i
= 0; i
< trp
->tr_depth
; i
++)
250 mdb_printf("\t%a\n", trp
->tr_stack
[i
]);
252 if (trp
->tr_depth
!= 0)
257 trprint_msg_stack(uintptr_t addr
, const fmd_tracerec_t
*trp
, uintptr_t tid
)
259 int status
= trprint_msg(addr
, trp
, tid
);
265 trprint_cpp_stack(uintptr_t addr
, const fmd_tracerec_t
*trp
, uintptr_t tid
)
267 int status
= trprint_cpp(addr
, trp
, tid
);
273 fmd_trace(uintptr_t tid
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
275 int (*func
)(uintptr_t, const fmd_tracerec_t
*, uintptr_t);
276 uint_t opt_c
= FALSE
, opt_s
= FALSE
;
278 if (mdb_getopts(argc
, argv
,
279 'c', MDB_OPT_SETBITS
, TRUE
, &opt_c
,
280 's', MDB_OPT_SETBITS
, TRUE
, &opt_s
, NULL
) != argc
)
283 if (!(flags
& DCMD_ADDRSPEC
)) {
289 mdb_printf("%-16s %-4s FILE:LINE\n", "TIME", "TAG");
290 func
= opt_s
? trprint_cpp_stack
: trprint_cpp
;
292 mdb_printf("%-16s %-4s %-5s MSG\n", "TIME", "TAG", "ERRNO");
293 func
= opt_s
? trprint_msg_stack
: trprint_msg
;
296 if (mdb_walk("fmd_trace", (mdb_walk_cb_t
)func
, (void *)tid
) == -1) {
297 mdb_warn("failed to walk fmd_trace");
305 hash_walk_init(mdb_walk_state_t
*wsp
, uintptr_t addr
, uint_t hashlen
,
306 const char *name
, size_t size
, size_t next
)
308 hashwalk_data_t
*hwp
;
309 size_t len
= sizeof (uintptr_t) * hashlen
;
312 mdb_warn("failed to walk hash: invalid hash length\n");
316 hwp
= mdb_alloc(sizeof (hashwalk_data_t
), UM_SLEEP
);
317 hwp
->hw_hash
= mdb_zalloc(len
, UM_SLEEP
);
318 (void) mdb_vread(hwp
->hw_hash
, len
, addr
);
319 hwp
->hw_hashlen
= hashlen
;
322 hwp
->hw_data
= mdb_zalloc(size
, UM_SLEEP
);
326 wsp
->walk_addr
= hwp
->hw_hash
[0];
327 wsp
->walk_data
= hwp
;
333 hash_walk_step(mdb_walk_state_t
*wsp
)
335 hashwalk_data_t
*hwp
= wsp
->walk_data
;
338 while (wsp
->walk_addr
== NULL
) {
339 if (++hwp
->hw_hashidx
< hwp
->hw_hashlen
)
340 wsp
->walk_addr
= hwp
->hw_hash
[hwp
->hw_hashidx
];
345 if (mdb_vread(hwp
->hw_data
, hwp
->hw_size
, wsp
->walk_addr
) == -1) {
346 mdb_warn("failed to read %s at %p",
347 hwp
->hw_name
, wsp
->walk_addr
);
351 rv
= wsp
->walk_callback(wsp
->walk_addr
, hwp
->hw_data
, wsp
->walk_cbdata
);
352 wsp
->walk_addr
= *(uintptr_t *)((uintptr_t)hwp
->hw_data
+ hwp
->hw_next
);
357 hash_walk_fini(mdb_walk_state_t
*wsp
)
359 hashwalk_data_t
*hwp
= wsp
->walk_data
;
361 mdb_free(hwp
->hw_hash
, sizeof (uintptr_t) * hwp
->hw_hashlen
);
362 mdb_free(hwp
->hw_data
, hwp
->hw_size
);
363 mdb_free(hwp
, sizeof (hashwalk_data_t
));
367 ustat_walk_init(mdb_walk_state_t
*wsp
)
371 if (mdb_vread(&us
, sizeof (us
), wsp
->walk_addr
) != sizeof (us
)) {
372 mdb_warn("failed to read fmd_ustat_t at %p", wsp
->walk_addr
);
376 return (hash_walk_init(wsp
,
377 (uintptr_t)us
.us_hash
, us
.us_hashlen
, NULL
, 0, 0));
381 ustat_walk_step(mdb_walk_state_t
*wsp
)
383 hashwalk_data_t
*hwp
= wsp
->walk_data
;
387 while (wsp
->walk_addr
== NULL
) {
388 if (++hwp
->hw_hashidx
< hwp
->hw_hashlen
)
389 wsp
->walk_addr
= hwp
->hw_hash
[hwp
->hw_hashidx
];
394 if (mdb_vread(&ue
, sizeof (ue
), wsp
->walk_addr
) != sizeof (ue
) ||
395 mdb_vread(&s
, sizeof (s
), (uintptr_t)ue
.use_stat
) != sizeof (s
)) {
396 mdb_warn("failed to read stat element at %p", wsp
->walk_addr
);
400 wsp
->walk_addr
= (uintptr_t)ue
.use_next
;
402 return (wsp
->walk_callback(
403 (uintptr_t)ue
.use_stat
, &s
, wsp
->walk_cbdata
));
406 struct fmd_cmd_data
{
408 const mdb_arg_t
*argv
;
413 module_ustat(uintptr_t addr
, const void *data
, void *wsp
)
415 fmd_module_t
*modp
= (fmd_module_t
*)data
;
417 const struct fmd_cmd_data
*udp
= wsp
;
419 if (mdb_readstr(name
, sizeof (name
), (uintptr_t)modp
->mod_name
) <= 0)
420 (void) mdb_snprintf(name
, sizeof (name
), "<%p>",
422 mdb_printf("%s\n", name
);
423 (void) fmd_ustat((uintptr_t)modp
->mod_ustat
,
424 DCMD_ADDRSPEC
| DCMD_LOOPFIRST
, udp
->argc
, udp
->argv
);
429 fmd_ustat(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
431 if (!(flags
& DCMD_ADDRSPEC
)) {
432 struct fmd_cmd_data ud
;
436 if (mdb_walk("fmd_module", module_ustat
, &ud
) == -1) {
437 mdb_warn("failed to walk 'fmd_module'");
443 if (mdb_pwalk_dcmd("fmd_ustat", "fmd_stat", argc
, argv
, addr
) != 0) {
444 mdb_warn("failed to walk fmd_ustat at %p", addr
);
453 module_stat(uintptr_t addr
, const void *data
, void *wsp
)
455 fmd_module_t
*modp
= (fmd_module_t
*)data
;
457 const struct fmd_cmd_data
*udp
= wsp
;
458 fmd_modstat_t
*mod_stats
;
460 if (mdb_readstr(name
, sizeof (name
), (uintptr_t)modp
->mod_name
) <= 0) {
461 (void) mdb_snprintf(name
, sizeof (name
), "<%p>",
464 mdb_printf("%s\n", name
);
465 mod_stats
= modp
->mod_stats
;
466 (void) fmd_stat((uintptr_t)&mod_stats
->ms_loadtime
,
467 DCMD_ADDRSPEC
| DCMD_LOOPFIRST
, udp
->argc
, udp
->argv
);
468 (void) fmd_stat((uintptr_t)&mod_stats
->ms_snaptime
,
469 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
470 (void) fmd_stat((uintptr_t)&mod_stats
->ms_accepted
,
471 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
472 (void) fmd_stat((uintptr_t)&mod_stats
->ms_debugdrop
,
473 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
474 (void) fmd_stat((uintptr_t)&mod_stats
->ms_memtotal
,
475 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
476 (void) fmd_stat((uintptr_t)&mod_stats
->ms_memlimit
,
477 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
478 (void) fmd_stat((uintptr_t)&mod_stats
->ms_buftotal
,
479 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
480 (void) fmd_stat((uintptr_t)&mod_stats
->ms_buflimit
,
481 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
482 (void) fmd_stat((uintptr_t)&mod_stats
->ms_thrtotal
,
483 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
484 (void) fmd_stat((uintptr_t)&mod_stats
->ms_thrlimit
,
485 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
486 (void) fmd_stat((uintptr_t)&mod_stats
->ms_doorthrtotal
,
487 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
488 (void) fmd_stat((uintptr_t)&mod_stats
->ms_doorthrlimit
,
489 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
490 (void) fmd_stat((uintptr_t)&mod_stats
->ms_caseopen
,
491 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
492 (void) fmd_stat((uintptr_t)&mod_stats
->ms_casesolved
,
493 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
494 (void) fmd_stat((uintptr_t)&mod_stats
->ms_caseclosed
,
495 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
496 (void) fmd_stat((uintptr_t)&mod_stats
->ms_ckpt_save
,
497 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
498 (void) fmd_stat((uintptr_t)&mod_stats
->ms_ckpt_restore
,
499 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
500 (void) fmd_stat((uintptr_t)&mod_stats
->ms_ckpt_zeroed
,
501 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
502 (void) fmd_stat((uintptr_t)&mod_stats
->ms_ckpt_cnt
,
503 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
504 (void) fmd_stat((uintptr_t)&mod_stats
->ms_ckpt_time
,
505 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
506 (void) fmd_stat((uintptr_t)&mod_stats
->ms_xprtopen
,
507 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
508 (void) fmd_stat((uintptr_t)&mod_stats
->ms_xprtlimit
,
509 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
510 (void) fmd_stat((uintptr_t)&mod_stats
->ms_xprtqlimit
,
511 DCMD_ADDRSPEC
| DCMD_LOOP
, udp
->argc
, udp
->argv
);
517 fmd_stat(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
525 if (DCMD_HDRSPEC(flags
))
526 mdb_printf("%<u>%-11s %-4s %-32s %s%</u>\n",
527 "ADDR", "TYPE", "NAME", "VALUE");
529 if (!(flags
& DCMD_ADDRSPEC
)) {
530 struct fmd_cmd_data ud
;
535 if (mdb_walk("fmd_module", module_stat
, &ud
) == -1) {
536 mdb_warn("failed to walk 'fmd_module'");
542 if (mdb_vread(&s
, sizeof (s
), addr
) != sizeof (s
)) {
543 mdb_warn("failed to read statistic at %p", addr
);
547 switch (s
.fmds_type
) {
549 mdb_printf("%-11p %-4s %-32s %s\n", addr
, "bool",
550 s
.fmds_name
, s
.fmds_value
.bool ? "true" : "false");
553 mdb_printf("%-11p %-4s %-32s %d\n", addr
, "i32",
554 s
.fmds_name
, s
.fmds_value
.i32
);
556 case FMD_TYPE_UINT32
:
557 mdb_printf("%-11p %-4s %-32s %u\n", addr
, "ui32",
558 s
.fmds_name
, s
.fmds_value
.i32
);
561 mdb_printf("%-11p %-4s %-32s %lld\n", addr
, "i64",
562 s
.fmds_name
, s
.fmds_value
.i64
);
564 case FMD_TYPE_UINT64
:
565 mdb_printf("%-11p %-4s %-32s %llu\n", addr
, "ui64",
566 s
.fmds_name
, s
.fmds_value
.ui64
);
568 case FMD_TYPE_STRING
:
569 if (mdb_readstr(buf
, sizeof (buf
),
570 (uintptr_t)s
.fmds_value
.str
) < 0) {
571 (void) mdb_snprintf(buf
, sizeof (buf
), "<%p>",
574 mdb_printf("%-11p %-4s %-32s %s\n", addr
, "str",
578 mdb_printf("%-11p %-4s %-32s %llu\n", addr
, "time",
579 s
.fmds_name
, s
.fmds_value
.ui64
);
582 mdb_printf("%-11p %-4s %-32s %llu\n", addr
, "size",
583 s
.fmds_name
, s
.fmds_value
.ui64
);
586 mdb_printf("%-11p %-4u %-32s ???\n", addr
,
587 s
.fmds_type
, s
.fmds_name
);
596 fmd_event(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
598 char type
[16], name
[16];
604 if (mdb_vread(&ev
, sizeof (ev
), addr
) != sizeof (ev
)) {
605 mdb_warn("failed to read fmd_event at %p", addr
);
609 if (DCMD_HDRSPEC(flags
)) {
610 mdb_printf("%<u>%-11s %-4s %-5s %-3s %-?s%</u>\n",
611 "ADDR", "TYPE", "STATE", "REF", "NVPAIR");
614 switch (ev
.ev_type
) {
615 case FMD_EVT_PROTOCOL
:
616 (void) strcpy(type
, "PROT");
619 (void) strcpy(type
, "GC");
622 (void) strcpy(type
, "CLSE");
624 case FMD_EVT_TIMEOUT
:
625 (void) strcpy(type
, "TIME");
628 (void) strcpy(type
, "STAT");
630 case FMD_EVT_PUBLISH
:
631 (void) strcpy(type
, "PUBL");
634 (void) strcpy(type
, "TOPO");
637 (void) mdb_snprintf(type
, sizeof (type
), "%u", ev
.ev_type
);
640 switch (ev
.ev_state
) {
641 case FMD_EVS_RECEIVED
:
642 (void) strcpy(name
, "RECVD");
644 case FMD_EVS_ACCEPTED
:
645 (void) strcpy(name
, "ACCPT");
647 case FMD_EVS_DISCARDED
:
648 (void) strcpy(name
, "DSCRD");
650 case FMD_EVS_DIAGNOSED
:
651 (void) strcpy(name
, "DIAGN");
654 (void) mdb_snprintf(name
, sizeof (name
), "%u", ev
.ev_state
);
657 mdb_printf("%-11p %-4s %-5s %-3u %p\n",
658 addr
, type
, name
, ev
.ev_refs
, ev
.ev_nvl
);
664 thread_walk_init(mdb_walk_state_t
*wsp
)
668 if (mdb_readvar(&F
, "fmd") != sizeof (F
)) {
669 mdb_warn("failed to read fmd meta-data");
673 wsp
->walk_addr
= (uintptr_t)F
.d_thr_list
.l_next
;
678 thread_walk_step(mdb_walk_state_t
*wsp
)
680 uintptr_t addr
= wsp
->walk_addr
;
686 if (mdb_vread(&t
, sizeof (t
), addr
) != sizeof (t
)) {
687 mdb_warn("failed to read fmd_thread at %p", addr
);
691 wsp
->walk_addr
= (uintptr_t)t
.thr_list
.l_next
;
692 return (wsp
->walk_callback(addr
, &t
, wsp
->walk_cbdata
));
696 fmd_thread(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
700 if (!(flags
& DCMD_ADDRSPEC
))
701 return (mdb_walk_dcmd("fmd_thread", "fmd_thread", argc
, argv
));
706 if (mdb_vread(&thr
, sizeof (thr
), addr
) != sizeof (thr
)) {
707 mdb_warn("failed to read fmd_thread at %p", addr
);
711 if (DCMD_HDRSPEC(flags
)) {
712 mdb_printf("%<u>%-11s %-11s %-8s %-16s%</u>\n",
713 "ADDR", "MOD", "TID", "FUNC");
716 mdb_printf("%-11p %-11p %-8u %a\n",
717 addr
, thr
.thr_mod
, thr
.thr_tid
, thr
.thr_func
);
723 mod_walk_init(mdb_walk_state_t
*wsp
)
727 if (mdb_readvar(&F
, "fmd") != sizeof (F
)) {
728 mdb_warn("failed to read fmd meta-data");
732 wsp
->walk_addr
= (uintptr_t)F
.d_mod_list
.l_next
;
737 mod_walk_step(mdb_walk_state_t
*wsp
)
739 uintptr_t addr
= wsp
->walk_addr
;
745 if (mdb_vread(&m
, sizeof (m
), addr
) != sizeof (m
)) {
746 mdb_warn("failed to read fmd_module at %p", addr
);
750 wsp
->walk_addr
= (uintptr_t)m
.mod_list
.l_next
;
751 return (wsp
->walk_callback(addr
, &m
, wsp
->walk_cbdata
));
755 fmd_module(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
760 if (!(flags
& DCMD_ADDRSPEC
))
761 return (mdb_walk_dcmd("fmd_module", "fmd_module", argc
, argv
));
766 if (mdb_vread(&mod
, sizeof (mod
), addr
) != sizeof (mod
)) {
767 mdb_warn("failed to read fmd_module at %p", addr
);
771 if (DCMD_HDRSPEC(flags
)) {
772 mdb_printf("%<u>%-11s %-16s %-11s %-4s %-?s %-16s%</u>\n",
773 "ADDR", "OPS", "DATA", "FLAG", "USTAT", "NAME");
776 if (mdb_readstr(name
, sizeof (name
), (uintptr_t)mod
.mod_name
) <= 0)
777 (void) mdb_snprintf(name
, sizeof (name
), "<%p>", mod
.mod_name
);
779 mdb_printf("%-11p %-16a %-11p 0x%02x %-?p %s\n", addr
,
780 mod
.mod_ops
, mod
.mod_data
, mod
.mod_flags
, mod
.mod_ustat
, name
);
786 case_walk_init(mdb_walk_state_t
*wsp
)
792 if (wsp
->walk_addr
!= NULL
) {
793 if (mdb_vread(&mod
, sizeof (mod
), wsp
->walk_addr
) == -1) {
794 mdb_warn("failed to read module at %p", wsp
->walk_addr
);
798 wsp
->walk_addr
= (uintptr_t)mod
.mod_cases
.l_next
;
802 if (mdb_readvar(&F
, "fmd") != sizeof (F
) ||
803 mdb_vread(&ch
, sizeof (ch
), (uintptr_t)F
.d_cases
) != sizeof (ch
)) {
804 mdb_warn("failed to read fmd meta-data");
808 return (hash_walk_init(wsp
, (uintptr_t)ch
.ch_hash
, ch
.ch_hashlen
,
809 "fmd_case", sizeof (fmd_case_impl_t
),
810 OFFSETOF(fmd_case_impl_t
, ci_next
)));
814 case_walk_step(mdb_walk_state_t
*wsp
)
816 uintptr_t addr
= wsp
->walk_addr
;
819 if (wsp
->walk_data
!= NULL
)
820 return (hash_walk_step(wsp
));
825 if (mdb_vread(&ci
, sizeof (ci
), addr
) != sizeof (ci
)) {
826 mdb_warn("failed to read fmd_case at %p", addr
);
830 wsp
->walk_addr
= (uintptr_t)ci
.ci_list
.l_next
;
831 return (wsp
->walk_callback(addr
, &ci
, wsp
->walk_cbdata
));
835 case_walk_fini(mdb_walk_state_t
*wsp
)
837 if (wsp
->walk_data
!= NULL
)
842 fmd_case(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
844 char uuid
[48], name
[16];
847 if (!(flags
& DCMD_ADDRSPEC
)) {
848 if (mdb_walk_dcmd("fmd_case", "fmd_case", argc
, argv
) != 0) {
849 mdb_warn("failed to walk fmd_case hash");
855 if (mdb_vread(&ci
, sizeof (ci
), addr
) != sizeof (ci
)) {
856 mdb_warn("failed to read fmd_case at %p", addr
);
860 if (DCMD_HDRSPEC(flags
)) {
861 mdb_printf("%<u>%-11s %-5s %-3s %-?s %-36s%</u>\n",
862 "ADDR", "STATE", "REF", "DATA", "UUID");
865 if (mdb_readstr(uuid
, sizeof (uuid
), (uintptr_t)ci
.ci_uuid
) <= 0)
866 (void) mdb_snprintf(uuid
, sizeof (uuid
), "<%p>", ci
.ci_uuid
);
868 switch (ci
.ci_state
) {
869 case FMD_CASE_UNSOLVED
:
870 (void) strcpy(name
, "UNSLV");
872 case FMD_CASE_SOLVED
:
873 (void) strcpy(name
, "SOLVE");
875 case FMD_CASE_CLOSE_WAIT
:
876 (void) strcpy(name
, "CWAIT");
878 case FMD_CASE_CLOSED
:
879 (void) strcpy(name
, "CLOSE");
881 case FMD_CASE_REPAIRED
:
882 (void) strcpy(name
, "RPAIR");
884 case FMD_CASE_RESOLVED
:
885 (void) strcpy(name
, "RSLVD");
888 (void) mdb_snprintf(name
, sizeof (name
), "%u", ci
.ci_state
);
891 mdb_printf("%-11p %-5s %-3u %-?p %s\n",
892 addr
, name
, ci
.ci_refs
, ci
.ci_data
, uuid
);
898 buf_walk_init(mdb_walk_state_t
*wsp
)
902 if (mdb_vread(&bh
, sizeof (bh
), wsp
->walk_addr
) != sizeof (bh
)) {
903 mdb_warn("failed to read fmd_buf_hash_t at %p", wsp
->walk_addr
);
907 return (hash_walk_init(wsp
, (uintptr_t)bh
.bh_hash
, bh
.bh_hashlen
,
908 "fmd_buf", sizeof (fmd_buf_t
), OFFSETOF(fmd_buf_t
, buf_next
)));
913 fmd_buf(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
918 if (argc
!= 0 || !(flags
& DCMD_ADDRSPEC
))
921 if (mdb_vread(&b
, sizeof (b
), addr
) != sizeof (b
)) {
922 mdb_warn("failed to read fmd_buf at %p", addr
);
926 if (DCMD_HDRSPEC(flags
)) {
927 mdb_printf("%<u>%-11s %-32s %-5s %-?s %s%</u>\n",
928 "ADDR", "NAME", "FLAGS", "DATA", "SIZE");
931 if (mdb_readstr(name
, sizeof (name
), (uintptr_t)b
.buf_name
) <= 0)
932 (void) mdb_snprintf(name
, sizeof (name
), "<%p>", b
.buf_name
);
934 mdb_printf("%-11p %-32s %-#5x %-?p %lu\n",
935 addr
, name
, b
.buf_flags
, b
.buf_data
, b
.buf_size
);
941 serd_walk_init(mdb_walk_state_t
*wsp
)
945 if (mdb_vread(&sh
, sizeof (sh
), wsp
->walk_addr
) != sizeof (sh
)) {
946 mdb_warn("failed to read fmd_serd_hash at %p", wsp
->walk_addr
);
950 return (hash_walk_init(wsp
, (uintptr_t)sh
.sh_hash
, sh
.sh_hashlen
,
951 "fmd_serd_eng", sizeof (fmd_serd_eng_t
),
952 OFFSETOF(fmd_serd_eng_t
, sg_next
)));
957 module_serd(uintptr_t addr
, const void *data
, void *wsp
)
959 fmd_module_t
*modp
= (fmd_module_t
*)data
;
961 if (modp
->mod_serds
.sh_count
!= 0) {
962 modp
= (fmd_module_t
*)addr
;
963 (void) mdb_pwalk_dcmd("fmd_serd", "fmd_serd", 0, 0,
964 (uintptr_t)&modp
->mod_serds
);
971 fmd_serd(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
978 if (!(flags
& DCMD_ADDRSPEC
)) {
979 if (mdb_walk("fmd_module", module_serd
, 0) == -1) {
980 mdb_warn("failed to walk 'fmd_module'");
986 if (mdb_vread(&sg
, sizeof (sg
), addr
) != sizeof (sg
)) {
987 mdb_warn("failed to read fmd_serd_eng at %p", addr
);
991 if (DCMD_HDRSPEC(flags
)) {
992 mdb_printf("%<u>%-11s %-32s %-3s F >%-2s %-16s%</u>\n",
993 "ADDR", "NAME", "CNT", "N", "T");
996 if (mdb_readstr(name
, sizeof (name
), (uintptr_t)sg
.sg_name
) <= 0)
997 (void) mdb_snprintf(name
, sizeof (name
), "<%p>", sg
.sg_name
);
999 mdb_printf("%-11p %-32s %-3u %c >%-2u %lluns\n",
1000 addr
, name
, sg
.sg_count
, (sg
.sg_flags
& FMD_SERD_FIRED
) ? 'F' : ' ',
1001 sg
.sg_n
, (u_longlong_t
)sg
.sg_t
);
1007 asru_walk_init(mdb_walk_state_t
*wsp
)
1012 if (wsp
->walk_addr
== NULL
&& mdb_readvar(&F
, "fmd") != sizeof (F
)) {
1013 mdb_warn("failed to read fmd meta-data");
1017 if (wsp
->walk_addr
== NULL
)
1018 wsp
->walk_addr
= (uintptr_t)F
.d_asrus
;
1020 if (mdb_vread(&ah
, sizeof (ah
), wsp
->walk_addr
) != sizeof (ah
)) {
1021 mdb_warn("failed to read asru_hash at %p", wsp
->walk_addr
);
1025 return (hash_walk_init(wsp
, (uintptr_t)ah
.ah_hash
, ah
.ah_hashlen
,
1026 "fmd_asru", sizeof (fmd_asru_t
), OFFSETOF(fmd_asru_t
, asru_next
)));
1030 fmd_asru(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1032 char uuid
[48], name
[PATH_MAX
];
1035 if (!(flags
& DCMD_ADDRSPEC
)) {
1036 if (mdb_walk_dcmd("fmd_asru", "fmd_asru", argc
, argv
) != 0) {
1037 mdb_warn("failed to walk fmd_asru hash");
1043 if (mdb_vread(&a
, sizeof (a
), addr
) != sizeof (a
)) {
1044 mdb_warn("failed to read fmd_asru at %p", addr
);
1048 if (DCMD_HDRSPEC(flags
))
1049 mdb_printf("%<u>%-8s %-36s %s%</u>\n", "ADDR", "UUID", "NAME");
1051 if (mdb_readstr(uuid
, sizeof (uuid
), (uintptr_t)a
.asru_uuid
) <= 0)
1052 (void) mdb_snprintf(uuid
, sizeof (uuid
), "<%p>", a
.asru_uuid
);
1053 if (mdb_readstr(name
, sizeof (name
), (uintptr_t)a
.asru_name
) <= 0)
1054 (void) mdb_snprintf(name
, sizeof (name
), "<%p>", a
.asru_name
);
1056 mdb_printf("%-8p %-36s %s\n", addr
, uuid
, name
);
1061 al_walk_init(mdb_walk_state_t
*wsp
)
1066 if (wsp
->walk_addr
== NULL
&& mdb_readvar(&F
, "fmd") != sizeof (F
)) {
1067 mdb_warn("failed to read fmd meta-data");
1071 if (wsp
->walk_addr
== NULL
)
1072 wsp
->walk_addr
= (uintptr_t)F
.d_asrus
;
1074 if (mdb_vread(&ah
, sizeof (ah
), wsp
->walk_addr
) != sizeof (ah
)) {
1075 mdb_warn("failed to read asru_hash at %p", wsp
->walk_addr
);
1079 return (hash_walk_init(wsp
, (uintptr_t)ah
.ah_rsrc_hash
, ah
.ah_hashlen
,
1080 "fmd_asru_link", sizeof (fmd_asru_link_t
), OFFSETOF(fmd_asru_link_t
,
1085 fmd_asru_link(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1087 char uuid
[48], name
[PATH_MAX
];
1090 if (!(flags
& DCMD_ADDRSPEC
)) {
1091 if (mdb_walk_dcmd("fmd_asru_link", "fmd_asru_link", argc
,
1093 mdb_warn("failed to walk fmd_asru_link hash");
1099 if (mdb_vread(&a
, sizeof (a
), addr
) != sizeof (a
)) {
1100 mdb_warn("failed to read fmd_asru_link at %p", addr
);
1104 if (DCMD_HDRSPEC(flags
))
1105 mdb_printf("%<u>%-8s %-36s %s%</u>\n", "ADDR", "UUID", "NAME");
1107 if (mdb_readstr(uuid
, sizeof (uuid
), (uintptr_t)a
.al_uuid
) <= 0)
1108 (void) mdb_snprintf(uuid
, sizeof (uuid
), "<%p>", a
.al_uuid
);
1109 if (mdb_readstr(name
, sizeof (name
), (uintptr_t)a
.al_rsrc_name
) <= 0)
1110 (void) mdb_snprintf(name
, sizeof (name
), "<%p>",
1113 mdb_printf("%-8p %-36s %s\n", addr
, uuid
, name
);
1119 fcf_hdr(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1124 return (DCMD_USAGE
);
1126 if (!(flags
& DCMD_ADDRSPEC
))
1127 addr
= 0; /* assume base of file in file target */
1129 if (mdb_vread(&h
, sizeof (h
), addr
) != sizeof (h
)) {
1130 mdb_warn("failed to read header at %p", addr
);
1134 mdb_printf("fcfh_ident.id_magic = 0x%x, %c, %c, %c\n",
1135 h
.fcfh_ident
[FCF_ID_MAG0
], h
.fcfh_ident
[FCF_ID_MAG1
],
1136 h
.fcfh_ident
[FCF_ID_MAG2
], h
.fcfh_ident
[FCF_ID_MAG3
]);
1138 switch (h
.fcfh_ident
[FCF_ID_MODEL
]) {
1139 case FCF_MODEL_ILP32
:
1140 mdb_printf("fcfh_ident.id_model = ILP32\n");
1142 case FCF_MODEL_LP64
:
1143 mdb_printf("fcfh_ident.id_model = LP64\n");
1146 mdb_printf("fcfh_ident.id_model = 0x%x\n",
1147 h
.fcfh_ident
[FCF_ID_MODEL
]);
1150 switch (h
.fcfh_ident
[FCF_ID_ENCODING
]) {
1151 case FCF_ENCODE_LSB
:
1152 mdb_printf("fcfh_ident.id_encoding = LSB\n");
1154 case FCF_ENCODE_MSB
:
1155 mdb_printf("fcfh_ident.id_encoding = MSB\n");
1158 mdb_printf("fcfh_ident.id_encoding = 0x%x\n",
1159 h
.fcfh_ident
[FCF_ID_ENCODING
]);
1162 mdb_printf("fcfh_ident.id_version = %u\n",
1163 h
.fcfh_ident
[FCF_ID_VERSION
]);
1165 mdb_printf("fcfh_flags = 0x%x\n", h
.fcfh_flags
);
1166 mdb_printf("fcfh_hdrsize = %u\n", h
.fcfh_hdrsize
);
1167 mdb_printf("fcfh_secsize = %u\n", h
.fcfh_secsize
);
1168 mdb_printf("fcfh_secnum = %u\n", h
.fcfh_secnum
);
1169 mdb_printf("fcfh_secoff = %llu\n", h
.fcfh_secoff
);
1170 mdb_printf("fcfh_filesz = %llu\n", h
.fcfh_filesz
);
1171 mdb_printf("fcfh_cgen = %llu\n", h
.fcfh_cgen
);
1176 static int fcf_sec(uintptr_t, uint_t
, int, const mdb_arg_t
*);
1179 fcf_sec_one(uintptr_t addr
, void *ignored
, uint_t
*secp
)
1182 mdb_printf("%3d ", (*secp
)++);
1183 (void) fcf_sec(addr
, DCMD_ADDRSPEC
| DCMD_LOOP
, 0, NULL
);
1189 fcf_sec(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1191 static const char *const types
[] = {
1192 "none", /* FCF_SECT_NONE */
1193 "strtab", /* FCF_SECT_STRTAB */
1194 "module", /* FCF_SECT_MODULE */
1195 "case", /* FCF_SECT_CASE */
1196 "bufs", /* FCF_SECT_BUFS */
1197 "buffer", /* FCF_SECT_BUFFER */
1198 "serd", /* FCF_SECT_SERD */
1199 "events", /* FCF_SECT_EVENTS */
1200 "nvlists", /* FCF_SECT_NVLISTS */
1206 if (!(flags
& DCMD_ADDRSPEC
))
1207 mdb_printf("%<u>%-3s ", "NDX");
1209 if (!(flags
& DCMD_ADDRSPEC
) || DCMD_HDRSPEC(flags
)) {
1210 mdb_printf("%<u>%?s %-10s %-5s %-5s %-5s %-6s %-5s%</u>\n",
1211 "ADDR", "TYPE", "ALIGN", "FLAGS", "ENTSZ", "OFF", "SIZE");
1214 if (!(flags
& DCMD_ADDRSPEC
)) {
1215 if (mdb_walk("fcf_sec", (mdb_walk_cb_t
)fcf_sec_one
, &sec
) < 0) {
1216 mdb_warn("failed to walk fcf_sec");
1223 return (DCMD_USAGE
);
1225 if (mdb_vread(&s
, sizeof (s
), addr
) != sizeof (s
)) {
1226 mdb_warn("failed to read section header at %p", addr
);
1230 mdb_printf("%?p ", addr
);
1232 if (s
.fcfs_type
< sizeof (types
) / sizeof (types
[0]))
1233 mdb_printf("%-10s ", types
[s
.fcfs_type
]);
1235 mdb_printf("%-10u ", s
.fcfs_type
);
1237 mdb_printf("%-5u %-#5x %-#5x %-6llx %-#5llx\n", s
.fcfs_align
,
1238 s
.fcfs_flags
, s
.fcfs_entsize
, s
.fcfs_offset
, s
.fcfs_size
);
1244 fcf_sec_walk_init(mdb_walk_state_t
*wsp
)
1249 if (mdb_vread(&h
, sizeof (h
), wsp
->walk_addr
) != sizeof (h
)) {
1250 mdb_warn("failed to read FCF header at %p", wsp
->walk_addr
);
1254 size
= sizeof (fcf_hdr_t
) + sizeof (fcf_sec_t
) * h
.fcfh_secnum
;
1255 hp
= mdb_alloc(size
, UM_SLEEP
);
1257 if (mdb_vread(hp
, size
, wsp
->walk_addr
) != size
) {
1258 mdb_warn("failed to read FCF sections at %p", wsp
->walk_addr
);
1263 wsp
->walk_data
= hp
;
1270 fcf_sec_walk_step(mdb_walk_state_t
*wsp
)
1272 uint_t i
= (uint_t
)wsp
->walk_arg
;
1273 size_t off
= sizeof (fcf_hdr_t
) + sizeof (fcf_sec_t
) * i
;
1274 fcf_hdr_t
*hp
= wsp
->walk_data
;
1275 fcf_sec_t
*sp
= (fcf_sec_t
*)((uintptr_t)hp
+ off
);
1277 if (i
>= hp
->fcfh_secnum
)
1280 wsp
->walk_arg
= (void *)(i
+ 1);
1281 return (wsp
->walk_callback(wsp
->walk_addr
+ off
, sp
, wsp
->walk_cbdata
));
1285 fcf_sec_walk_fini(mdb_walk_state_t
*wsp
)
1287 fcf_hdr_t
*hp
= wsp
->walk_data
;
1288 mdb_free(hp
, sizeof (fcf_hdr_t
) + sizeof (fcf_sec_t
) * hp
->fcfh_secnum
);
1293 fcf_case(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1298 return (DCMD_USAGE
);
1300 if (mdb_vread(&fcfc
, sizeof (fcfc
), addr
) != sizeof (fcfc
)) {
1301 mdb_warn("failed to read case at %p", addr
);
1305 mdb_printf("fcfc_uuid = 0x%x\n", fcfc
.fcfc_uuid
);
1306 mdb_printf("fcfc_state = %u\n", fcfc
.fcfc_state
);
1307 mdb_printf("fcfc_bufs = %u\n", fcfc
.fcfc_bufs
);
1308 mdb_printf("fcfc_events = %u\n", fcfc
.fcfc_events
);
1309 mdb_printf("fcfc_suspects = %u\n", fcfc
.fcfc_suspects
);
1316 fcf_event(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1321 return (DCMD_USAGE
);
1323 if (mdb_vread(&fcfe
, sizeof (fcfe
), addr
) != sizeof (fcfe
)) {
1324 mdb_warn("failed to read event at %p", addr
);
1328 mdb_printf("fcfe_todsec = %llu (%Y)\n",
1329 fcfe
.fcfe_todsec
, (time_t)fcfe
.fcfe_todsec
);
1330 mdb_printf("fcfe_todnsec = %llu\n", fcfe
.fcfe_todnsec
);
1331 mdb_printf("fcfe_major = %u\n", fcfe
.fcfe_major
);
1332 mdb_printf("fcfe_minor = %u\n", fcfe
.fcfe_minor
);
1333 mdb_printf("fcfe_inode = %llu\n", fcfe
.fcfe_inode
);
1334 mdb_printf("fcfe_offset = %llu\n", fcfe
.fcfe_offset
);
1341 fcf_serd(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1346 return (DCMD_USAGE
);
1348 if (mdb_vread(&fcfd
, sizeof (fcfd
), addr
) != sizeof (fcfd
)) {
1349 mdb_warn("failed to read serd at %p", addr
);
1353 mdb_printf("fcfd_name = 0x%x\n", fcfd
.fcfd_name
);
1354 mdb_printf("fcfd_events = %u\n", fcfd
.fcfd_events
);
1355 mdb_printf("fcfd_n = >%u\n", fcfd
.fcfd_n
);
1356 mdb_printf("fcfd_t = %lluns\n", fcfd
.fcfd_t
);
1362 tmq_walk_init(mdb_walk_state_t
*wsp
)
1367 if (wsp
->walk_addr
== NULL
&& mdb_readvar(&F
, "fmd") != sizeof (F
)) {
1368 mdb_warn("failed to read fmd meta-data");
1372 if (wsp
->walk_addr
== NULL
)
1373 wsp
->walk_addr
= (uintptr_t)F
.d_timers
;
1375 if (mdb_vread(&tmq
, sizeof (tmq
), wsp
->walk_addr
) != sizeof (tmq
)) {
1376 mdb_warn("failed to read timerq at %p", wsp
->walk_addr
);
1380 wsp
->walk_addr
= (uintptr_t)tmq
.tmq_list
.l_next
;
1385 tmq_walk_step(mdb_walk_state_t
*wsp
)
1387 uintptr_t addr
= wsp
->walk_addr
;
1393 if (mdb_vread(&tmr
, sizeof (tmr
), addr
) != sizeof (tmr
)) {
1394 mdb_warn("failed to read fmd_timer at %p", addr
);
1398 wsp
->walk_addr
= (uintptr_t)tmr
.tmr_list
.l_next
;
1399 return (wsp
->walk_callback(addr
, &tmr
, wsp
->walk_cbdata
));
1403 fmd_timer(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1405 char name
[32], func
[MDB_SYM_NAMLEN
];
1408 if (!(flags
& DCMD_ADDRSPEC
)) {
1409 if (mdb_walk_dcmd("fmd_timerq", "fmd_timer", argc
, argv
) != 0) {
1410 mdb_warn("failed to walk fmd_timerq");
1416 if (mdb_vread(&t
, sizeof (t
), addr
) != sizeof (t
)) {
1417 mdb_warn("failed to read fmd_timer at %p", addr
);
1421 if (DCMD_HDRSPEC(flags
)) {
1422 mdb_printf("%<u>%-8s %-20s %-4s %-18s %-8s %s%</u>\n",
1423 "ADDR", "MODULE", "ID", "HRTIME", "ARG", "FUNC");
1426 if (mdb_readstr(name
, sizeof (name
), (uintptr_t)
1427 t
.tmr_ids
+ OFFSETOF(fmd_idspace_t
, ids_name
)) <= 0)
1428 (void) mdb_snprintf(name
, sizeof (name
), "<%p>", t
.tmr_ids
);
1430 if (mdb_lookup_by_addr((uintptr_t)t
.tmr_func
, MDB_SYM_FUZZY
,
1431 func
, sizeof (func
), NULL
) != 0)
1432 (void) mdb_snprintf(func
, sizeof (func
), "<%p>", t
.tmr_func
);
1434 mdb_printf("%-8p %-20s %4d 0x%-16llx %-8p %s\n",
1435 addr
, name
, t
.tmr_id
, t
.tmr_hrt
, t
.tmr_arg
, func
);
1440 xprt_walk_init(mdb_walk_state_t
*wsp
)
1444 if (wsp
->walk_addr
== NULL
) {
1445 mdb_warn("transport walker requires fmd_module_t address\n");
1449 if (mdb_vread(&m
, sizeof (m
), wsp
->walk_addr
) != sizeof (m
)) {
1450 mdb_warn("failed to read module at %p", wsp
->walk_addr
);
1454 wsp
->walk_addr
= (uintptr_t)m
.mod_transports
.l_next
;
1459 xprt_walk_step(mdb_walk_state_t
*wsp
)
1461 uintptr_t addr
= wsp
->walk_addr
;
1467 if (mdb_vread(&xi
, sizeof (xi
), addr
) != sizeof (xi
)) {
1468 mdb_warn("failed to read fmd_xprt at %p", addr
);
1472 wsp
->walk_addr
= (uintptr_t)xi
.xi_list
.l_next
;
1473 return (wsp
->walk_callback(addr
, &xi
, wsp
->walk_cbdata
));
1477 xpc_walk_init(mdb_walk_state_t
*wsp
)
1479 fmd_xprt_class_hash_t xch
;
1481 if (mdb_vread(&xch
, sizeof (xch
), wsp
->walk_addr
) != sizeof (xch
)) {
1482 mdb_warn("failed to read fmd_xprt_class_hash at %p",
1487 return (hash_walk_init(wsp
, (uintptr_t)xch
.xch_hash
, xch
.xch_hashlen
,
1488 "fmd_xprt_class", sizeof (fmd_xprt_class_t
),
1489 OFFSETOF(fmd_xprt_class_t
, xc_next
)));
1494 fmd_xprt_class(uintptr_t addr
, const void *data
, void *arg
)
1496 const fmd_xprt_class_t
*xcp
= data
;
1499 if (mdb_readstr(name
, sizeof (name
), (uintptr_t)xcp
->xc_class
) <= 0)
1500 (void) mdb_snprintf(name
, sizeof (name
), "<%p>", xcp
->xc_class
);
1502 mdb_printf("%-8p %-4u %s\n", addr
, xcp
->xc_refs
, name
);
1507 fmd_xprt(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1509 uint_t opt_s
= FALSE
, opt_l
= FALSE
, opt_r
= FALSE
, opt_u
= FALSE
;
1512 if (mdb_getopts(argc
, argv
,
1513 'l', MDB_OPT_SETBITS
, TRUE
, &opt_l
,
1514 'r', MDB_OPT_SETBITS
, TRUE
, &opt_r
,
1515 's', MDB_OPT_SETBITS
, TRUE
, &opt_s
,
1516 'u', MDB_OPT_SETBITS
, TRUE
, &opt_u
, NULL
) != argc
)
1517 return (DCMD_USAGE
);
1519 if (!(flags
& DCMD_ADDRSPEC
)) {
1520 if (mdb_walk_dcmd("fmd_xprt", "fmd_xprt", argc
, argv
) != 0) {
1521 mdb_warn("failed to walk fmd_xprt");
1527 if (mdb_vread(&xi
, sizeof (xi
), addr
) != sizeof (xi
)) {
1528 mdb_warn("failed to read fmd_xprt at %p", addr
);
1532 if (DCMD_HDRSPEC(flags
)) {
1533 mdb_printf("%<u>%-8s %-4s %-4s %-5s %s%</u>\n",
1534 "ADDR", "ID", "VERS", "FLAGS", "STATE");
1537 mdb_printf("%-8p %-4d %-4u %-5x %a\n",
1538 addr
, xi
.xi_id
, xi
.xi_version
, xi
.xi_flags
, xi
.xi_state
);
1540 if (opt_l
| opt_s
) {
1541 (void) mdb_inc_indent(4);
1542 mdb_printf("Local subscriptions requested by peer:\n");
1543 mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS");
1544 (void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class
, &xi
,
1545 addr
+ OFFSETOF(fmd_xprt_impl_t
, xi_lsub
));
1546 (void) mdb_dec_indent(4);
1549 if (opt_r
| opt_s
) {
1550 (void) mdb_inc_indent(4);
1551 mdb_printf("Remote subscriptions requested of peer:\n");
1552 mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS");
1553 (void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class
, &xi
,
1554 addr
+ OFFSETOF(fmd_xprt_impl_t
, xi_rsub
));
1555 (void) mdb_dec_indent(4);
1558 if (opt_u
| opt_s
) {
1559 (void) mdb_inc_indent(4);
1560 mdb_printf("Pending unsubscription acknowledgements:\n");
1561 mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS");
1562 (void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class
, &xi
,
1563 addr
+ OFFSETOF(fmd_xprt_impl_t
, xi_usub
));
1564 (void) mdb_dec_indent(4);
1571 tsnap_walk_init(mdb_walk_state_t
*wsp
)
1575 if (mdb_readvar(&F
, "fmd") != sizeof (F
)) {
1576 mdb_warn("failed to read fmd meta-data");
1580 wsp
->walk_addr
= (uintptr_t)F
.d_topo_list
.l_next
;
1585 tsnap_walk_step(mdb_walk_state_t
*wsp
)
1587 uintptr_t addr
= wsp
->walk_addr
;
1593 if (mdb_vread(&ftp
, sizeof (ftp
), addr
) != sizeof (ftp
)) {
1594 mdb_warn("failed to read fmd_topo_t at %p", addr
);
1598 wsp
->walk_addr
= (uintptr_t)ftp
.ft_list
.l_next
;
1599 return (wsp
->walk_callback(addr
, &ftp
, wsp
->walk_cbdata
));
1603 mq_walk_init(mdb_walk_state_t
*wsp
)
1606 struct fmd_eventq eq
;
1608 if (wsp
->walk_addr
== NULL
) {
1609 mdb_warn("NULL fmd_module_t passed in");
1613 if (mdb_vread(&m
, sizeof (m
), wsp
->walk_addr
) != sizeof (m
)) {
1614 mdb_warn("failed to read fmd_module_t at %p", wsp
->walk_addr
);
1617 if (mdb_vread(&eq
, sizeof (eq
), (uintptr_t)m
.mod_queue
)
1619 mdb_warn("failed to read fmd_eventq at %p", wsp
->walk_addr
);
1623 wsp
->walk_addr
= (uintptr_t)eq
.eq_list
.l_next
;
1629 mq_walk_step(mdb_walk_state_t
*wsp
)
1631 uintptr_t addr
= wsp
->walk_addr
;
1632 fmd_eventqelem_t eqe
;
1637 if (mdb_vread(&eqe
, sizeof (eqe
), addr
) != sizeof (eqe
)) {
1638 mdb_warn("failed to read fmd_eventqelem_t at %p", addr
);
1642 wsp
->walk_addr
= (uintptr_t)eqe
.eqe_list
.l_next
;
1643 return (wsp
->walk_callback(addr
, &eqe
, wsp
->walk_cbdata
));
1646 static const mdb_dcmd_t dcmds
[] = {
1647 { "fcf_case", "?", "print a FCF case", fcf_case
},
1648 { "fcf_event", "?", "print a FCF event", fcf_event
},
1649 { "fcf_hdr", "?", "print a FCF header", fcf_hdr
},
1650 { "fcf_sec", ":", "print a FCF section header", fcf_sec
},
1651 { "fcf_serd", "?", "print a FCF serd engine", fcf_serd
},
1652 { "fmd_trace", "?[-cs]", "display thread trace buffer(s)", fmd_trace
},
1653 { "fmd_ustat", "[:]", "display statistics collection", fmd_ustat
},
1654 { "fmd_stat", "[:]", "display statistic structure", fmd_stat
},
1655 { "fmd_event", NULL
, "display event structure", fmd_event
},
1656 { "fmd_thread", "?", "display thread or list of threads", fmd_thread
},
1657 { "fmd_module", "?", "display module or list of modules", fmd_module
},
1658 { "fmd_case", ":", "display case file structure", fmd_case
},
1659 { "fmd_buf", ":", "display buffer structure", fmd_buf
},
1660 { "fmd_serd", "[:]", "display serd engine structure", fmd_serd
},
1661 { "fmd_asru", "?", "display asru resource structure", fmd_asru
},
1662 { "fmd_asru_link", "?", "display resource structure", fmd_asru_link
},
1663 { "fmd_timer", "?", "display pending timer(s)", fmd_timer
},
1664 { "fmd_xprt", "?[-lrsu]", "display event transport(s)", fmd_xprt
},
1668 static const mdb_walker_t walkers
[] = {
1669 { "fcf_sec", "walk FCF section header table given header address",
1670 fcf_sec_walk_init
, fcf_sec_walk_step
, fcf_sec_walk_fini
},
1671 { "fmd_trace", "walk per-thread trace buffers",
1672 trwalk_init
, trwalk_step
, trwalk_fini
},
1673 { "fmd_ustat", "walk per-collection statistics",
1674 ustat_walk_init
, ustat_walk_step
, hash_walk_fini
},
1675 { "fmd_thread", "walk list of all fmd_thread_t's",
1676 thread_walk_init
, thread_walk_step
, NULL
},
1677 { "fmd_module", "walk list of all fmd_module_t's",
1678 mod_walk_init
, mod_walk_step
, NULL
},
1679 { "fmd_case", "walk per-module case objects",
1680 case_walk_init
, case_walk_step
, case_walk_fini
},
1681 { "fmd_buf", "walk per-buf_hash buffers",
1682 buf_walk_init
, hash_walk_step
, hash_walk_fini
},
1683 { "fmd_serd", "walk per-serd_hash engines",
1684 serd_walk_init
, hash_walk_step
, hash_walk_fini
},
1685 { "fmd_asru", "walk asru resource hash",
1686 asru_walk_init
, hash_walk_step
, hash_walk_fini
},
1687 { "fmd_asru_link", "walk resource hash",
1688 al_walk_init
, hash_walk_step
, hash_walk_fini
},
1689 { "fmd_timerq", "walk timer queue",
1690 tmq_walk_init
, tmq_walk_step
, NULL
},
1691 { "fmd_xprt", "walk per-module list of transports",
1692 xprt_walk_init
, xprt_walk_step
, NULL
},
1693 { "fmd_xprt_class", "walk hash table of subscription classes",
1694 xpc_walk_init
, hash_walk_step
, hash_walk_fini
},
1695 { "fmd_topo", "walk fmd's list of topo snapshots",
1696 tsnap_walk_init
, tsnap_walk_step
, NULL
},
1697 { "fmd_mod_queue", "walk per-module event queue",
1698 mq_walk_init
, mq_walk_step
, NULL
},
1699 { NULL
, NULL
, NULL
, NULL
, NULL
}
1702 static const mdb_modinfo_t modinfo
= { MDB_API_VERSION
, dcmds
, walkers
};
1704 const mdb_modinfo_t
*