xref: /illumos-gate/usr/src/cmd/fm/fmd/common/fmd_mdb.c (revision 1743a90d)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
524db4641Seschrock  * Common Development and Distribution License (the "License").
624db4641Seschrock  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21d9638e54Smws 
227c478bd9Sstevel@tonic-gate /*
232a417b23SRobert Johnston  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <sys/mdb_modapi.h>
276cb1ca52Saf #include <limits.h>
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <fmd_trace.h>
307c478bd9Sstevel@tonic-gate #include <fmd_module.h>
317c478bd9Sstevel@tonic-gate #include <fmd_thread.h>
327c478bd9Sstevel@tonic-gate #include <fmd_ustat.h>
337c478bd9Sstevel@tonic-gate #include <fmd_event.h>
347c478bd9Sstevel@tonic-gate #include <fmd_case.h>
357c478bd9Sstevel@tonic-gate #include <fmd_buf.h>
367c478bd9Sstevel@tonic-gate #include <fmd_asru.h>
377c478bd9Sstevel@tonic-gate #include <fmd_ckpt.h>
387c478bd9Sstevel@tonic-gate #include <fmd_timerq.h>
39d9638e54Smws #include <fmd_xprt.h>
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #include <fmd.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate typedef struct trwalk_state {
447c478bd9Sstevel@tonic-gate 	struct trwalk_state *trw_next;
457c478bd9Sstevel@tonic-gate 	fmd_tracebuf_t trw_data;
467c478bd9Sstevel@tonic-gate 	pthread_t trw_tid;
477c478bd9Sstevel@tonic-gate 	uintptr_t trw_base;
487c478bd9Sstevel@tonic-gate 	const fmd_tracerec_t *trw_stop;
497c478bd9Sstevel@tonic-gate 	fmd_tracerec_t *trw_xrec;
507c478bd9Sstevel@tonic-gate } trwalk_state_t;
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate typedef struct hashwalk_data {
537c478bd9Sstevel@tonic-gate 	uintptr_t *hw_hash;
547c478bd9Sstevel@tonic-gate 	uint_t hw_hashlen;
557c478bd9Sstevel@tonic-gate 	uint_t hw_hashidx;
567c478bd9Sstevel@tonic-gate 	const char *hw_name;
577c478bd9Sstevel@tonic-gate 	void *hw_data;
587c478bd9Sstevel@tonic-gate 	size_t hw_size;
597c478bd9Sstevel@tonic-gate 	size_t hw_next;
607c478bd9Sstevel@tonic-gate } hashwalk_data_t;
617c478bd9Sstevel@tonic-gate 
626cb1ca52Saf static int fmd_stat(uintptr_t, uint_t, int, const mdb_arg_t *);
636cb1ca52Saf static int fmd_ustat(uintptr_t, uint_t, int, const mdb_arg_t *);
646cb1ca52Saf 
657c478bd9Sstevel@tonic-gate static int
trwalk_init(mdb_walk_state_t * wsp)667c478bd9Sstevel@tonic-gate trwalk_init(mdb_walk_state_t *wsp)
677c478bd9Sstevel@tonic-gate {
687c478bd9Sstevel@tonic-gate 	uintptr_t addr;
697c478bd9Sstevel@tonic-gate 	fmd_thread_t thr;
707c478bd9Sstevel@tonic-gate 	fmd_t F;
717c478bd9Sstevel@tonic-gate 
72940f2f58SToomas Soome 	if (wsp->walk_addr != 0) {
737c478bd9Sstevel@tonic-gate 		mdb_warn("fmd_trace only supports global walks\n");
747c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
757c478bd9Sstevel@tonic-gate 	}
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&F, "fmd") != sizeof (F)) {
787c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd meta-data");
797c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
807c478bd9Sstevel@tonic-gate 	}
817c478bd9Sstevel@tonic-gate 
82940f2f58SToomas Soome 	for (addr = (uintptr_t)F.d_thr_list.l_next; addr != 0;
837c478bd9Sstevel@tonic-gate 	    addr = (uintptr_t)thr.thr_list.l_next) {
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate 		size_t len, ptr_off, end_off;
867c478bd9Sstevel@tonic-gate 		fmd_tracerec_t *buf;
877c478bd9Sstevel@tonic-gate 		trwalk_state_t *t;
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate 		if (mdb_vread(&thr, sizeof (thr), addr) != sizeof (thr)) {
907c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read thread at %p "
917c478bd9Sstevel@tonic-gate 			    "(some trace data will be unavailable)", addr);
927c478bd9Sstevel@tonic-gate 			break;
937c478bd9Sstevel@tonic-gate 		}
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 		t = mdb_zalloc(sizeof (trwalk_state_t), UM_SLEEP);
967c478bd9Sstevel@tonic-gate 		t->trw_next = wsp->walk_data;
977c478bd9Sstevel@tonic-gate 		wsp->walk_data = t;
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 		(void) mdb_vread(&t->trw_data,
1007c478bd9Sstevel@tonic-gate 		    sizeof (t->trw_data), (uintptr_t)thr.thr_trdata);
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate 		if (t->trw_data.tb_recs == 0)
1037c478bd9Sstevel@tonic-gate 			continue; /* no trace buffer allocated for thread */
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 		len = t->trw_data.tb_recs * t->trw_data.tb_size;
1067c478bd9Sstevel@tonic-gate 		buf = mdb_alloc(len, UM_SLEEP);
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate 		t->trw_tid = thr.thr_tid;
1097c478bd9Sstevel@tonic-gate 		t->trw_base = (uintptr_t)t->trw_data.tb_buf;
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate 		if (mdb_vread(buf, len, t->trw_base) == -1) {
1127c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read buffer for t%u", t->trw_tid);
1137c478bd9Sstevel@tonic-gate 			bzero(buf, len);
1147c478bd9Sstevel@tonic-gate 		}
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate 		end_off = (uintptr_t)t->trw_data.tb_end - t->trw_base;
1177c478bd9Sstevel@tonic-gate 		ptr_off = (uintptr_t)t->trw_data.tb_ptr - t->trw_base;
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 		t->trw_data.tb_buf = buf;
1207c478bd9Sstevel@tonic-gate 		t->trw_data.tb_end = (void *)((uintptr_t)buf + end_off);
1217c478bd9Sstevel@tonic-gate 		t->trw_data.tb_ptr = (void *)((uintptr_t)buf + ptr_off);
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 		if (t->trw_data.tb_ptr < t->trw_data.tb_buf ||
1247c478bd9Sstevel@tonic-gate 		    t->trw_data.tb_ptr > t->trw_data.tb_end) {
1257c478bd9Sstevel@tonic-gate 			mdb_warn("trace record ptr for t%u is corrupt "
1267c478bd9Sstevel@tonic-gate 			    "(some data may be unavailable)\n", t->trw_tid);
1277c478bd9Sstevel@tonic-gate 			t->trw_data.tb_ptr = t->trw_data.tb_buf;
1287c478bd9Sstevel@tonic-gate 		}
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 		t->trw_stop = t->trw_data.tb_ptr;
1317c478bd9Sstevel@tonic-gate 		t->trw_xrec = mdb_alloc(
1327c478bd9Sstevel@tonic-gate 		    t->trw_data.tb_size + sizeof (uintptr_t), UM_SLEEP);
1337c478bd9Sstevel@tonic-gate 	}
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
1367c478bd9Sstevel@tonic-gate }
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate static fmd_tracerec_t *
trwalk_nextrec(trwalk_state_t * t)1397c478bd9Sstevel@tonic-gate trwalk_nextrec(trwalk_state_t *t)
1407c478bd9Sstevel@tonic-gate {
1417c478bd9Sstevel@tonic-gate 	if (t->trw_stop == NULL)
1427c478bd9Sstevel@tonic-gate 		return (t->trw_data.tb_ptr);
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 	if (t->trw_data.tb_ptr == t->trw_data.tb_buf)
1457c478bd9Sstevel@tonic-gate 		t->trw_data.tb_ptr = t->trw_data.tb_end;
1467c478bd9Sstevel@tonic-gate 	else
1477c478bd9Sstevel@tonic-gate 		t->trw_data.tb_ptr = (fmd_tracerec_t *)
1487c478bd9Sstevel@tonic-gate 		    ((uintptr_t)t->trw_data.tb_ptr - t->trw_data.tb_size);
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	if (t->trw_data.tb_ptr == t->trw_stop)
1517c478bd9Sstevel@tonic-gate 		t->trw_stop = NULL; /* mark buffer as empty */
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	return (t->trw_data.tb_ptr);
1547c478bd9Sstevel@tonic-gate }
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate static int
trwalk_step(mdb_walk_state_t * wsp)1577c478bd9Sstevel@tonic-gate trwalk_step(mdb_walk_state_t *wsp)
1587c478bd9Sstevel@tonic-gate {
1597c478bd9Sstevel@tonic-gate 	trwalk_state_t *t, *oldest_t;
1607c478bd9Sstevel@tonic-gate 	hrtime_t oldest_time = 0;
1617c478bd9Sstevel@tonic-gate 	fmd_tracerec_t *trp;
1627c478bd9Sstevel@tonic-gate 	int status;
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate 	for (t = wsp->walk_data; t != NULL; t = t->trw_next) {
1657c478bd9Sstevel@tonic-gate 		for (trp = t->trw_data.tb_ptr; t->trw_stop != NULL &&
1667c478bd9Sstevel@tonic-gate 		    trp->tr_time == 0; trp = trwalk_nextrec(t))
1677c478bd9Sstevel@tonic-gate 			continue;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 		if (t->trw_stop == NULL)
1707c478bd9Sstevel@tonic-gate 			continue; /* buffer has been emptied */
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 		if (trp->tr_time > oldest_time) {
1737c478bd9Sstevel@tonic-gate 			oldest_time = trp->tr_time;
1747c478bd9Sstevel@tonic-gate 			oldest_t = t;
1757c478bd9Sstevel@tonic-gate 		}
1767c478bd9Sstevel@tonic-gate 	}
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 	if (oldest_time == 0)
1797c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate 	t = oldest_t;
1827c478bd9Sstevel@tonic-gate 	trp = t->trw_data.tb_ptr;
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate 	bcopy(trp, t->trw_xrec, t->trw_data.tb_size);
1857c478bd9Sstevel@tonic-gate 	t->trw_xrec->tr_depth = MIN(trp->tr_depth, t->trw_data.tb_frames);
1867c478bd9Sstevel@tonic-gate 	t->trw_xrec->tr_stack[t->trw_xrec->tr_depth] = t->trw_tid;
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate 	status = wsp->walk_callback((uintptr_t)trp - (uintptr_t)
1897c478bd9Sstevel@tonic-gate 	    t->trw_data.tb_buf + t->trw_base, t->trw_xrec, wsp->walk_cbdata);
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate 	(void) trwalk_nextrec(t);
1927c478bd9Sstevel@tonic-gate 	return (status);
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate static void
trwalk_fini(mdb_walk_state_t * wsp)1967c478bd9Sstevel@tonic-gate trwalk_fini(mdb_walk_state_t *wsp)
1977c478bd9Sstevel@tonic-gate {
1987c478bd9Sstevel@tonic-gate 	trwalk_state_t *t, *u;
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 	for (t = wsp->walk_data; t != NULL; t = u) {
2017c478bd9Sstevel@tonic-gate 		u = t->trw_next;
2027c478bd9Sstevel@tonic-gate 		mdb_free(t->trw_data.tb_buf,
2037c478bd9Sstevel@tonic-gate 		    t->trw_data.tb_recs * t->trw_data.tb_size);
2047c478bd9Sstevel@tonic-gate 		mdb_free(t->trw_xrec, t->trw_data.tb_size + sizeof (uintptr_t));
2057c478bd9Sstevel@tonic-gate 		mdb_free(t, sizeof (trwalk_state_t));
2067c478bd9Sstevel@tonic-gate 	}
2077c478bd9Sstevel@tonic-gate }
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2107c478bd9Sstevel@tonic-gate static int
trprint_msg(uintptr_t addr,const void * arg,void * arg1)211*1743a90dSToomas Soome trprint_msg(uintptr_t addr, const void *arg, void *arg1)
2127c478bd9Sstevel@tonic-gate {
213*1743a90dSToomas Soome 	const fmd_tracerec_t *trp = arg;
214*1743a90dSToomas Soome 	uintptr_t tid = (uintptr_t)arg1;
215*1743a90dSToomas Soome 
2167c478bd9Sstevel@tonic-gate 	if (tid == 0)
2177c478bd9Sstevel@tonic-gate 		mdb_printf("%3lu ", trp->tr_stack[trp->tr_depth]);
2187c478bd9Sstevel@tonic-gate 	else if (trp->tr_stack[trp->tr_depth] != tid)
2197c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate 	mdb_printf("%016llx %04x %-5u %s\n",
222d9638e54Smws 	    trp->tr_time, 1 << trp->tr_tag, trp->tr_errno, trp->tr_msg);
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
2257c478bd9Sstevel@tonic-gate }
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2287c478bd9Sstevel@tonic-gate static int
trprint_cpp(uintptr_t addr,const void * arg,void * arg1)229*1743a90dSToomas Soome trprint_cpp(uintptr_t addr, const void *arg, void *arg1)
2307c478bd9Sstevel@tonic-gate {
231*1743a90dSToomas Soome 	const fmd_tracerec_t *trp = arg;
232*1743a90dSToomas Soome 	uintptr_t tid = (uintptr_t)arg1;
2337c478bd9Sstevel@tonic-gate 	char file[64];
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	if (tid == 0)
2367c478bd9Sstevel@tonic-gate 		mdb_printf("%3lu ", trp->tr_stack[trp->tr_depth]);
2377c478bd9Sstevel@tonic-gate 	else if (trp->tr_stack[trp->tr_depth] != tid)
2387c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 	if (mdb_readstr(file, sizeof (file), (uintptr_t)trp->tr_file) <= 0)
2417c478bd9Sstevel@tonic-gate 		(void) strcpy(file, "???");
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 	mdb_printf("%016llx %04x %s: %u\n",
244d9638e54Smws 	    trp->tr_time, 1 << trp->tr_tag, file, trp->tr_line);
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
2477c478bd9Sstevel@tonic-gate }
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate static void
trprint_stack(const fmd_tracerec_t * trp)2507c478bd9Sstevel@tonic-gate trprint_stack(const fmd_tracerec_t *trp)
2517c478bd9Sstevel@tonic-gate {
2527c478bd9Sstevel@tonic-gate 	uint8_t i;
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 	for (i = 0; i < trp->tr_depth; i++)
2557c478bd9Sstevel@tonic-gate 		mdb_printf("\t%a\n", trp->tr_stack[i]);
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 	if (trp->tr_depth != 0)
2587c478bd9Sstevel@tonic-gate 		mdb_printf("\n");
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate static int
trprint_msg_stack(uintptr_t addr,const void * arg,void * arg1)262*1743a90dSToomas Soome trprint_msg_stack(uintptr_t addr, const void *arg, void *arg1)
2637c478bd9Sstevel@tonic-gate {
264*1743a90dSToomas Soome 	const fmd_tracerec_t *trp = arg;
265*1743a90dSToomas Soome 	int status = trprint_msg(addr, trp, arg1);
2667c478bd9Sstevel@tonic-gate 	trprint_stack(trp);
2677c478bd9Sstevel@tonic-gate 	return (status);
2687c478bd9Sstevel@tonic-gate }
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate static int
trprint_cpp_stack(uintptr_t addr,const void * arg,void * arg1)271*1743a90dSToomas Soome trprint_cpp_stack(uintptr_t addr, const void *arg, void *arg1)
2727c478bd9Sstevel@tonic-gate {
273*1743a90dSToomas Soome 	const fmd_tracerec_t *trp = arg;
274*1743a90dSToomas Soome 	int status = trprint_cpp(addr, trp, arg1);
2757c478bd9Sstevel@tonic-gate 	trprint_stack(trp);
2767c478bd9Sstevel@tonic-gate 	return (status);
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate static int
fmd_trace(uintptr_t tid,uint_t flags,int argc,const mdb_arg_t * argv)2807c478bd9Sstevel@tonic-gate fmd_trace(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv)
2817c478bd9Sstevel@tonic-gate {
282*1743a90dSToomas Soome 	int (*func)(uintptr_t, const void *, void *);
2837c478bd9Sstevel@tonic-gate 	uint_t opt_c = FALSE, opt_s = FALSE;
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv,
2867c478bd9Sstevel@tonic-gate 	    'c', MDB_OPT_SETBITS, TRUE, &opt_c,
2877c478bd9Sstevel@tonic-gate 	    's', MDB_OPT_SETBITS, TRUE, &opt_s, NULL) != argc)
2887c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
2917c478bd9Sstevel@tonic-gate 		mdb_printf("TID ");
2927c478bd9Sstevel@tonic-gate 		tid = 0;
2937c478bd9Sstevel@tonic-gate 	}
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 	if (opt_c) {
2967c478bd9Sstevel@tonic-gate 		mdb_printf("%-16s %-4s FILE:LINE\n", "TIME", "TAG");
2977c478bd9Sstevel@tonic-gate 		func = opt_s ? trprint_cpp_stack : trprint_cpp;
2987c478bd9Sstevel@tonic-gate 	} else {
2997c478bd9Sstevel@tonic-gate 		mdb_printf("%-16s %-4s %-5s MSG\n", "TIME", "TAG", "ERRNO");
3007c478bd9Sstevel@tonic-gate 		func = opt_s ? trprint_msg_stack : trprint_msg;
3017c478bd9Sstevel@tonic-gate 	}
3027c478bd9Sstevel@tonic-gate 
303*1743a90dSToomas Soome 	if (mdb_walk("fmd_trace", func, (void *)tid) == -1) {
3047c478bd9Sstevel@tonic-gate 		mdb_warn("failed to walk fmd_trace");
3057c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
3067c478bd9Sstevel@tonic-gate 	}
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
3097c478bd9Sstevel@tonic-gate }
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate static int
hash_walk_init(mdb_walk_state_t * wsp,uintptr_t addr,uint_t hashlen,const char * name,size_t size,size_t next)3127c478bd9Sstevel@tonic-gate hash_walk_init(mdb_walk_state_t *wsp, uintptr_t addr, uint_t hashlen,
3137c478bd9Sstevel@tonic-gate     const char *name, size_t size, size_t next)
3147c478bd9Sstevel@tonic-gate {
3153d7072f8Seschrock 	hashwalk_data_t *hwp;
3167c478bd9Sstevel@tonic-gate 	size_t len = sizeof (uintptr_t) * hashlen;
3177c478bd9Sstevel@tonic-gate 
3183d7072f8Seschrock 	if (len == 0) {
3193d7072f8Seschrock 		mdb_warn("failed to walk hash: invalid hash length\n");
3203d7072f8Seschrock 		return (WALK_ERR);
3213d7072f8Seschrock 	}
3223d7072f8Seschrock 
3233d7072f8Seschrock 	hwp = mdb_alloc(sizeof (hashwalk_data_t), UM_SLEEP);
3247c478bd9Sstevel@tonic-gate 	hwp->hw_hash = mdb_zalloc(len, UM_SLEEP);
3257c478bd9Sstevel@tonic-gate 	(void) mdb_vread(hwp->hw_hash, len, addr);
3267c478bd9Sstevel@tonic-gate 	hwp->hw_hashlen = hashlen;
3277c478bd9Sstevel@tonic-gate 	hwp->hw_hashidx = 0;
3287c478bd9Sstevel@tonic-gate 	hwp->hw_name = name;
3297c478bd9Sstevel@tonic-gate 	hwp->hw_data = mdb_zalloc(size, UM_SLEEP);
3307c478bd9Sstevel@tonic-gate 	hwp->hw_size = size;
3317c478bd9Sstevel@tonic-gate 	hwp->hw_next = next;
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 	wsp->walk_addr = hwp->hw_hash[0];
3347c478bd9Sstevel@tonic-gate 	wsp->walk_data = hwp;
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
3377c478bd9Sstevel@tonic-gate }
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate static int
hash_walk_step(mdb_walk_state_t * wsp)3407c478bd9Sstevel@tonic-gate hash_walk_step(mdb_walk_state_t *wsp)
3417c478bd9Sstevel@tonic-gate {
3427c478bd9Sstevel@tonic-gate 	hashwalk_data_t *hwp = wsp->walk_data;
3437c478bd9Sstevel@tonic-gate 	int rv;
3447c478bd9Sstevel@tonic-gate 
345940f2f58SToomas Soome 	while (wsp->walk_addr == 0) {
3467c478bd9Sstevel@tonic-gate 		if (++hwp->hw_hashidx < hwp->hw_hashlen)
3477c478bd9Sstevel@tonic-gate 			wsp->walk_addr = hwp->hw_hash[hwp->hw_hashidx];
3487c478bd9Sstevel@tonic-gate 		else
3497c478bd9Sstevel@tonic-gate 			return (WALK_DONE);
3507c478bd9Sstevel@tonic-gate 	}
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 	if (mdb_vread(hwp->hw_data, hwp->hw_size, wsp->walk_addr) == -1) {
3537c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read %s at %p",
3547c478bd9Sstevel@tonic-gate 		    hwp->hw_name, wsp->walk_addr);
3557c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
3567c478bd9Sstevel@tonic-gate 	}
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 	rv = wsp->walk_callback(wsp->walk_addr, hwp->hw_data, wsp->walk_cbdata);
3597c478bd9Sstevel@tonic-gate 	wsp->walk_addr = *(uintptr_t *)((uintptr_t)hwp->hw_data + hwp->hw_next);
3607c478bd9Sstevel@tonic-gate 	return (rv);
3617c478bd9Sstevel@tonic-gate }
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate static void
hash_walk_fini(mdb_walk_state_t * wsp)3647c478bd9Sstevel@tonic-gate hash_walk_fini(mdb_walk_state_t *wsp)
3657c478bd9Sstevel@tonic-gate {
3667c478bd9Sstevel@tonic-gate 	hashwalk_data_t *hwp = wsp->walk_data;
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate 	mdb_free(hwp->hw_hash, sizeof (uintptr_t) * hwp->hw_hashlen);
3697c478bd9Sstevel@tonic-gate 	mdb_free(hwp->hw_data, hwp->hw_size);
3707c478bd9Sstevel@tonic-gate 	mdb_free(hwp, sizeof (hashwalk_data_t));
3717c478bd9Sstevel@tonic-gate }
3727c478bd9Sstevel@tonic-gate 
3737c478bd9Sstevel@tonic-gate static int
ustat_walk_init(mdb_walk_state_t * wsp)3747c478bd9Sstevel@tonic-gate ustat_walk_init(mdb_walk_state_t *wsp)
3757c478bd9Sstevel@tonic-gate {
3767c478bd9Sstevel@tonic-gate 	fmd_ustat_t us;
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate 	if (mdb_vread(&us, sizeof (us), wsp->walk_addr) != sizeof (us)) {
3797c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_ustat_t at %p", wsp->walk_addr);
3807c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
3817c478bd9Sstevel@tonic-gate 	}
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate 	return (hash_walk_init(wsp,
3847c478bd9Sstevel@tonic-gate 	    (uintptr_t)us.us_hash, us.us_hashlen, NULL, 0, 0));
3857c478bd9Sstevel@tonic-gate }
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate static int
ustat_walk_step(mdb_walk_state_t * wsp)3887c478bd9Sstevel@tonic-gate ustat_walk_step(mdb_walk_state_t *wsp)
3897c478bd9Sstevel@tonic-gate {
3907c478bd9Sstevel@tonic-gate 	hashwalk_data_t *hwp = wsp->walk_data;
3917c478bd9Sstevel@tonic-gate 	fmd_ustat_elem_t ue;
3927c478bd9Sstevel@tonic-gate 	fmd_stat_t s;
3937c478bd9Sstevel@tonic-gate 
394940f2f58SToomas Soome 	while (wsp->walk_addr == 0) {
3957c478bd9Sstevel@tonic-gate 		if (++hwp->hw_hashidx < hwp->hw_hashlen)
3967c478bd9Sstevel@tonic-gate 			wsp->walk_addr = hwp->hw_hash[hwp->hw_hashidx];
3977c478bd9Sstevel@tonic-gate 		else
3987c478bd9Sstevel@tonic-gate 			return (WALK_DONE);
3997c478bd9Sstevel@tonic-gate 	}
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate 	if (mdb_vread(&ue, sizeof (ue), wsp->walk_addr) != sizeof (ue) ||
4027c478bd9Sstevel@tonic-gate 	    mdb_vread(&s, sizeof (s), (uintptr_t)ue.use_stat) != sizeof (s)) {
4037c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read stat element at %p", wsp->walk_addr);
4047c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
4057c478bd9Sstevel@tonic-gate 	}
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)ue.use_next;
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate 	return (wsp->walk_callback(
4107c478bd9Sstevel@tonic-gate 	    (uintptr_t)ue.use_stat, &s, wsp->walk_cbdata));
4117c478bd9Sstevel@tonic-gate }
4127c478bd9Sstevel@tonic-gate 
4136cb1ca52Saf struct fmd_cmd_data {
4146cb1ca52Saf 	int argc;
4156cb1ca52Saf 	const mdb_arg_t *argv;
4166cb1ca52Saf };
4176cb1ca52Saf 
4186cb1ca52Saf /* ARGSUSED */
4196cb1ca52Saf static int
module_ustat(uintptr_t addr,const void * data,void * wsp)4206cb1ca52Saf module_ustat(uintptr_t addr, const void *data, void *wsp)
4216cb1ca52Saf {
4226cb1ca52Saf 	fmd_module_t *modp = (fmd_module_t *)data;
4236cb1ca52Saf 	char name[PATH_MAX];
4246cb1ca52Saf 	const struct fmd_cmd_data *udp = wsp;
4256cb1ca52Saf 
4266cb1ca52Saf 	if (mdb_readstr(name, sizeof (name), (uintptr_t)modp->mod_name) <= 0)
4276cb1ca52Saf 		(void) mdb_snprintf(name, sizeof (name), "<%p>",
4286cb1ca52Saf 		    modp->mod_name);
4296cb1ca52Saf 	mdb_printf("%s\n", name);
4306cb1ca52Saf 	(void) fmd_ustat((uintptr_t)modp->mod_ustat,
4316cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOPFIRST, udp->argc, udp->argv);
4326cb1ca52Saf 	return (WALK_NEXT);
4336cb1ca52Saf }
4346cb1ca52Saf 
4357c478bd9Sstevel@tonic-gate static int
fmd_ustat(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)4367c478bd9Sstevel@tonic-gate fmd_ustat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
4377c478bd9Sstevel@tonic-gate {
4386cb1ca52Saf 	if (!(flags & DCMD_ADDRSPEC)) {
4396cb1ca52Saf 		struct fmd_cmd_data ud;
4406cb1ca52Saf 
4416cb1ca52Saf 		ud.argc = argc;
4426cb1ca52Saf 		ud.argv = argv;
4436cb1ca52Saf 		if (mdb_walk("fmd_module", module_ustat, &ud) == -1) {
4446cb1ca52Saf 			mdb_warn("failed to walk 'fmd_module'");
4456cb1ca52Saf 			return (DCMD_ERR);
4466cb1ca52Saf 		}
4476cb1ca52Saf 		return (DCMD_OK);
4486cb1ca52Saf 	}
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate 	if (mdb_pwalk_dcmd("fmd_ustat", "fmd_stat", argc, argv, addr) != 0) {
4517c478bd9Sstevel@tonic-gate 		mdb_warn("failed to walk fmd_ustat at %p", addr);
4527c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
4537c478bd9Sstevel@tonic-gate 	}
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
4567c478bd9Sstevel@tonic-gate }
4577c478bd9Sstevel@tonic-gate 
4586cb1ca52Saf /* ARGSUSED */
4596cb1ca52Saf static int
module_stat(uintptr_t addr,const void * data,void * wsp)4606cb1ca52Saf module_stat(uintptr_t addr, const void *data, void *wsp)
4616cb1ca52Saf {
4626cb1ca52Saf 	fmd_module_t *modp = (fmd_module_t *)data;
4636cb1ca52Saf 	char name[PATH_MAX];
4646cb1ca52Saf 	const struct fmd_cmd_data *udp = wsp;
4656cb1ca52Saf 	fmd_modstat_t *mod_stats;
4666cb1ca52Saf 
4676cb1ca52Saf 	if (mdb_readstr(name, sizeof (name), (uintptr_t)modp->mod_name) <= 0) {
4686cb1ca52Saf 		(void) mdb_snprintf(name, sizeof (name), "<%p>",
4696cb1ca52Saf 		    modp->mod_name);
4706cb1ca52Saf 	}
4716cb1ca52Saf 	mdb_printf("%s\n", name);
4726cb1ca52Saf 	mod_stats = modp->mod_stats;
4736cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_loadtime,
4746cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOPFIRST, udp->argc, udp->argv);
4756cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_snaptime,
4766cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4776cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_accepted,
4786cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4796cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_debugdrop,
4806cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4816cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_memtotal,
4826cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4836cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_memlimit,
4846cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4856cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_buftotal,
4866cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4876cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_buflimit,
4886cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4896cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_thrtotal,
4906cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4916cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_thrlimit,
4926cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
493f6e214c7SGavin Maltby 	(void) fmd_stat((uintptr_t)&mod_stats->ms_doorthrtotal,
494f6e214c7SGavin Maltby 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
495f6e214c7SGavin Maltby 	(void) fmd_stat((uintptr_t)&mod_stats->ms_doorthrlimit,
496f6e214c7SGavin Maltby 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4976cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_caseopen,
4986cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4996cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_casesolved,
5006cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5016cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_caseclosed,
5026cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5036cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_save,
5046cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5056cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_restore,
5066cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5076cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_zeroed,
5086cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5096cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_cnt,
5106cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5116cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_time,
5126cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5136cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_xprtopen,
5146cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5156cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_xprtlimit,
5166cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5176cb1ca52Saf 	(void) fmd_stat((uintptr_t)&mod_stats->ms_xprtqlimit,
5186cb1ca52Saf 	    DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5196cb1ca52Saf 	return (WALK_NEXT);
5206cb1ca52Saf }
5216cb1ca52Saf 
5227c478bd9Sstevel@tonic-gate /*ARGSUSED*/
5237c478bd9Sstevel@tonic-gate static int
fmd_stat(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)5247c478bd9Sstevel@tonic-gate fmd_stat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
5257c478bd9Sstevel@tonic-gate {
5267c478bd9Sstevel@tonic-gate 	char buf[512];
5277c478bd9Sstevel@tonic-gate 	fmd_stat_t s;
5287c478bd9Sstevel@tonic-gate 
5296cb1ca52Saf 	if (argc != 0)
5307c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags))
5337c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-11s %-4s %-32s %s%</u>\n",
5347c478bd9Sstevel@tonic-gate 		    "ADDR", "TYPE", "NAME", "VALUE");
5357c478bd9Sstevel@tonic-gate 
5366cb1ca52Saf 	if (!(flags & DCMD_ADDRSPEC)) {
5376cb1ca52Saf 		struct fmd_cmd_data ud;
5386cb1ca52Saf 
5396cb1ca52Saf 		ud.argc = argc;
5406cb1ca52Saf 		ud.argv = argv;
5416cb1ca52Saf 
5426cb1ca52Saf 		if (mdb_walk("fmd_module", module_stat, &ud) == -1) {
5436cb1ca52Saf 			mdb_warn("failed to walk 'fmd_module'");
5446cb1ca52Saf 			return (DCMD_ERR);
5456cb1ca52Saf 		}
5466cb1ca52Saf 		return (DCMD_OK);
5476cb1ca52Saf 	}
5486cb1ca52Saf 
5497c478bd9Sstevel@tonic-gate 	if (mdb_vread(&s, sizeof (s), addr) != sizeof (s)) {
5507c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read statistic at %p", addr);
5517c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
5527c478bd9Sstevel@tonic-gate 	}
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate 	switch (s.fmds_type) {
5557c478bd9Sstevel@tonic-gate 	case FMD_TYPE_BOOL:
5567c478bd9Sstevel@tonic-gate 		mdb_printf("%-11p %-4s %-32s %s\n", addr, "bool",
5577c478bd9Sstevel@tonic-gate 		    s.fmds_name, s.fmds_value.bool ? "true" : "false");
5587c478bd9Sstevel@tonic-gate 		break;
5597c478bd9Sstevel@tonic-gate 	case FMD_TYPE_INT32:
5607c478bd9Sstevel@tonic-gate 		mdb_printf("%-11p %-4s %-32s %d\n", addr, "i32",
5617c478bd9Sstevel@tonic-gate 		    s.fmds_name, s.fmds_value.i32);
5627c478bd9Sstevel@tonic-gate 		break;
5637c478bd9Sstevel@tonic-gate 	case FMD_TYPE_UINT32:
5647c478bd9Sstevel@tonic-gate 		mdb_printf("%-11p %-4s %-32s %u\n", addr, "ui32",
5657c478bd9Sstevel@tonic-gate 		    s.fmds_name, s.fmds_value.i32);
5667c478bd9Sstevel@tonic-gate 		break;
5677c478bd9Sstevel@tonic-gate 	case FMD_TYPE_INT64:
5687c478bd9Sstevel@tonic-gate 		mdb_printf("%-11p %-4s %-32s %lld\n", addr, "i64",
5697c478bd9Sstevel@tonic-gate 		    s.fmds_name, s.fmds_value.i64);
5707c478bd9Sstevel@tonic-gate 		break;
5717c478bd9Sstevel@tonic-gate 	case FMD_TYPE_UINT64:
5727c478bd9Sstevel@tonic-gate 		mdb_printf("%-11p %-4s %-32s %llu\n", addr, "ui64",
5737c478bd9Sstevel@tonic-gate 		    s.fmds_name, s.fmds_value.ui64);
5747c478bd9Sstevel@tonic-gate 		break;
5757c478bd9Sstevel@tonic-gate 	case FMD_TYPE_STRING:
5767c478bd9Sstevel@tonic-gate 		if (mdb_readstr(buf, sizeof (buf),
5777c478bd9Sstevel@tonic-gate 		    (uintptr_t)s.fmds_value.str) < 0) {
5787c478bd9Sstevel@tonic-gate 			(void) mdb_snprintf(buf, sizeof (buf), "<%p>",
5797c478bd9Sstevel@tonic-gate 			    s.fmds_value.str);
5807c478bd9Sstevel@tonic-gate 		}
5817c478bd9Sstevel@tonic-gate 		mdb_printf("%-11p %-4s %-32s %s\n", addr, "str",
5827c478bd9Sstevel@tonic-gate 		    s.fmds_name, buf);
5837c478bd9Sstevel@tonic-gate 		break;
5847c478bd9Sstevel@tonic-gate 	case FMD_TYPE_TIME:
5857c478bd9Sstevel@tonic-gate 		mdb_printf("%-11p %-4s %-32s %llu\n", addr, "time",
5867c478bd9Sstevel@tonic-gate 		    s.fmds_name, s.fmds_value.ui64);
5877c478bd9Sstevel@tonic-gate 		break;
5887c478bd9Sstevel@tonic-gate 	case FMD_TYPE_SIZE:
5897c478bd9Sstevel@tonic-gate 		mdb_printf("%-11p %-4s %-32s %llu\n", addr, "size",
5907c478bd9Sstevel@tonic-gate 		    s.fmds_name, s.fmds_value.ui64);
5917c478bd9Sstevel@tonic-gate 		break;
5927c478bd9Sstevel@tonic-gate 	default:
5937c478bd9Sstevel@tonic-gate 		mdb_printf("%-11p %-4u %-32s ???\n", addr,
5947c478bd9Sstevel@tonic-gate 		    s.fmds_type, s.fmds_name);
5957c478bd9Sstevel@tonic-gate 		break;
5967c478bd9Sstevel@tonic-gate 	}
5977c478bd9Sstevel@tonic-gate 
5987c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
5997c478bd9Sstevel@tonic-gate }
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate /*ARGSUSED*/
6027c478bd9Sstevel@tonic-gate static int
fmd_event(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)6037c478bd9Sstevel@tonic-gate fmd_event(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
6047c478bd9Sstevel@tonic-gate {
6057c478bd9Sstevel@tonic-gate 	char type[16], name[16];
6067c478bd9Sstevel@tonic-gate 	fmd_event_impl_t ev;
6077c478bd9Sstevel@tonic-gate 
6087c478bd9Sstevel@tonic-gate 	if (argc != 0)
6097c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 	if (mdb_vread(&ev, sizeof (ev), addr) != sizeof (ev)) {
6127c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_event at %p", addr);
6137c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
6147c478bd9Sstevel@tonic-gate 	}
6157c478bd9Sstevel@tonic-gate 
6167c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
6177c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-11s %-4s %-5s %-3s %-?s%</u>\n",
6187c478bd9Sstevel@tonic-gate 		    "ADDR", "TYPE", "STATE", "REF", "NVPAIR");
6197c478bd9Sstevel@tonic-gate 	}
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate 	switch (ev.ev_type) {
6227c478bd9Sstevel@tonic-gate 	case FMD_EVT_PROTOCOL:
6237c478bd9Sstevel@tonic-gate 		(void) strcpy(type, "PROT");
6247c478bd9Sstevel@tonic-gate 		break;
6257c478bd9Sstevel@tonic-gate 	case FMD_EVT_GC:
6267c478bd9Sstevel@tonic-gate 		(void) strcpy(type, "GC");
6277c478bd9Sstevel@tonic-gate 		break;
6287c478bd9Sstevel@tonic-gate 	case FMD_EVT_CLOSE:
6297c478bd9Sstevel@tonic-gate 		(void) strcpy(type, "CLSE");
6307c478bd9Sstevel@tonic-gate 		break;
6317c478bd9Sstevel@tonic-gate 	case FMD_EVT_TIMEOUT:
6327c478bd9Sstevel@tonic-gate 		(void) strcpy(type, "TIME");
6337c478bd9Sstevel@tonic-gate 		break;
6347c478bd9Sstevel@tonic-gate 	case FMD_EVT_STATS:
6357c478bd9Sstevel@tonic-gate 		(void) strcpy(type, "STAT");
6367c478bd9Sstevel@tonic-gate 		break;
637d9638e54Smws 	case FMD_EVT_PUBLISH:
638d9638e54Smws 		(void) strcpy(type, "PUBL");
639d9638e54Smws 		break;
64024db4641Seschrock 	case FMD_EVT_TOPO:
64124db4641Seschrock 		(void) strcpy(type, "TOPO");
64224db4641Seschrock 		break;
6437c478bd9Sstevel@tonic-gate 	default:
6447c478bd9Sstevel@tonic-gate 		(void) mdb_snprintf(type, sizeof (type), "%u", ev.ev_type);
6457c478bd9Sstevel@tonic-gate 	}
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate 	switch (ev.ev_state) {
6487c478bd9Sstevel@tonic-gate 	case FMD_EVS_RECEIVED:
6497c478bd9Sstevel@tonic-gate 		(void) strcpy(name, "RECVD");
6507c478bd9Sstevel@tonic-gate 		break;
6517c478bd9Sstevel@tonic-gate 	case FMD_EVS_ACCEPTED:
6527c478bd9Sstevel@tonic-gate 		(void) strcpy(name, "ACCPT");
6537c478bd9Sstevel@tonic-gate 		break;
6547c478bd9Sstevel@tonic-gate 	case FMD_EVS_DISCARDED:
6557c478bd9Sstevel@tonic-gate 		(void) strcpy(name, "DSCRD");
6567c478bd9Sstevel@tonic-gate 		break;
6577c478bd9Sstevel@tonic-gate 	case FMD_EVS_DIAGNOSED:
6587c478bd9Sstevel@tonic-gate 		(void) strcpy(name, "DIAGN");
6597c478bd9Sstevel@tonic-gate 		break;
6607c478bd9Sstevel@tonic-gate 	default:
6617c478bd9Sstevel@tonic-gate 		(void) mdb_snprintf(name, sizeof (name), "%u", ev.ev_state);
6627c478bd9Sstevel@tonic-gate 	}
6637c478bd9Sstevel@tonic-gate 
6647c478bd9Sstevel@tonic-gate 	mdb_printf("%-11p %-4s %-5s %-3u %p\n",
6657c478bd9Sstevel@tonic-gate 	    addr, type, name, ev.ev_refs, ev.ev_nvl);
6667c478bd9Sstevel@tonic-gate 
6677c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
6687c478bd9Sstevel@tonic-gate }
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate static int
thread_walk_init(mdb_walk_state_t * wsp)6717c478bd9Sstevel@tonic-gate thread_walk_init(mdb_walk_state_t *wsp)
6727c478bd9Sstevel@tonic-gate {
6737c478bd9Sstevel@tonic-gate 	fmd_t F;
6747c478bd9Sstevel@tonic-gate 
6757c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&F, "fmd") != sizeof (F)) {
6767c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd meta-data");
6777c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
6787c478bd9Sstevel@tonic-gate 	}
6797c478bd9Sstevel@tonic-gate 
6807c478bd9Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)F.d_thr_list.l_next;
6817c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
6827c478bd9Sstevel@tonic-gate }
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate static int
thread_walk_step(mdb_walk_state_t * wsp)6857c478bd9Sstevel@tonic-gate thread_walk_step(mdb_walk_state_t *wsp)
6867c478bd9Sstevel@tonic-gate {
6877c478bd9Sstevel@tonic-gate 	uintptr_t addr = wsp->walk_addr;
6887c478bd9Sstevel@tonic-gate 	fmd_thread_t t;
6897c478bd9Sstevel@tonic-gate 
690940f2f58SToomas Soome 	if (addr == 0)
6917c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
6927c478bd9Sstevel@tonic-gate 
6937c478bd9Sstevel@tonic-gate 	if (mdb_vread(&t, sizeof (t), addr) != sizeof (t)) {
6947c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_thread at %p", addr);
6957c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
6967c478bd9Sstevel@tonic-gate 	}
6977c478bd9Sstevel@tonic-gate 
6987c478bd9Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)t.thr_list.l_next;
6997c478bd9Sstevel@tonic-gate 	return (wsp->walk_callback(addr, &t, wsp->walk_cbdata));
7007c478bd9Sstevel@tonic-gate }
7017c478bd9Sstevel@tonic-gate 
7027c478bd9Sstevel@tonic-gate static int
fmd_thread(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)7037c478bd9Sstevel@tonic-gate fmd_thread(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
7047c478bd9Sstevel@tonic-gate {
7057c478bd9Sstevel@tonic-gate 	fmd_thread_t thr;
7067c478bd9Sstevel@tonic-gate 
7077c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC))
7087c478bd9Sstevel@tonic-gate 		return (mdb_walk_dcmd("fmd_thread", "fmd_thread", argc, argv));
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate 	if (argc != 0)
7117c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
7127c478bd9Sstevel@tonic-gate 
7137c478bd9Sstevel@tonic-gate 	if (mdb_vread(&thr, sizeof (thr), addr) != sizeof (thr)) {
7147c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_thread at %p", addr);
7157c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
7167c478bd9Sstevel@tonic-gate 	}
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
7197c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-11s %-11s %-8s %-16s%</u>\n",
7207c478bd9Sstevel@tonic-gate 		    "ADDR", "MOD", "TID", "FUNC");
7217c478bd9Sstevel@tonic-gate 	}
7227c478bd9Sstevel@tonic-gate 
7237c478bd9Sstevel@tonic-gate 	mdb_printf("%-11p %-11p %-8u %a\n",
7247c478bd9Sstevel@tonic-gate 	    addr, thr.thr_mod, thr.thr_tid, thr.thr_func);
7257c478bd9Sstevel@tonic-gate 
7267c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
7277c478bd9Sstevel@tonic-gate }
7287c478bd9Sstevel@tonic-gate 
7297c478bd9Sstevel@tonic-gate static int
mod_walk_init(mdb_walk_state_t * wsp)7307c478bd9Sstevel@tonic-gate mod_walk_init(mdb_walk_state_t *wsp)
7317c478bd9Sstevel@tonic-gate {
7327c478bd9Sstevel@tonic-gate 	fmd_t F;
7337c478bd9Sstevel@tonic-gate 
7347c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&F, "fmd") != sizeof (F)) {
7357c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd meta-data");
7367c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
7377c478bd9Sstevel@tonic-gate 	}
7387c478bd9Sstevel@tonic-gate 
7397c478bd9Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)F.d_mod_list.l_next;
7407c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
7417c478bd9Sstevel@tonic-gate }
7427c478bd9Sstevel@tonic-gate 
7437c478bd9Sstevel@tonic-gate static int
mod_walk_step(mdb_walk_state_t * wsp)7447c478bd9Sstevel@tonic-gate mod_walk_step(mdb_walk_state_t *wsp)
7457c478bd9Sstevel@tonic-gate {
7467c478bd9Sstevel@tonic-gate 	uintptr_t addr = wsp->walk_addr;
7477c478bd9Sstevel@tonic-gate 	fmd_module_t m;
7487c478bd9Sstevel@tonic-gate 
749940f2f58SToomas Soome 	if (addr == 0)
7507c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
7517c478bd9Sstevel@tonic-gate 
7527c478bd9Sstevel@tonic-gate 	if (mdb_vread(&m, sizeof (m), addr) != sizeof (m)) {
7537c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_module at %p", addr);
7547c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
7557c478bd9Sstevel@tonic-gate 	}
7567c478bd9Sstevel@tonic-gate 
7577c478bd9Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)m.mod_list.l_next;
7587c478bd9Sstevel@tonic-gate 	return (wsp->walk_callback(addr, &m, wsp->walk_cbdata));
7597c478bd9Sstevel@tonic-gate }
7607c478bd9Sstevel@tonic-gate 
7617c478bd9Sstevel@tonic-gate static int
fmd_module(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)7627c478bd9Sstevel@tonic-gate fmd_module(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
7637c478bd9Sstevel@tonic-gate {
7647c478bd9Sstevel@tonic-gate 	fmd_module_t mod;
7656cb1ca52Saf 	char name[PATH_MAX];
7667c478bd9Sstevel@tonic-gate 
7677c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC))
7687c478bd9Sstevel@tonic-gate 		return (mdb_walk_dcmd("fmd_module", "fmd_module", argc, argv));
7697c478bd9Sstevel@tonic-gate 
7707c478bd9Sstevel@tonic-gate 	if (argc != 0)
7717c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
7727c478bd9Sstevel@tonic-gate 
7737c478bd9Sstevel@tonic-gate 	if (mdb_vread(&mod, sizeof (mod), addr) != sizeof (mod)) {
7747c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_module at %p", addr);
7757c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
7767c478bd9Sstevel@tonic-gate 	}
7777c478bd9Sstevel@tonic-gate 
7787c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
7797c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-11s %-16s %-11s %-4s %-?s %-16s%</u>\n",
7807c478bd9Sstevel@tonic-gate 		    "ADDR", "OPS", "DATA", "FLAG", "USTAT", "NAME");
7817c478bd9Sstevel@tonic-gate 	}
7827c478bd9Sstevel@tonic-gate 
7837c478bd9Sstevel@tonic-gate 	if (mdb_readstr(name, sizeof (name), (uintptr_t)mod.mod_name) <= 0)
7847c478bd9Sstevel@tonic-gate 		(void) mdb_snprintf(name, sizeof (name), "<%p>", mod.mod_name);
7857c478bd9Sstevel@tonic-gate 
7867c478bd9Sstevel@tonic-gate 	mdb_printf("%-11p %-16a %-11p 0x%02x %-?p %s\n", addr,
7877c478bd9Sstevel@tonic-gate 	    mod.mod_ops, mod.mod_data, mod.mod_flags, mod.mod_ustat, name);
7887c478bd9Sstevel@tonic-gate 
7897c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
7907c478bd9Sstevel@tonic-gate }
7917c478bd9Sstevel@tonic-gate 
7927c478bd9Sstevel@tonic-gate static int
case_walk_init(mdb_walk_state_t * wsp)7937c478bd9Sstevel@tonic-gate case_walk_init(mdb_walk_state_t *wsp)
7947c478bd9Sstevel@tonic-gate {
7957c478bd9Sstevel@tonic-gate 	fmd_module_t mod;
7967c478bd9Sstevel@tonic-gate 	fmd_case_hash_t ch;
7977c478bd9Sstevel@tonic-gate 	fmd_t F;
7987c478bd9Sstevel@tonic-gate 
799940f2f58SToomas Soome 	if (wsp->walk_addr != 0) {
8007c478bd9Sstevel@tonic-gate 		if (mdb_vread(&mod, sizeof (mod), wsp->walk_addr) == -1) {
8017c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read module at %p", wsp->walk_addr);
8027c478bd9Sstevel@tonic-gate 			return (WALK_ERR);
8037c478bd9Sstevel@tonic-gate 		}
8047c478bd9Sstevel@tonic-gate 
8057c478bd9Sstevel@tonic-gate 		wsp->walk_addr = (uintptr_t)mod.mod_cases.l_next;
8067c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
8077c478bd9Sstevel@tonic-gate 	}
8087c478bd9Sstevel@tonic-gate 
8097c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&F, "fmd") != sizeof (F) ||
8107c478bd9Sstevel@tonic-gate 	    mdb_vread(&ch, sizeof (ch), (uintptr_t)F.d_cases) != sizeof (ch)) {
8117c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd meta-data");
8127c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
8137c478bd9Sstevel@tonic-gate 	}
8147c478bd9Sstevel@tonic-gate 
8157c478bd9Sstevel@tonic-gate 	return (hash_walk_init(wsp, (uintptr_t)ch.ch_hash, ch.ch_hashlen,
8167c478bd9Sstevel@tonic-gate 	    "fmd_case", sizeof (fmd_case_impl_t),
8177c478bd9Sstevel@tonic-gate 	    OFFSETOF(fmd_case_impl_t, ci_next)));
8187c478bd9Sstevel@tonic-gate }
8197c478bd9Sstevel@tonic-gate 
8207c478bd9Sstevel@tonic-gate static int
case_walk_step(mdb_walk_state_t * wsp)8217c478bd9Sstevel@tonic-gate case_walk_step(mdb_walk_state_t *wsp)
8227c478bd9Sstevel@tonic-gate {
8237c478bd9Sstevel@tonic-gate 	uintptr_t addr = wsp->walk_addr;
8247c478bd9Sstevel@tonic-gate 	fmd_case_impl_t ci;
8257c478bd9Sstevel@tonic-gate 
8267c478bd9Sstevel@tonic-gate 	if (wsp->walk_data != NULL)
8277c478bd9Sstevel@tonic-gate 		return (hash_walk_step(wsp));
8287c478bd9Sstevel@tonic-gate 
829940f2f58SToomas Soome 	if (addr == 0)
8307c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
8317c478bd9Sstevel@tonic-gate 
8327c478bd9Sstevel@tonic-gate 	if (mdb_vread(&ci, sizeof (ci), addr) != sizeof (ci)) {
8337c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_case at %p", addr);
8347c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
8357c478bd9Sstevel@tonic-gate 	}
8367c478bd9Sstevel@tonic-gate 
8377c478bd9Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)ci.ci_list.l_next;
8387c478bd9Sstevel@tonic-gate 	return (wsp->walk_callback(addr, &ci, wsp->walk_cbdata));
8397c478bd9Sstevel@tonic-gate }
8407c478bd9Sstevel@tonic-gate 
8417c478bd9Sstevel@tonic-gate static void
case_walk_fini(mdb_walk_state_t * wsp)8427c478bd9Sstevel@tonic-gate case_walk_fini(mdb_walk_state_t *wsp)
8437c478bd9Sstevel@tonic-gate {
8447c478bd9Sstevel@tonic-gate 	if (wsp->walk_data != NULL)
8457c478bd9Sstevel@tonic-gate 		hash_walk_fini(wsp);
8467c478bd9Sstevel@tonic-gate }
8477c478bd9Sstevel@tonic-gate 
8487c478bd9Sstevel@tonic-gate static int
fmd_case(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)8497c478bd9Sstevel@tonic-gate fmd_case(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
8507c478bd9Sstevel@tonic-gate {
8517c478bd9Sstevel@tonic-gate 	char uuid[48], name[16];
8527c478bd9Sstevel@tonic-gate 	fmd_case_impl_t ci;
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
8557c478bd9Sstevel@tonic-gate 		if (mdb_walk_dcmd("fmd_case", "fmd_case", argc, argv) != 0) {
8567c478bd9Sstevel@tonic-gate 			mdb_warn("failed to walk fmd_case hash");
8577c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
8587c478bd9Sstevel@tonic-gate 		}
8597c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
8607c478bd9Sstevel@tonic-gate 	}
8617c478bd9Sstevel@tonic-gate 
8627c478bd9Sstevel@tonic-gate 	if (mdb_vread(&ci, sizeof (ci), addr) != sizeof (ci)) {
8637c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_case at %p", addr);
8647c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
8657c478bd9Sstevel@tonic-gate 	}
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
8687c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-11s %-5s %-3s %-?s %-36s%</u>\n",
8697c478bd9Sstevel@tonic-gate 		    "ADDR", "STATE", "REF", "DATA", "UUID");
8707c478bd9Sstevel@tonic-gate 	}
8717c478bd9Sstevel@tonic-gate 
8727c478bd9Sstevel@tonic-gate 	if (mdb_readstr(uuid, sizeof (uuid), (uintptr_t)ci.ci_uuid) <= 0)
8737c478bd9Sstevel@tonic-gate 		(void) mdb_snprintf(uuid, sizeof (uuid), "<%p>", ci.ci_uuid);
8747c478bd9Sstevel@tonic-gate 
8757c478bd9Sstevel@tonic-gate 	switch (ci.ci_state) {
8767c478bd9Sstevel@tonic-gate 	case FMD_CASE_UNSOLVED:
8777c478bd9Sstevel@tonic-gate 		(void) strcpy(name, "UNSLV");
8787c478bd9Sstevel@tonic-gate 		break;
8797c478bd9Sstevel@tonic-gate 	case FMD_CASE_SOLVED:
8807c478bd9Sstevel@tonic-gate 		(void) strcpy(name, "SOLVE");
8817c478bd9Sstevel@tonic-gate 		break;
882d9638e54Smws 	case FMD_CASE_CLOSE_WAIT:
883d9638e54Smws 		(void) strcpy(name, "CWAIT");
884d9638e54Smws 		break;
8857c478bd9Sstevel@tonic-gate 	case FMD_CASE_CLOSED:
8867c478bd9Sstevel@tonic-gate 		(void) strcpy(name, "CLOSE");
8877c478bd9Sstevel@tonic-gate 		break;
888d9638e54Smws 	case FMD_CASE_REPAIRED:
889d9638e54Smws 		(void) strcpy(name, "RPAIR");
890d9638e54Smws 		break;
891f6e214c7SGavin Maltby 	case FMD_CASE_RESOLVED:
892f6e214c7SGavin Maltby 		(void) strcpy(name, "RSLVD");
893f6e214c7SGavin Maltby 		break;
8947c478bd9Sstevel@tonic-gate 	default:
8957c478bd9Sstevel@tonic-gate 		(void) mdb_snprintf(name, sizeof (name), "%u", ci.ci_state);
8967c478bd9Sstevel@tonic-gate 	}
8977c478bd9Sstevel@tonic-gate 
8987c478bd9Sstevel@tonic-gate 	mdb_printf("%-11p %-5s %-3u %-?p %s\n",
8997c478bd9Sstevel@tonic-gate 	    addr, name, ci.ci_refs, ci.ci_data, uuid);
9007c478bd9Sstevel@tonic-gate 
9017c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
9027c478bd9Sstevel@tonic-gate }
9037c478bd9Sstevel@tonic-gate 
9047c478bd9Sstevel@tonic-gate static int
buf_walk_init(mdb_walk_state_t * wsp)9057c478bd9Sstevel@tonic-gate buf_walk_init(mdb_walk_state_t *wsp)
9067c478bd9Sstevel@tonic-gate {
9077c478bd9Sstevel@tonic-gate 	fmd_buf_hash_t bh;
9087c478bd9Sstevel@tonic-gate 
9097c478bd9Sstevel@tonic-gate 	if (mdb_vread(&bh, sizeof (bh), wsp->walk_addr) != sizeof (bh)) {
9107c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_buf_hash_t at %p", wsp->walk_addr);
9117c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
9127c478bd9Sstevel@tonic-gate 	}
9137c478bd9Sstevel@tonic-gate 
9147c478bd9Sstevel@tonic-gate 	return (hash_walk_init(wsp, (uintptr_t)bh.bh_hash, bh.bh_hashlen,
9157c478bd9Sstevel@tonic-gate 	    "fmd_buf", sizeof (fmd_buf_t), OFFSETOF(fmd_buf_t, buf_next)));
9167c478bd9Sstevel@tonic-gate }
9177c478bd9Sstevel@tonic-gate 
9187c478bd9Sstevel@tonic-gate /*ARGSUSED*/
9197c478bd9Sstevel@tonic-gate static int
fmd_buf(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)9207c478bd9Sstevel@tonic-gate fmd_buf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
9217c478bd9Sstevel@tonic-gate {
9226cb1ca52Saf 	char name[PATH_MAX];
9237c478bd9Sstevel@tonic-gate 	fmd_buf_t b;
9247c478bd9Sstevel@tonic-gate 
9257c478bd9Sstevel@tonic-gate 	if (argc != 0 || !(flags & DCMD_ADDRSPEC))
9267c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
9277c478bd9Sstevel@tonic-gate 
9287c478bd9Sstevel@tonic-gate 	if (mdb_vread(&b, sizeof (b), addr) != sizeof (b)) {
9297c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_buf at %p", addr);
9307c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
9317c478bd9Sstevel@tonic-gate 	}
9327c478bd9Sstevel@tonic-gate 
9337c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
9347c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-11s %-32s %-5s %-?s %s%</u>\n",
9357c478bd9Sstevel@tonic-gate 		    "ADDR", "NAME", "FLAGS", "DATA", "SIZE");
9367c478bd9Sstevel@tonic-gate 	}
9377c478bd9Sstevel@tonic-gate 
9387c478bd9Sstevel@tonic-gate 	if (mdb_readstr(name, sizeof (name), (uintptr_t)b.buf_name) <= 0)
9397c478bd9Sstevel@tonic-gate 		(void) mdb_snprintf(name, sizeof (name), "<%p>", b.buf_name);
9407c478bd9Sstevel@tonic-gate 
9417c478bd9Sstevel@tonic-gate 	mdb_printf("%-11p %-32s %-#5x %-?p %lu\n",
9427c478bd9Sstevel@tonic-gate 	    addr, name, b.buf_flags, b.buf_data, b.buf_size);
9437c478bd9Sstevel@tonic-gate 
9447c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
9457c478bd9Sstevel@tonic-gate }
9467c478bd9Sstevel@tonic-gate 
9477c478bd9Sstevel@tonic-gate static int
serd_walk_init(mdb_walk_state_t * wsp)9487c478bd9Sstevel@tonic-gate serd_walk_init(mdb_walk_state_t *wsp)
9497c478bd9Sstevel@tonic-gate {
9507c478bd9Sstevel@tonic-gate 	fmd_serd_hash_t sh;
9517c478bd9Sstevel@tonic-gate 
9527c478bd9Sstevel@tonic-gate 	if (mdb_vread(&sh, sizeof (sh), wsp->walk_addr) != sizeof (sh)) {
9537c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_serd_hash at %p", wsp->walk_addr);
9547c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
9557c478bd9Sstevel@tonic-gate 	}
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate 	return (hash_walk_init(wsp, (uintptr_t)sh.sh_hash, sh.sh_hashlen,
9587c478bd9Sstevel@tonic-gate 	    "fmd_serd_eng", sizeof (fmd_serd_eng_t),
9597c478bd9Sstevel@tonic-gate 	    OFFSETOF(fmd_serd_eng_t, sg_next)));
9607c478bd9Sstevel@tonic-gate }
9617c478bd9Sstevel@tonic-gate 
9626cb1ca52Saf /* ARGSUSED */
9636cb1ca52Saf static int
module_serd(uintptr_t addr,const void * data,void * wsp)9646cb1ca52Saf module_serd(uintptr_t addr, const void *data, void *wsp)
9656cb1ca52Saf {
9666cb1ca52Saf 	fmd_module_t *modp = (fmd_module_t *)data;
9676cb1ca52Saf 
9686cb1ca52Saf 	if (modp->mod_serds.sh_count != 0) {
9696cb1ca52Saf 		modp = (fmd_module_t *)addr;
9706cb1ca52Saf 		(void) mdb_pwalk_dcmd("fmd_serd", "fmd_serd", 0, 0,
9716cb1ca52Saf 		    (uintptr_t)&modp->mod_serds);
9726cb1ca52Saf 	}
9736cb1ca52Saf 	return (WALK_NEXT);
9746cb1ca52Saf }
9756cb1ca52Saf 
9767c478bd9Sstevel@tonic-gate /*ARGSUSED*/
9777c478bd9Sstevel@tonic-gate static int
fmd_serd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)9787c478bd9Sstevel@tonic-gate fmd_serd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
9797c478bd9Sstevel@tonic-gate {
9806cb1ca52Saf 	char name[PATH_MAX];
9817c478bd9Sstevel@tonic-gate 	fmd_serd_eng_t sg;
9827c478bd9Sstevel@tonic-gate 
9836cb1ca52Saf 	if (argc != 0)
9847c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
9856cb1ca52Saf 	if (!(flags & DCMD_ADDRSPEC)) {
9866cb1ca52Saf 		if (mdb_walk("fmd_module", module_serd, 0) == -1) {
9876cb1ca52Saf 			mdb_warn("failed to walk 'fmd_module'");
9886cb1ca52Saf 			return (DCMD_ERR);
9896cb1ca52Saf 		}
9906cb1ca52Saf 		return (DCMD_OK);
9916cb1ca52Saf 	}
9927c478bd9Sstevel@tonic-gate 
9937c478bd9Sstevel@tonic-gate 	if (mdb_vread(&sg, sizeof (sg), addr) != sizeof (sg)) {
9947c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_serd_eng at %p", addr);
9957c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
9967c478bd9Sstevel@tonic-gate 	}
9977c478bd9Sstevel@tonic-gate 
9987c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
9997c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-11s %-32s %-3s F >%-2s %-16s%</u>\n",
10007c478bd9Sstevel@tonic-gate 		    "ADDR", "NAME", "CNT", "N", "T");
10017c478bd9Sstevel@tonic-gate 	}
10027c478bd9Sstevel@tonic-gate 
10037c478bd9Sstevel@tonic-gate 	if (mdb_readstr(name, sizeof (name), (uintptr_t)sg.sg_name) <= 0)
10047c478bd9Sstevel@tonic-gate 		(void) mdb_snprintf(name, sizeof (name), "<%p>", sg.sg_name);
10057c478bd9Sstevel@tonic-gate 
10067c478bd9Sstevel@tonic-gate 	mdb_printf("%-11p %-32s %-3u %c >%-2u %lluns\n",
10077c478bd9Sstevel@tonic-gate 	    addr, name, sg.sg_count, (sg.sg_flags & FMD_SERD_FIRED) ? 'F' : ' ',
10087c478bd9Sstevel@tonic-gate 	    sg.sg_n, (u_longlong_t)sg.sg_t);
10097c478bd9Sstevel@tonic-gate 
10107c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
10117c478bd9Sstevel@tonic-gate }
10127c478bd9Sstevel@tonic-gate 
10137c478bd9Sstevel@tonic-gate static int
asru_walk_init(mdb_walk_state_t * wsp)10147c478bd9Sstevel@tonic-gate asru_walk_init(mdb_walk_state_t *wsp)
10157c478bd9Sstevel@tonic-gate {
10167c478bd9Sstevel@tonic-gate 	fmd_asru_hash_t ah;
10177c478bd9Sstevel@tonic-gate 	fmd_t F;
10187c478bd9Sstevel@tonic-gate 
1019940f2f58SToomas Soome 	if (wsp->walk_addr == 0 && mdb_readvar(&F, "fmd") != sizeof (F)) {
10207c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd meta-data");
10217c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
10227c478bd9Sstevel@tonic-gate 	}
10237c478bd9Sstevel@tonic-gate 
1024940f2f58SToomas Soome 	if (wsp->walk_addr == 0)
10257c478bd9Sstevel@tonic-gate 		wsp->walk_addr = (uintptr_t)F.d_asrus;
10267c478bd9Sstevel@tonic-gate 
10277c478bd9Sstevel@tonic-gate 	if (mdb_vread(&ah, sizeof (ah), wsp->walk_addr) != sizeof (ah)) {
10287c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read asru_hash at %p", wsp->walk_addr);
10297c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
10307c478bd9Sstevel@tonic-gate 	}
10317c478bd9Sstevel@tonic-gate 
10327c478bd9Sstevel@tonic-gate 	return (hash_walk_init(wsp, (uintptr_t)ah.ah_hash, ah.ah_hashlen,
10337c478bd9Sstevel@tonic-gate 	    "fmd_asru", sizeof (fmd_asru_t), OFFSETOF(fmd_asru_t, asru_next)));
10347c478bd9Sstevel@tonic-gate }
10357c478bd9Sstevel@tonic-gate 
10367c478bd9Sstevel@tonic-gate static int
fmd_asru(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)10377c478bd9Sstevel@tonic-gate fmd_asru(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
10387c478bd9Sstevel@tonic-gate {
10396cb1ca52Saf 	char uuid[48], name[PATH_MAX];
10407c478bd9Sstevel@tonic-gate 	fmd_asru_t a;
10417c478bd9Sstevel@tonic-gate 
10427c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
10437c478bd9Sstevel@tonic-gate 		if (mdb_walk_dcmd("fmd_asru", "fmd_asru", argc, argv) != 0) {
10447c478bd9Sstevel@tonic-gate 			mdb_warn("failed to walk fmd_asru hash");
10457c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
10467c478bd9Sstevel@tonic-gate 		}
10477c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
10487c478bd9Sstevel@tonic-gate 	}
10497c478bd9Sstevel@tonic-gate 
10507c478bd9Sstevel@tonic-gate 	if (mdb_vread(&a, sizeof (a), addr) != sizeof (a)) {
10517c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_asru at %p", addr);
10527c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
10537c478bd9Sstevel@tonic-gate 	}
10547c478bd9Sstevel@tonic-gate 
10557c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags))
10567c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-8s %-36s %s%</u>\n", "ADDR", "UUID", "NAME");
10577c478bd9Sstevel@tonic-gate 
10587c478bd9Sstevel@tonic-gate 	if (mdb_readstr(uuid, sizeof (uuid), (uintptr_t)a.asru_uuid) <= 0)
10597c478bd9Sstevel@tonic-gate 		(void) mdb_snprintf(uuid, sizeof (uuid), "<%p>", a.asru_uuid);
10607c478bd9Sstevel@tonic-gate 	if (mdb_readstr(name, sizeof (name), (uintptr_t)a.asru_name) <= 0)
10617c478bd9Sstevel@tonic-gate 		(void) mdb_snprintf(name, sizeof (name), "<%p>", a.asru_name);
10627c478bd9Sstevel@tonic-gate 
10637c478bd9Sstevel@tonic-gate 	mdb_printf("%-8p %-36s %s\n", addr, uuid, name);
10647c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
10657c478bd9Sstevel@tonic-gate }
10667c478bd9Sstevel@tonic-gate 
1067cbf75e67SStephen Hanson static int
al_walk_init(mdb_walk_state_t * wsp)1068cbf75e67SStephen Hanson al_walk_init(mdb_walk_state_t *wsp)
1069cbf75e67SStephen Hanson {
1070cbf75e67SStephen Hanson 	fmd_asru_hash_t ah;
1071cbf75e67SStephen Hanson 	fmd_t F;
1072cbf75e67SStephen Hanson 
1073940f2f58SToomas Soome 	if (wsp->walk_addr == 0 && mdb_readvar(&F, "fmd") != sizeof (F)) {
1074cbf75e67SStephen Hanson 		mdb_warn("failed to read fmd meta-data");
1075cbf75e67SStephen Hanson 		return (WALK_ERR);
1076cbf75e67SStephen Hanson 	}
1077cbf75e67SStephen Hanson 
1078940f2f58SToomas Soome 	if (wsp->walk_addr == 0)
1079cbf75e67SStephen Hanson 		wsp->walk_addr = (uintptr_t)F.d_asrus;
1080cbf75e67SStephen Hanson 
1081cbf75e67SStephen Hanson 	if (mdb_vread(&ah, sizeof (ah), wsp->walk_addr) != sizeof (ah)) {
1082cbf75e67SStephen Hanson 		mdb_warn("failed to read asru_hash at %p", wsp->walk_addr);
1083cbf75e67SStephen Hanson 		return (WALK_ERR);
1084cbf75e67SStephen Hanson 	}
1085cbf75e67SStephen Hanson 
1086cbf75e67SStephen Hanson 	return (hash_walk_init(wsp, (uintptr_t)ah.ah_rsrc_hash, ah.ah_hashlen,
1087cbf75e67SStephen Hanson 	    "fmd_asru_link", sizeof (fmd_asru_link_t), OFFSETOF(fmd_asru_link_t,
1088cbf75e67SStephen Hanson 	    al_rsrc_next)));
1089cbf75e67SStephen Hanson }
1090cbf75e67SStephen Hanson 
1091cbf75e67SStephen Hanson static int
fmd_asru_link(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1092cbf75e67SStephen Hanson fmd_asru_link(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1093cbf75e67SStephen Hanson {
1094cbf75e67SStephen Hanson 	char uuid[48], name[PATH_MAX];
1095cbf75e67SStephen Hanson 	fmd_asru_link_t a;
1096cbf75e67SStephen Hanson 
1097cbf75e67SStephen Hanson 	if (!(flags & DCMD_ADDRSPEC)) {
1098cbf75e67SStephen Hanson 		if (mdb_walk_dcmd("fmd_asru_link", "fmd_asru_link", argc,
1099cbf75e67SStephen Hanson 		    argv) != 0) {
1100cbf75e67SStephen Hanson 			mdb_warn("failed to walk fmd_asru_link hash");
1101cbf75e67SStephen Hanson 			return (DCMD_ERR);
1102cbf75e67SStephen Hanson 		}
1103cbf75e67SStephen Hanson 		return (DCMD_OK);
1104cbf75e67SStephen Hanson 	}
1105cbf75e67SStephen Hanson 
1106cbf75e67SStephen Hanson 	if (mdb_vread(&a, sizeof (a), addr) != sizeof (a)) {
1107cbf75e67SStephen Hanson 		mdb_warn("failed to read fmd_asru_link at %p", addr);
1108cbf75e67SStephen Hanson 		return (DCMD_ERR);
1109cbf75e67SStephen Hanson 	}
1110cbf75e67SStephen Hanson 
1111cbf75e67SStephen Hanson 	if (DCMD_HDRSPEC(flags))
1112cbf75e67SStephen Hanson 		mdb_printf("%<u>%-8s %-36s %s%</u>\n", "ADDR", "UUID", "NAME");
1113cbf75e67SStephen Hanson 
1114cbf75e67SStephen Hanson 	if (mdb_readstr(uuid, sizeof (uuid), (uintptr_t)a.al_uuid) <= 0)
1115cbf75e67SStephen Hanson 		(void) mdb_snprintf(uuid, sizeof (uuid), "<%p>", a.al_uuid);
1116cbf75e67SStephen Hanson 	if (mdb_readstr(name, sizeof (name), (uintptr_t)a.al_rsrc_name) <= 0)
1117cbf75e67SStephen Hanson 		(void) mdb_snprintf(name, sizeof (name), "<%p>",
1118cbf75e67SStephen Hanson 		    a.al_rsrc_name);
1119cbf75e67SStephen Hanson 
1120cbf75e67SStephen Hanson 	mdb_printf("%-8p %-36s %s\n", addr, uuid, name);
1121cbf75e67SStephen Hanson 	return (DCMD_OK);
1122cbf75e67SStephen Hanson }
1123cbf75e67SStephen Hanson 
11247c478bd9Sstevel@tonic-gate /*ARGSUSED*/
11257c478bd9Sstevel@tonic-gate static int
fcf_hdr(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)11267c478bd9Sstevel@tonic-gate fcf_hdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
11277c478bd9Sstevel@tonic-gate {
11287c478bd9Sstevel@tonic-gate 	fcf_hdr_t h;
11297c478bd9Sstevel@tonic-gate 
11307c478bd9Sstevel@tonic-gate 	if (argc != 0)
11317c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
11327c478bd9Sstevel@tonic-gate 
11337c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC))
11347c478bd9Sstevel@tonic-gate 		addr = 0; /* assume base of file in file target */
11357c478bd9Sstevel@tonic-gate 
11367c478bd9Sstevel@tonic-gate 	if (mdb_vread(&h, sizeof (h), addr) != sizeof (h)) {
11377c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read header at %p", addr);
11387c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
11397c478bd9Sstevel@tonic-gate 	}
11407c478bd9Sstevel@tonic-gate 
11417c478bd9Sstevel@tonic-gate 	mdb_printf("fcfh_ident.id_magic = 0x%x, %c, %c, %c\n",
11427c478bd9Sstevel@tonic-gate 	    h.fcfh_ident[FCF_ID_MAG0], h.fcfh_ident[FCF_ID_MAG1],
11437c478bd9Sstevel@tonic-gate 	    h.fcfh_ident[FCF_ID_MAG2], h.fcfh_ident[FCF_ID_MAG3]);
11447c478bd9Sstevel@tonic-gate 
11457c478bd9Sstevel@tonic-gate 	switch (h.fcfh_ident[FCF_ID_MODEL]) {
11467c478bd9Sstevel@tonic-gate 	case FCF_MODEL_ILP32:
11477c478bd9Sstevel@tonic-gate 		mdb_printf("fcfh_ident.id_model = ILP32\n");
11487c478bd9Sstevel@tonic-gate 		break;
11497c478bd9Sstevel@tonic-gate 	case FCF_MODEL_LP64:
11507c478bd9Sstevel@tonic-gate 		mdb_printf("fcfh_ident.id_model = LP64\n");
11517c478bd9Sstevel@tonic-gate 		break;
11527c478bd9Sstevel@tonic-gate 	default:
11537c478bd9Sstevel@tonic-gate 		mdb_printf("fcfh_ident.id_model = 0x%x\n",
11547c478bd9Sstevel@tonic-gate 		    h.fcfh_ident[FCF_ID_MODEL]);
11557c478bd9Sstevel@tonic-gate 	}
11567c478bd9Sstevel@tonic-gate 
11577c478bd9Sstevel@tonic-gate 	switch (h.fcfh_ident[FCF_ID_ENCODING]) {
11587c478bd9Sstevel@tonic-gate 	case FCF_ENCODE_LSB:
11597c478bd9Sstevel@tonic-gate 		mdb_printf("fcfh_ident.id_encoding = LSB\n");
11607c478bd9Sstevel@tonic-gate 		break;
11617c478bd9Sstevel@tonic-gate 	case FCF_ENCODE_MSB:
11627c478bd9Sstevel@tonic-gate 		mdb_printf("fcfh_ident.id_encoding = MSB\n");
11637c478bd9Sstevel@tonic-gate 		break;
11647c478bd9Sstevel@tonic-gate 	default:
11657c478bd9Sstevel@tonic-gate 		mdb_printf("fcfh_ident.id_encoding = 0x%x\n",
11667c478bd9Sstevel@tonic-gate 		    h.fcfh_ident[FCF_ID_ENCODING]);
11677c478bd9Sstevel@tonic-gate 	}
11687c478bd9Sstevel@tonic-gate 
11697c478bd9Sstevel@tonic-gate 	mdb_printf("fcfh_ident.id_version = %u\n",
11707c478bd9Sstevel@tonic-gate 	    h.fcfh_ident[FCF_ID_VERSION]);
11717c478bd9Sstevel@tonic-gate 
11727c478bd9Sstevel@tonic-gate 	mdb_printf("fcfh_flags = 0x%x\n", h.fcfh_flags);
11737c478bd9Sstevel@tonic-gate 	mdb_printf("fcfh_hdrsize = %u\n", h.fcfh_hdrsize);
11747c478bd9Sstevel@tonic-gate 	mdb_printf("fcfh_secsize = %u\n", h.fcfh_secsize);
11757c478bd9Sstevel@tonic-gate 	mdb_printf("fcfh_secnum = %u\n", h.fcfh_secnum);
11767c478bd9Sstevel@tonic-gate 	mdb_printf("fcfh_secoff = %llu\n", h.fcfh_secoff);
11777c478bd9Sstevel@tonic-gate 	mdb_printf("fcfh_filesz = %llu\n", h.fcfh_filesz);
11787c478bd9Sstevel@tonic-gate 	mdb_printf("fcfh_cgen = %llu\n", h.fcfh_cgen);
11797c478bd9Sstevel@tonic-gate 
11807c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
11817c478bd9Sstevel@tonic-gate }
11827c478bd9Sstevel@tonic-gate 
1183d67944fbSScott Rotondo static int fcf_sec(uintptr_t, uint_t, int, const mdb_arg_t *);
11847c478bd9Sstevel@tonic-gate /*ARGSUSED*/
11857c478bd9Sstevel@tonic-gate static int
fcf_sec_one(uintptr_t addr,void * ignored,uint_t * secp)11867c478bd9Sstevel@tonic-gate fcf_sec_one(uintptr_t addr, void *ignored, uint_t *secp)
11877c478bd9Sstevel@tonic-gate {
11887c478bd9Sstevel@tonic-gate 
11897c478bd9Sstevel@tonic-gate 	mdb_printf("%3d ", (*secp)++);
11907c478bd9Sstevel@tonic-gate 	(void) fcf_sec(addr, DCMD_ADDRSPEC | DCMD_LOOP, 0, NULL);
11917c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
11927c478bd9Sstevel@tonic-gate }
11937c478bd9Sstevel@tonic-gate 
11947c478bd9Sstevel@tonic-gate /*ARGSUSED*/
11957c478bd9Sstevel@tonic-gate static int
fcf_sec(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)11967c478bd9Sstevel@tonic-gate fcf_sec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
11977c478bd9Sstevel@tonic-gate {
11987c478bd9Sstevel@tonic-gate 	static const char *const types[] = {
11997c478bd9Sstevel@tonic-gate 		"none",		/* FCF_SECT_NONE */
12007c478bd9Sstevel@tonic-gate 		"strtab",	/* FCF_SECT_STRTAB */
12017c478bd9Sstevel@tonic-gate 		"module",	/* FCF_SECT_MODULE */
12027c478bd9Sstevel@tonic-gate 		"case",		/* FCF_SECT_CASE */
12037c478bd9Sstevel@tonic-gate 		"bufs",		/* FCF_SECT_BUFS */
12047c478bd9Sstevel@tonic-gate 		"buffer",	/* FCF_SECT_BUFFER */
12057c478bd9Sstevel@tonic-gate 		"serd",		/* FCF_SECT_SERD */
12067c478bd9Sstevel@tonic-gate 		"events",	/* FCF_SECT_EVENTS */
12077c478bd9Sstevel@tonic-gate 		"nvlists",	/* FCF_SECT_NVLISTS */
12087c478bd9Sstevel@tonic-gate 	};
12097c478bd9Sstevel@tonic-gate 
12107c478bd9Sstevel@tonic-gate 	uint_t sec = 0;
12117c478bd9Sstevel@tonic-gate 	fcf_sec_t s;
12127c478bd9Sstevel@tonic-gate 
12137c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC))
12147c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-3s ", "NDX");
12157c478bd9Sstevel@tonic-gate 
12167c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC) || DCMD_HDRSPEC(flags)) {
12177c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%?s %-10s %-5s %-5s %-5s %-6s %-5s%</u>\n",
12187c478bd9Sstevel@tonic-gate 		    "ADDR", "TYPE", "ALIGN", "FLAGS", "ENTSZ", "OFF", "SIZE");
12197c478bd9Sstevel@tonic-gate 	}
12207c478bd9Sstevel@tonic-gate 
12217c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
12227c478bd9Sstevel@tonic-gate 		if (mdb_walk("fcf_sec", (mdb_walk_cb_t)fcf_sec_one, &sec) < 0) {
12237c478bd9Sstevel@tonic-gate 			mdb_warn("failed to walk fcf_sec");
12247c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
12257c478bd9Sstevel@tonic-gate 		}
12267c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
12277c478bd9Sstevel@tonic-gate 	}
12287c478bd9Sstevel@tonic-gate 
12297c478bd9Sstevel@tonic-gate 	if (argc != 0)
12307c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
12317c478bd9Sstevel@tonic-gate 
12327c478bd9Sstevel@tonic-gate 	if (mdb_vread(&s, sizeof (s), addr) != sizeof (s)) {
12337c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read section header at %p", addr);
12347c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
12357c478bd9Sstevel@tonic-gate 	}
12367c478bd9Sstevel@tonic-gate 
12377c478bd9Sstevel@tonic-gate 	mdb_printf("%?p ", addr);
12387c478bd9Sstevel@tonic-gate 
12397c478bd9Sstevel@tonic-gate 	if (s.fcfs_type < sizeof (types) / sizeof (types[0]))
12407c478bd9Sstevel@tonic-gate 		mdb_printf("%-10s ", types[s.fcfs_type]);
12417c478bd9Sstevel@tonic-gate 	else
12427c478bd9Sstevel@tonic-gate 		mdb_printf("%-10u ", s.fcfs_type);
12437c478bd9Sstevel@tonic-gate 
12447c478bd9Sstevel@tonic-gate 	mdb_printf("%-5u %-#5x %-#5x %-6llx %-#5llx\n", s.fcfs_align,
12457c478bd9Sstevel@tonic-gate 	    s.fcfs_flags, s.fcfs_entsize, s.fcfs_offset, s.fcfs_size);
12467c478bd9Sstevel@tonic-gate 
12477c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
12487c478bd9Sstevel@tonic-gate }
12497c478bd9Sstevel@tonic-gate 
12507c478bd9Sstevel@tonic-gate static int
fcf_sec_walk_init(mdb_walk_state_t * wsp)12517c478bd9Sstevel@tonic-gate fcf_sec_walk_init(mdb_walk_state_t *wsp)
12527c478bd9Sstevel@tonic-gate {
12537c478bd9Sstevel@tonic-gate 	fcf_hdr_t h, *hp;
12547c478bd9Sstevel@tonic-gate 	size_t size;
12557c478bd9Sstevel@tonic-gate 
12567c478bd9Sstevel@tonic-gate 	if (mdb_vread(&h, sizeof (h), wsp->walk_addr) != sizeof (h)) {
12577c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read FCF header at %p", wsp->walk_addr);
12587c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
12597c478bd9Sstevel@tonic-gate 	}
12607c478bd9Sstevel@tonic-gate 
12617c478bd9Sstevel@tonic-gate 	size = sizeof (fcf_hdr_t) + sizeof (fcf_sec_t) * h.fcfh_secnum;
12627c478bd9Sstevel@tonic-gate 	hp = mdb_alloc(size, UM_SLEEP);
12637c478bd9Sstevel@tonic-gate 
12647c478bd9Sstevel@tonic-gate 	if (mdb_vread(hp, size, wsp->walk_addr) != size) {
12657c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read FCF sections at %p", wsp->walk_addr);
12667c478bd9Sstevel@tonic-gate 		mdb_free(hp, size);
12677c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
12687c478bd9Sstevel@tonic-gate 	}
12697c478bd9Sstevel@tonic-gate 
12707c478bd9Sstevel@tonic-gate 	wsp->walk_data = hp;
12717c478bd9Sstevel@tonic-gate 	wsp->walk_arg = 0;
12727c478bd9Sstevel@tonic-gate 
12737c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
12747c478bd9Sstevel@tonic-gate }
12757c478bd9Sstevel@tonic-gate 
12767c478bd9Sstevel@tonic-gate static int
fcf_sec_walk_step(mdb_walk_state_t * wsp)12777c478bd9Sstevel@tonic-gate fcf_sec_walk_step(mdb_walk_state_t *wsp)
12787c478bd9Sstevel@tonic-gate {
12797c478bd9Sstevel@tonic-gate 	uint_t i = (uint_t)wsp->walk_arg;
12807c478bd9Sstevel@tonic-gate 	size_t off = sizeof (fcf_hdr_t) + sizeof (fcf_sec_t) * i;
12817c478bd9Sstevel@tonic-gate 	fcf_hdr_t *hp = wsp->walk_data;
12827c478bd9Sstevel@tonic-gate 	fcf_sec_t *sp = (fcf_sec_t *)((uintptr_t)hp + off);
12837c478bd9Sstevel@tonic-gate 
12847c478bd9Sstevel@tonic-gate 	if (i >= hp->fcfh_secnum)
12857c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
12867c478bd9Sstevel@tonic-gate 
12877c478bd9Sstevel@tonic-gate 	wsp->walk_arg = (void *)(i + 1);
12887c478bd9Sstevel@tonic-gate 	return (wsp->walk_callback(wsp->walk_addr + off, sp, wsp->walk_cbdata));
12897c478bd9Sstevel@tonic-gate }
12907c478bd9Sstevel@tonic-gate 
12917c478bd9Sstevel@tonic-gate static void
fcf_sec_walk_fini(mdb_walk_state_t * wsp)12927c478bd9Sstevel@tonic-gate fcf_sec_walk_fini(mdb_walk_state_t *wsp)
12937c478bd9Sstevel@tonic-gate {
12947c478bd9Sstevel@tonic-gate 	fcf_hdr_t *hp = wsp->walk_data;
12957c478bd9Sstevel@tonic-gate 	mdb_free(hp, sizeof (fcf_hdr_t) + sizeof (fcf_sec_t) * hp->fcfh_secnum);
12967c478bd9Sstevel@tonic-gate }
12977c478bd9Sstevel@tonic-gate 
12987c478bd9Sstevel@tonic-gate /*ARGSUSED*/
12997c478bd9Sstevel@tonic-gate static int
fcf_case(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)13007c478bd9Sstevel@tonic-gate fcf_case(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
13017c478bd9Sstevel@tonic-gate {
13027c478bd9Sstevel@tonic-gate 	fcf_case_t fcfc;
13037c478bd9Sstevel@tonic-gate 
13047c478bd9Sstevel@tonic-gate 	if (argc != 0)
13057c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
13067c478bd9Sstevel@tonic-gate 
13077c478bd9Sstevel@tonic-gate 	if (mdb_vread(&fcfc, sizeof (fcfc), addr) != sizeof (fcfc)) {
13087c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read case at %p", addr);
13097c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
13107c478bd9Sstevel@tonic-gate 	}
13117c478bd9Sstevel@tonic-gate 
13127c478bd9Sstevel@tonic-gate 	mdb_printf("fcfc_uuid = 0x%x\n", fcfc.fcfc_uuid);
13137c478bd9Sstevel@tonic-gate 	mdb_printf("fcfc_state = %u\n", fcfc.fcfc_state);
13147c478bd9Sstevel@tonic-gate 	mdb_printf("fcfc_bufs = %u\n", fcfc.fcfc_bufs);
13157c478bd9Sstevel@tonic-gate 	mdb_printf("fcfc_events = %u\n", fcfc.fcfc_events);
13167c478bd9Sstevel@tonic-gate 	mdb_printf("fcfc_suspects = %u\n", fcfc.fcfc_suspects);
13177c478bd9Sstevel@tonic-gate 
13187c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
13197c478bd9Sstevel@tonic-gate }
13207c478bd9Sstevel@tonic-gate 
13217c478bd9Sstevel@tonic-gate /*ARGSUSED*/
13227c478bd9Sstevel@tonic-gate static int
fcf_event(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)13237c478bd9Sstevel@tonic-gate fcf_event(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
13247c478bd9Sstevel@tonic-gate {
13257c478bd9Sstevel@tonic-gate 	fcf_event_t fcfe;
13267c478bd9Sstevel@tonic-gate 
13277c478bd9Sstevel@tonic-gate 	if (argc != 0)
13287c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
13297c478bd9Sstevel@tonic-gate 
13307c478bd9Sstevel@tonic-gate 	if (mdb_vread(&fcfe, sizeof (fcfe), addr) != sizeof (fcfe)) {
13317c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read event at %p", addr);
13327c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
13337c478bd9Sstevel@tonic-gate 	}
13347c478bd9Sstevel@tonic-gate 
13357c478bd9Sstevel@tonic-gate 	mdb_printf("fcfe_todsec = %llu (%Y)\n",
13367c478bd9Sstevel@tonic-gate 	    fcfe.fcfe_todsec, (time_t)fcfe.fcfe_todsec);
13377c478bd9Sstevel@tonic-gate 	mdb_printf("fcfe_todnsec = %llu\n", fcfe.fcfe_todnsec);
13387c478bd9Sstevel@tonic-gate 	mdb_printf("fcfe_major = %u\n", fcfe.fcfe_major);
13397c478bd9Sstevel@tonic-gate 	mdb_printf("fcfe_minor = %u\n", fcfe.fcfe_minor);
13407c478bd9Sstevel@tonic-gate 	mdb_printf("fcfe_inode = %llu\n", fcfe.fcfe_inode);
13417c478bd9Sstevel@tonic-gate 	mdb_printf("fcfe_offset = %llu\n", fcfe.fcfe_offset);
13427c478bd9Sstevel@tonic-gate 
13437c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
13447c478bd9Sstevel@tonic-gate }
13457c478bd9Sstevel@tonic-gate 
13467c478bd9Sstevel@tonic-gate /*ARGSUSED*/
13477c478bd9Sstevel@tonic-gate static int
fcf_serd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)13487c478bd9Sstevel@tonic-gate fcf_serd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
13497c478bd9Sstevel@tonic-gate {
13507c478bd9Sstevel@tonic-gate 	fcf_serd_t fcfd;
13517c478bd9Sstevel@tonic-gate 
13527c478bd9Sstevel@tonic-gate 	if (argc != 0)
13537c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
13547c478bd9Sstevel@tonic-gate 
13557c478bd9Sstevel@tonic-gate 	if (mdb_vread(&fcfd, sizeof (fcfd), addr) != sizeof (fcfd)) {
13567c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read serd at %p", addr);
13577c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
13587c478bd9Sstevel@tonic-gate 	}
13597c478bd9Sstevel@tonic-gate 
13607c478bd9Sstevel@tonic-gate 	mdb_printf("fcfd_name = 0x%x\n", fcfd.fcfd_name);
13617c478bd9Sstevel@tonic-gate 	mdb_printf("fcfd_events = %u\n", fcfd.fcfd_events);
13627c478bd9Sstevel@tonic-gate 	mdb_printf("fcfd_n = >%u\n", fcfd.fcfd_n);
13637c478bd9Sstevel@tonic-gate 	mdb_printf("fcfd_t = %lluns\n", fcfd.fcfd_t);
13647c478bd9Sstevel@tonic-gate 
13657c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
13667c478bd9Sstevel@tonic-gate }
13677c478bd9Sstevel@tonic-gate 
13687c478bd9Sstevel@tonic-gate static int
tmq_walk_init(mdb_walk_state_t * wsp)13697c478bd9Sstevel@tonic-gate tmq_walk_init(mdb_walk_state_t *wsp)
13707c478bd9Sstevel@tonic-gate {
13717c478bd9Sstevel@tonic-gate 	fmd_timerq_t tmq;
13727c478bd9Sstevel@tonic-gate 	fmd_t F;
13737c478bd9Sstevel@tonic-gate 
1374940f2f58SToomas Soome 	if (wsp->walk_addr == 0 && mdb_readvar(&F, "fmd") != sizeof (F)) {
13757c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd meta-data");
13767c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
13777c478bd9Sstevel@tonic-gate 	}
13787c478bd9Sstevel@tonic-gate 
1379940f2f58SToomas Soome 	if (wsp->walk_addr == 0)
13807c478bd9Sstevel@tonic-gate 		wsp->walk_addr = (uintptr_t)F.d_timers;
13817c478bd9Sstevel@tonic-gate 
13827c478bd9Sstevel@tonic-gate 	if (mdb_vread(&tmq, sizeof (tmq), wsp->walk_addr) != sizeof (tmq)) {
13837c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read timerq at %p", wsp->walk_addr);
13847c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
13857c478bd9Sstevel@tonic-gate 	}
13867c478bd9Sstevel@tonic-gate 
13877c478bd9Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)tmq.tmq_list.l_next;
13887c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
13897c478bd9Sstevel@tonic-gate }
13907c478bd9Sstevel@tonic-gate 
13917c478bd9Sstevel@tonic-gate static int
tmq_walk_step(mdb_walk_state_t * wsp)13927c478bd9Sstevel@tonic-gate tmq_walk_step(mdb_walk_state_t *wsp)
13937c478bd9Sstevel@tonic-gate {
13947c478bd9Sstevel@tonic-gate 	uintptr_t addr = wsp->walk_addr;
13957c478bd9Sstevel@tonic-gate 	fmd_timer_t tmr;
13967c478bd9Sstevel@tonic-gate 
1397940f2f58SToomas Soome 	if (addr == 0)
13987c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
13997c478bd9Sstevel@tonic-gate 
14007c478bd9Sstevel@tonic-gate 	if (mdb_vread(&tmr, sizeof (tmr), addr) != sizeof (tmr)) {
14017c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_timer at %p", addr);
14027c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
14037c478bd9Sstevel@tonic-gate 	}
14047c478bd9Sstevel@tonic-gate 
14057c478bd9Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)tmr.tmr_list.l_next;
14067c478bd9Sstevel@tonic-gate 	return (wsp->walk_callback(addr, &tmr, wsp->walk_cbdata));
14077c478bd9Sstevel@tonic-gate }
14087c478bd9Sstevel@tonic-gate 
14097c478bd9Sstevel@tonic-gate static int
fmd_timer(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)14107c478bd9Sstevel@tonic-gate fmd_timer(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
14117c478bd9Sstevel@tonic-gate {
14127c478bd9Sstevel@tonic-gate 	char name[32], func[MDB_SYM_NAMLEN];
14137c478bd9Sstevel@tonic-gate 	fmd_timer_t t;
14147c478bd9Sstevel@tonic-gate 
14157c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
14167c478bd9Sstevel@tonic-gate 		if (mdb_walk_dcmd("fmd_timerq", "fmd_timer", argc, argv) != 0) {
14177c478bd9Sstevel@tonic-gate 			mdb_warn("failed to walk fmd_timerq");
14187c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
14197c478bd9Sstevel@tonic-gate 		}
14207c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
14217c478bd9Sstevel@tonic-gate 	}
14227c478bd9Sstevel@tonic-gate 
14237c478bd9Sstevel@tonic-gate 	if (mdb_vread(&t, sizeof (t), addr) != sizeof (t)) {
14247c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read fmd_timer at %p", addr);
14257c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
14267c478bd9Sstevel@tonic-gate 	}
14277c478bd9Sstevel@tonic-gate 
14287c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
14297c478bd9Sstevel@tonic-gate 		mdb_printf("%<u>%-8s %-20s %-4s %-18s %-8s %s%</u>\n",
14307c478bd9Sstevel@tonic-gate 		    "ADDR", "MODULE", "ID", "HRTIME", "ARG", "FUNC");
14317c478bd9Sstevel@tonic-gate 	}
14327c478bd9Sstevel@tonic-gate 
14337c478bd9Sstevel@tonic-gate 	if (mdb_readstr(name, sizeof (name), (uintptr_t)
14347c478bd9Sstevel@tonic-gate 	    t.tmr_ids + OFFSETOF(fmd_idspace_t, ids_name)) <= 0)
14357c478bd9Sstevel@tonic-gate 		(void) mdb_snprintf(name, sizeof (name), "<%p>", t.tmr_ids);
14367c478bd9Sstevel@tonic-gate 
14377c478bd9Sstevel@tonic-gate 	if (mdb_lookup_by_addr((uintptr_t)t.tmr_func, MDB_SYM_FUZZY,
14387c478bd9Sstevel@tonic-gate 	    func, sizeof (func), NULL) != 0)
14397c478bd9Sstevel@tonic-gate 		(void) mdb_snprintf(func, sizeof (func), "<%p>", t.tmr_func);
14407c478bd9Sstevel@tonic-gate 
14417c478bd9Sstevel@tonic-gate 	mdb_printf("%-8p %-20s %4d 0x%-16llx %-8p %s\n",
14427c478bd9Sstevel@tonic-gate 	    addr, name, t.tmr_id, t.tmr_hrt, t.tmr_arg, func);
14437c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
14447c478bd9Sstevel@tonic-gate }
14457c478bd9Sstevel@tonic-gate 
1446d9638e54Smws static int
xprt_walk_init(mdb_walk_state_t * wsp)1447d9638e54Smws xprt_walk_init(mdb_walk_state_t *wsp)
1448d9638e54Smws {
1449d9638e54Smws 	fmd_module_t m;
1450d9638e54Smws 
1451940f2f58SToomas Soome 	if (wsp->walk_addr == 0) {
1452d9638e54Smws 		mdb_warn("transport walker requires fmd_module_t address\n");
1453d9638e54Smws 		return (WALK_ERR);
1454d9638e54Smws 	}
1455d9638e54Smws 
1456d9638e54Smws 	if (mdb_vread(&m, sizeof (m), wsp->walk_addr) != sizeof (m)) {
1457d9638e54Smws 		mdb_warn("failed to read module at %p", wsp->walk_addr);
1458d9638e54Smws 		return (WALK_ERR);
1459d9638e54Smws 	}
1460d9638e54Smws 
1461d9638e54Smws 	wsp->walk_addr = (uintptr_t)m.mod_transports.l_next;
1462d9638e54Smws 	return (WALK_NEXT);
1463d9638e54Smws }
1464d9638e54Smws 
1465d9638e54Smws static int
xprt_walk_step(mdb_walk_state_t * wsp)1466d9638e54Smws xprt_walk_step(mdb_walk_state_t *wsp)
1467d9638e54Smws {
1468d9638e54Smws 	uintptr_t addr = wsp->walk_addr;
1469d9638e54Smws 	fmd_xprt_impl_t xi;
1470d9638e54Smws 
1471940f2f58SToomas Soome 	if (addr == 0)
1472d9638e54Smws 		return (WALK_DONE);
1473d9638e54Smws 
1474d9638e54Smws 	if (mdb_vread(&xi, sizeof (xi), addr) != sizeof (xi)) {
1475d9638e54Smws 		mdb_warn("failed to read fmd_xprt at %p", addr);
1476d9638e54Smws 		return (WALK_ERR);
1477d9638e54Smws 	}
1478d9638e54Smws 
1479d9638e54Smws 	wsp->walk_addr = (uintptr_t)xi.xi_list.l_next;
1480d9638e54Smws 	return (wsp->walk_callback(addr, &xi, wsp->walk_cbdata));
1481d9638e54Smws }
1482d9638e54Smws 
1483d9638e54Smws static int
xpc_walk_init(mdb_walk_state_t * wsp)1484d9638e54Smws xpc_walk_init(mdb_walk_state_t *wsp)
1485d9638e54Smws {
1486d9638e54Smws 	fmd_xprt_class_hash_t xch;
1487d9638e54Smws 
1488d9638e54Smws 	if (mdb_vread(&xch, sizeof (xch), wsp->walk_addr) != sizeof (xch)) {
1489d9638e54Smws 		mdb_warn("failed to read fmd_xprt_class_hash at %p",
1490d9638e54Smws 		    wsp->walk_addr);
1491d9638e54Smws 		return (WALK_ERR);
1492d9638e54Smws 	}
1493d9638e54Smws 
1494d9638e54Smws 	return (hash_walk_init(wsp, (uintptr_t)xch.xch_hash, xch.xch_hashlen,
1495d9638e54Smws 	    "fmd_xprt_class", sizeof (fmd_xprt_class_t),
1496d9638e54Smws 	    OFFSETOF(fmd_xprt_class_t, xc_next)));
1497d9638e54Smws }
1498d9638e54Smws 
1499d9638e54Smws /*ARGSUSED*/
1500d9638e54Smws static int
fmd_xprt_class(uintptr_t addr,const void * data,void * arg)1501d9638e54Smws fmd_xprt_class(uintptr_t addr, const void *data, void *arg)
1502d9638e54Smws {
1503d9638e54Smws 	const fmd_xprt_class_t *xcp = data;
1504d9638e54Smws 	char name[1024];
1505d9638e54Smws 
1506d9638e54Smws 	if (mdb_readstr(name, sizeof (name), (uintptr_t)xcp->xc_class) <= 0)
1507d9638e54Smws 		(void) mdb_snprintf(name, sizeof (name), "<%p>", xcp->xc_class);
1508d9638e54Smws 
1509d9638e54Smws 	mdb_printf("%-8p %-4u %s\n", addr, xcp->xc_refs, name);
1510d9638e54Smws 	return (WALK_NEXT);
1511d9638e54Smws }
1512d9638e54Smws 
1513d9638e54Smws static int
fmd_xprt(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1514d9638e54Smws fmd_xprt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1515d9638e54Smws {
1516d9638e54Smws 	uint_t opt_s = FALSE, opt_l = FALSE, opt_r = FALSE, opt_u = FALSE;
1517d9638e54Smws 	fmd_xprt_impl_t xi;
1518d9638e54Smws 
1519d9638e54Smws 	if (mdb_getopts(argc, argv,
1520d9638e54Smws 	    'l', MDB_OPT_SETBITS, TRUE, &opt_l,
1521d9638e54Smws 	    'r', MDB_OPT_SETBITS, TRUE, &opt_r,
1522d9638e54Smws 	    's', MDB_OPT_SETBITS, TRUE, &opt_s,
1523d9638e54Smws 	    'u', MDB_OPT_SETBITS, TRUE, &opt_u, NULL) != argc)
1524d9638e54Smws 		return (DCMD_USAGE);
1525d9638e54Smws 
1526d9638e54Smws 	if (!(flags & DCMD_ADDRSPEC)) {
1527d9638e54Smws 		if (mdb_walk_dcmd("fmd_xprt", "fmd_xprt", argc, argv) != 0) {
1528d9638e54Smws 			mdb_warn("failed to walk fmd_xprt");
1529d9638e54Smws 			return (DCMD_ERR);
1530d9638e54Smws 		}
1531d9638e54Smws 		return (DCMD_OK);
1532d9638e54Smws 	}
1533d9638e54Smws 
1534d9638e54Smws 	if (mdb_vread(&xi, sizeof (xi), addr) != sizeof (xi)) {
1535d9638e54Smws 		mdb_warn("failed to read fmd_xprt at %p", addr);
1536d9638e54Smws 		return (DCMD_ERR);
1537d9638e54Smws 	}
1538d9638e54Smws 
1539d9638e54Smws 	if (DCMD_HDRSPEC(flags)) {
1540d9638e54Smws 		mdb_printf("%<u>%-8s %-4s %-4s %-5s %s%</u>\n",
1541d9638e54Smws 		    "ADDR", "ID", "VERS", "FLAGS", "STATE");
1542d9638e54Smws 	}
1543d9638e54Smws 
1544d9638e54Smws 	mdb_printf("%-8p %-4d %-4u %-5x %a\n",
1545d9638e54Smws 	    addr, xi.xi_id, xi.xi_version, xi.xi_flags, xi.xi_state);
1546d9638e54Smws 
1547d9638e54Smws 	if (opt_l | opt_s) {
1548d9638e54Smws 		(void) mdb_inc_indent(4);
1549d9638e54Smws 		mdb_printf("Local subscriptions requested by peer:\n");
1550d9638e54Smws 		mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS");
1551d9638e54Smws 		(void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class, &xi,
1552d9638e54Smws 		    addr + OFFSETOF(fmd_xprt_impl_t, xi_lsub));
1553d9638e54Smws 		(void) mdb_dec_indent(4);
1554d9638e54Smws 	}
1555d9638e54Smws 
1556d9638e54Smws 	if (opt_r | opt_s) {
1557d9638e54Smws 		(void) mdb_inc_indent(4);
1558d9638e54Smws 		mdb_printf("Remote subscriptions requested of peer:\n");
1559d9638e54Smws 		mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS");
1560d9638e54Smws 		(void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class, &xi,
1561d9638e54Smws 		    addr + OFFSETOF(fmd_xprt_impl_t, xi_rsub));
1562d9638e54Smws 		(void) mdb_dec_indent(4);
1563d9638e54Smws 	}
1564d9638e54Smws 
1565d9638e54Smws 	if (opt_u | opt_s) {
1566d9638e54Smws 		(void) mdb_inc_indent(4);
1567d9638e54Smws 		mdb_printf("Pending unsubscription acknowledgements:\n");
1568d9638e54Smws 		mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS");
1569d9638e54Smws 		(void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class, &xi,
1570d9638e54Smws 		    addr + OFFSETOF(fmd_xprt_impl_t, xi_usub));
1571d9638e54Smws 		(void) mdb_dec_indent(4);
1572d9638e54Smws 	}
1573d9638e54Smws 
1574d9638e54Smws 	return (DCMD_OK);
1575d9638e54Smws }
1576d9638e54Smws 
15772a417b23SRobert Johnston static int
tsnap_walk_init(mdb_walk_state_t * wsp)15782a417b23SRobert Johnston tsnap_walk_init(mdb_walk_state_t *wsp)
15792a417b23SRobert Johnston {
15802a417b23SRobert Johnston 	fmd_t F;
15812a417b23SRobert Johnston 
15822a417b23SRobert Johnston 	if (mdb_readvar(&F, "fmd") != sizeof (F)) {
15832a417b23SRobert Johnston 		mdb_warn("failed to read fmd meta-data");
15842a417b23SRobert Johnston 		return (WALK_ERR);
15852a417b23SRobert Johnston 	}
15862a417b23SRobert Johnston 
15872a417b23SRobert Johnston 	wsp->walk_addr = (uintptr_t)F.d_topo_list.l_next;
15882a417b23SRobert Johnston 	return (WALK_NEXT);
15892a417b23SRobert Johnston }
15902a417b23SRobert Johnston 
15912a417b23SRobert Johnston static int
tsnap_walk_step(mdb_walk_state_t * wsp)15922a417b23SRobert Johnston tsnap_walk_step(mdb_walk_state_t *wsp)
15932a417b23SRobert Johnston {
15942a417b23SRobert Johnston 	uintptr_t addr = wsp->walk_addr;
15952a417b23SRobert Johnston 	fmd_topo_t ftp;
15962a417b23SRobert Johnston 
1597940f2f58SToomas Soome 	if (addr == 0)
15982a417b23SRobert Johnston 		return (WALK_DONE);
15992a417b23SRobert Johnston 
16002a417b23SRobert Johnston 	if (mdb_vread(&ftp, sizeof (ftp), addr) != sizeof (ftp)) {
16012a417b23SRobert Johnston 		mdb_warn("failed to read fmd_topo_t at %p", addr);
16022a417b23SRobert Johnston 		return (WALK_ERR);
16032a417b23SRobert Johnston 	}
16042a417b23SRobert Johnston 
16052a417b23SRobert Johnston 	wsp->walk_addr = (uintptr_t)ftp.ft_list.l_next;
16062a417b23SRobert Johnston 	return (wsp->walk_callback(addr, &ftp, wsp->walk_cbdata));
16072a417b23SRobert Johnston }
16082a417b23SRobert Johnston 
16092a417b23SRobert Johnston static int
mq_walk_init(mdb_walk_state_t * wsp)16102a417b23SRobert Johnston mq_walk_init(mdb_walk_state_t *wsp)
16112a417b23SRobert Johnston {
16122a417b23SRobert Johnston 	fmd_module_t m;
16132a417b23SRobert Johnston 	struct fmd_eventq eq;
16142a417b23SRobert Johnston 
1615940f2f58SToomas Soome 	if (wsp->walk_addr == 0) {
16162a417b23SRobert Johnston 		mdb_warn("NULL fmd_module_t passed in");
16172a417b23SRobert Johnston 		return (WALK_ERR);
16182a417b23SRobert Johnston 	}
16192a417b23SRobert Johnston 
16202a417b23SRobert Johnston 	if (mdb_vread(&m, sizeof (m), wsp->walk_addr) != sizeof (m)) {
16212a417b23SRobert Johnston 		mdb_warn("failed to read fmd_module_t at %p", wsp->walk_addr);
16222a417b23SRobert Johnston 		return (WALK_ERR);
16232a417b23SRobert Johnston 	}
16242a417b23SRobert Johnston 	if (mdb_vread(&eq, sizeof (eq), (uintptr_t)m.mod_queue)
16252a417b23SRobert Johnston 	    != sizeof (eq)) {
16262a417b23SRobert Johnston 		mdb_warn("failed to read fmd_eventq at %p", wsp->walk_addr);
16272a417b23SRobert Johnston 		return (WALK_ERR);
16282a417b23SRobert Johnston 	}
16292a417b23SRobert Johnston 
16302a417b23SRobert Johnston 	wsp->walk_addr = (uintptr_t)eq.eq_list.l_next;
16312a417b23SRobert Johnston 
16322a417b23SRobert Johnston 	return (WALK_NEXT);
16332a417b23SRobert Johnston }
16342a417b23SRobert Johnston 
16352a417b23SRobert Johnston static int
mq_walk_step(mdb_walk_state_t * wsp)16362a417b23SRobert Johnston mq_walk_step(mdb_walk_state_t *wsp)
16372a417b23SRobert Johnston {
16382a417b23SRobert Johnston 	uintptr_t addr = wsp->walk_addr;
16392a417b23SRobert Johnston 	fmd_eventqelem_t eqe;
16402a417b23SRobert Johnston 
1641940f2f58SToomas Soome 	if (addr == 0)
16422a417b23SRobert Johnston 		return (WALK_DONE);
16432a417b23SRobert Johnston 
16442a417b23SRobert Johnston 	if (mdb_vread(&eqe, sizeof (eqe), addr) != sizeof (eqe)) {
16452a417b23SRobert Johnston 		mdb_warn("failed to read fmd_eventqelem_t at %p", addr);
16462a417b23SRobert Johnston 		return (WALK_ERR);
16472a417b23SRobert Johnston 	}
16482a417b23SRobert Johnston 
16492a417b23SRobert Johnston 	wsp->walk_addr = (uintptr_t)eqe.eqe_list.l_next;
16502a417b23SRobert Johnston 	return (wsp->walk_callback(addr, &eqe, wsp->walk_cbdata));
16512a417b23SRobert Johnston }
16522a417b23SRobert Johnston 
16537c478bd9Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = {
16547c478bd9Sstevel@tonic-gate 	{ "fcf_case", "?", "print a FCF case", fcf_case },
16557c478bd9Sstevel@tonic-gate 	{ "fcf_event", "?", "print a FCF event", fcf_event },
16567c478bd9Sstevel@tonic-gate 	{ "fcf_hdr", "?", "print a FCF header", fcf_hdr },
16577c478bd9Sstevel@tonic-gate 	{ "fcf_sec", ":", "print a FCF section header", fcf_sec },
16587c478bd9Sstevel@tonic-gate 	{ "fcf_serd", "?", "print a FCF serd engine", fcf_serd },
16597c478bd9Sstevel@tonic-gate 	{ "fmd_trace", "?[-cs]", "display thread trace buffer(s)", fmd_trace },
16606cb1ca52Saf 	{ "fmd_ustat", "[:]", "display statistics collection", fmd_ustat },
16616cb1ca52Saf 	{ "fmd_stat", "[:]", "display statistic structure", fmd_stat },
16627c478bd9Sstevel@tonic-gate 	{ "fmd_event", NULL, "display event structure", fmd_event },
16637c478bd9Sstevel@tonic-gate 	{ "fmd_thread", "?", "display thread or list of threads", fmd_thread },
16647c478bd9Sstevel@tonic-gate 	{ "fmd_module", "?", "display module or list of modules", fmd_module },
16657c478bd9Sstevel@tonic-gate 	{ "fmd_case", ":", "display case file structure", fmd_case },
16667c478bd9Sstevel@tonic-gate 	{ "fmd_buf", ":", "display buffer structure", fmd_buf },
16676cb1ca52Saf 	{ "fmd_serd", "[:]", "display serd engine structure", fmd_serd },
16687c478bd9Sstevel@tonic-gate 	{ "fmd_asru", "?", "display asru resource structure", fmd_asru },
1669cbf75e67SStephen Hanson 	{ "fmd_asru_link", "?", "display resource structure", fmd_asru_link },
16707c478bd9Sstevel@tonic-gate 	{ "fmd_timer", "?", "display pending timer(s)", fmd_timer },
1671d9638e54Smws 	{ "fmd_xprt", "?[-lrsu]", "display event transport(s)", fmd_xprt },
16727c478bd9Sstevel@tonic-gate 	{ NULL }
16737c478bd9Sstevel@tonic-gate };
16747c478bd9Sstevel@tonic-gate 
16757c478bd9Sstevel@tonic-gate static const mdb_walker_t walkers[] = {
16767c478bd9Sstevel@tonic-gate 	{ "fcf_sec", "walk FCF section header table given header address",
16777c478bd9Sstevel@tonic-gate 		fcf_sec_walk_init, fcf_sec_walk_step, fcf_sec_walk_fini },
16787c478bd9Sstevel@tonic-gate 	{ "fmd_trace", "walk per-thread trace buffers",
16797c478bd9Sstevel@tonic-gate 		trwalk_init, trwalk_step, trwalk_fini },
16807c478bd9Sstevel@tonic-gate 	{ "fmd_ustat", "walk per-collection statistics",
16817c478bd9Sstevel@tonic-gate 		ustat_walk_init, ustat_walk_step, hash_walk_fini },
16827c478bd9Sstevel@tonic-gate 	{ "fmd_thread", "walk list of all fmd_thread_t's",
16837c478bd9Sstevel@tonic-gate 		thread_walk_init, thread_walk_step, NULL },
16847c478bd9Sstevel@tonic-gate 	{ "fmd_module", "walk list of all fmd_module_t's",
16857c478bd9Sstevel@tonic-gate 		mod_walk_init, mod_walk_step, NULL },
16867c478bd9Sstevel@tonic-gate 	{ "fmd_case", "walk per-module case objects",
16877c478bd9Sstevel@tonic-gate 		case_walk_init, case_walk_step, case_walk_fini },
16887c478bd9Sstevel@tonic-gate 	{ "fmd_buf", "walk per-buf_hash buffers",
16897c478bd9Sstevel@tonic-gate 		buf_walk_init, hash_walk_step, hash_walk_fini },
16907c478bd9Sstevel@tonic-gate 	{ "fmd_serd", "walk per-serd_hash engines",
16917c478bd9Sstevel@tonic-gate 		serd_walk_init, hash_walk_step, hash_walk_fini },
16927c478bd9Sstevel@tonic-gate 	{ "fmd_asru", "walk asru resource hash",
16937c478bd9Sstevel@tonic-gate 		asru_walk_init, hash_walk_step, hash_walk_fini },
1694cbf75e67SStephen Hanson 	{ "fmd_asru_link", "walk resource hash",
1695cbf75e67SStephen Hanson 		al_walk_init, hash_walk_step, hash_walk_fini },
16967c478bd9Sstevel@tonic-gate 	{ "fmd_timerq", "walk timer queue",
16977c478bd9Sstevel@tonic-gate 		tmq_walk_init, tmq_walk_step, NULL },
1698d9638e54Smws 	{ "fmd_xprt", "walk per-module list of transports",
1699d9638e54Smws 		xprt_walk_init, xprt_walk_step, NULL },
1700d9638e54Smws 	{ "fmd_xprt_class", "walk hash table of subscription classes",
1701d9638e54Smws 		xpc_walk_init, hash_walk_step, hash_walk_fini },
17022a417b23SRobert Johnston 	{ "fmd_topo", "walk fmd's list of topo snapshots",
17032a417b23SRobert Johnston 		tsnap_walk_init, tsnap_walk_step, NULL },
17042a417b23SRobert Johnston 	{ "fmd_mod_queue", "walk per-module event queue",
17052a417b23SRobert Johnston 		mq_walk_init, mq_walk_step, NULL },
17067c478bd9Sstevel@tonic-gate 	{ NULL, NULL, NULL, NULL, NULL }
17077c478bd9Sstevel@tonic-gate };
17087c478bd9Sstevel@tonic-gate 
17097c478bd9Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
17107c478bd9Sstevel@tonic-gate 
17117c478bd9Sstevel@tonic-gate const mdb_modinfo_t *
_mdb_init(void)17127c478bd9Sstevel@tonic-gate _mdb_init(void)
17137c478bd9Sstevel@tonic-gate {
17147c478bd9Sstevel@tonic-gate 	return (&modinfo);
17157c478bd9Sstevel@tonic-gate }
1716