10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
54198Seschrock * Common Development and Distribution License (the "License").
64198Seschrock * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
211193Smws
220Sstevel@tonic-gate /*
2312066SRobert.Johnston@Sun.COM * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #include <sys/mdb_modapi.h>
275433Saf #include <limits.h>
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <fmd_trace.h>
300Sstevel@tonic-gate #include <fmd_module.h>
310Sstevel@tonic-gate #include <fmd_thread.h>
320Sstevel@tonic-gate #include <fmd_ustat.h>
330Sstevel@tonic-gate #include <fmd_event.h>
340Sstevel@tonic-gate #include <fmd_case.h>
350Sstevel@tonic-gate #include <fmd_buf.h>
360Sstevel@tonic-gate #include <fmd_asru.h>
370Sstevel@tonic-gate #include <fmd_ckpt.h>
380Sstevel@tonic-gate #include <fmd_timerq.h>
391193Smws #include <fmd_xprt.h>
400Sstevel@tonic-gate
410Sstevel@tonic-gate #include <fmd.h>
420Sstevel@tonic-gate
430Sstevel@tonic-gate typedef struct trwalk_state {
440Sstevel@tonic-gate struct trwalk_state *trw_next;
450Sstevel@tonic-gate fmd_tracebuf_t trw_data;
460Sstevel@tonic-gate pthread_t trw_tid;
470Sstevel@tonic-gate uintptr_t trw_base;
480Sstevel@tonic-gate const fmd_tracerec_t *trw_stop;
490Sstevel@tonic-gate fmd_tracerec_t *trw_xrec;
500Sstevel@tonic-gate } trwalk_state_t;
510Sstevel@tonic-gate
520Sstevel@tonic-gate typedef struct hashwalk_data {
530Sstevel@tonic-gate uintptr_t *hw_hash;
540Sstevel@tonic-gate uint_t hw_hashlen;
550Sstevel@tonic-gate uint_t hw_hashidx;
560Sstevel@tonic-gate const char *hw_name;
570Sstevel@tonic-gate void *hw_data;
580Sstevel@tonic-gate size_t hw_size;
590Sstevel@tonic-gate size_t hw_next;
600Sstevel@tonic-gate } hashwalk_data_t;
610Sstevel@tonic-gate
625433Saf static int fmd_stat(uintptr_t, uint_t, int, const mdb_arg_t *);
635433Saf static int fmd_ustat(uintptr_t, uint_t, int, const mdb_arg_t *);
645433Saf
650Sstevel@tonic-gate static int
trwalk_init(mdb_walk_state_t * wsp)660Sstevel@tonic-gate trwalk_init(mdb_walk_state_t *wsp)
670Sstevel@tonic-gate {
680Sstevel@tonic-gate uintptr_t addr;
690Sstevel@tonic-gate fmd_thread_t thr;
700Sstevel@tonic-gate fmd_t F;
710Sstevel@tonic-gate
720Sstevel@tonic-gate if (wsp->walk_addr != NULL) {
730Sstevel@tonic-gate mdb_warn("fmd_trace only supports global walks\n");
740Sstevel@tonic-gate return (WALK_ERR);
750Sstevel@tonic-gate }
760Sstevel@tonic-gate
770Sstevel@tonic-gate if (mdb_readvar(&F, "fmd") != sizeof (F)) {
780Sstevel@tonic-gate mdb_warn("failed to read fmd meta-data");
790Sstevel@tonic-gate return (WALK_ERR);
800Sstevel@tonic-gate }
810Sstevel@tonic-gate
820Sstevel@tonic-gate for (addr = (uintptr_t)F.d_thr_list.l_next; addr != NULL;
830Sstevel@tonic-gate addr = (uintptr_t)thr.thr_list.l_next) {
840Sstevel@tonic-gate
850Sstevel@tonic-gate size_t len, ptr_off, end_off;
860Sstevel@tonic-gate fmd_tracerec_t *buf;
870Sstevel@tonic-gate trwalk_state_t *t;
880Sstevel@tonic-gate
890Sstevel@tonic-gate if (mdb_vread(&thr, sizeof (thr), addr) != sizeof (thr)) {
900Sstevel@tonic-gate mdb_warn("failed to read thread at %p "
910Sstevel@tonic-gate "(some trace data will be unavailable)", addr);
920Sstevel@tonic-gate break;
930Sstevel@tonic-gate }
940Sstevel@tonic-gate
950Sstevel@tonic-gate t = mdb_zalloc(sizeof (trwalk_state_t), UM_SLEEP);
960Sstevel@tonic-gate t->trw_next = wsp->walk_data;
970Sstevel@tonic-gate wsp->walk_data = t;
980Sstevel@tonic-gate
990Sstevel@tonic-gate (void) mdb_vread(&t->trw_data,
1000Sstevel@tonic-gate sizeof (t->trw_data), (uintptr_t)thr.thr_trdata);
1010Sstevel@tonic-gate
1020Sstevel@tonic-gate if (t->trw_data.tb_recs == 0)
1030Sstevel@tonic-gate continue; /* no trace buffer allocated for thread */
1040Sstevel@tonic-gate
1050Sstevel@tonic-gate len = t->trw_data.tb_recs * t->trw_data.tb_size;
1060Sstevel@tonic-gate buf = mdb_alloc(len, UM_SLEEP);
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate t->trw_tid = thr.thr_tid;
1090Sstevel@tonic-gate t->trw_base = (uintptr_t)t->trw_data.tb_buf;
1100Sstevel@tonic-gate
1110Sstevel@tonic-gate if (mdb_vread(buf, len, t->trw_base) == -1) {
1120Sstevel@tonic-gate mdb_warn("failed to read buffer for t%u", t->trw_tid);
1130Sstevel@tonic-gate bzero(buf, len);
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate
1160Sstevel@tonic-gate end_off = (uintptr_t)t->trw_data.tb_end - t->trw_base;
1170Sstevel@tonic-gate ptr_off = (uintptr_t)t->trw_data.tb_ptr - t->trw_base;
1180Sstevel@tonic-gate
1190Sstevel@tonic-gate t->trw_data.tb_buf = buf;
1200Sstevel@tonic-gate t->trw_data.tb_end = (void *)((uintptr_t)buf + end_off);
1210Sstevel@tonic-gate t->trw_data.tb_ptr = (void *)((uintptr_t)buf + ptr_off);
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate if (t->trw_data.tb_ptr < t->trw_data.tb_buf ||
1240Sstevel@tonic-gate t->trw_data.tb_ptr > t->trw_data.tb_end) {
1250Sstevel@tonic-gate mdb_warn("trace record ptr for t%u is corrupt "
1260Sstevel@tonic-gate "(some data may be unavailable)\n", t->trw_tid);
1270Sstevel@tonic-gate t->trw_data.tb_ptr = t->trw_data.tb_buf;
1280Sstevel@tonic-gate }
1290Sstevel@tonic-gate
1300Sstevel@tonic-gate t->trw_stop = t->trw_data.tb_ptr;
1310Sstevel@tonic-gate t->trw_xrec = mdb_alloc(
1320Sstevel@tonic-gate t->trw_data.tb_size + sizeof (uintptr_t), UM_SLEEP);
1330Sstevel@tonic-gate }
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate return (WALK_NEXT);
1360Sstevel@tonic-gate }
1370Sstevel@tonic-gate
1380Sstevel@tonic-gate static fmd_tracerec_t *
trwalk_nextrec(trwalk_state_t * t)1390Sstevel@tonic-gate trwalk_nextrec(trwalk_state_t *t)
1400Sstevel@tonic-gate {
1410Sstevel@tonic-gate if (t->trw_stop == NULL)
1420Sstevel@tonic-gate return (t->trw_data.tb_ptr);
1430Sstevel@tonic-gate
1440Sstevel@tonic-gate if (t->trw_data.tb_ptr == t->trw_data.tb_buf)
1450Sstevel@tonic-gate t->trw_data.tb_ptr = t->trw_data.tb_end;
1460Sstevel@tonic-gate else
1470Sstevel@tonic-gate t->trw_data.tb_ptr = (fmd_tracerec_t *)
1480Sstevel@tonic-gate ((uintptr_t)t->trw_data.tb_ptr - t->trw_data.tb_size);
1490Sstevel@tonic-gate
1500Sstevel@tonic-gate if (t->trw_data.tb_ptr == t->trw_stop)
1510Sstevel@tonic-gate t->trw_stop = NULL; /* mark buffer as empty */
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate return (t->trw_data.tb_ptr);
1540Sstevel@tonic-gate }
1550Sstevel@tonic-gate
1560Sstevel@tonic-gate static int
trwalk_step(mdb_walk_state_t * wsp)1570Sstevel@tonic-gate trwalk_step(mdb_walk_state_t *wsp)
1580Sstevel@tonic-gate {
1590Sstevel@tonic-gate trwalk_state_t *t, *oldest_t;
1600Sstevel@tonic-gate hrtime_t oldest_time = 0;
1610Sstevel@tonic-gate fmd_tracerec_t *trp;
1620Sstevel@tonic-gate int status;
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate for (t = wsp->walk_data; t != NULL; t = t->trw_next) {
1650Sstevel@tonic-gate for (trp = t->trw_data.tb_ptr; t->trw_stop != NULL &&
1660Sstevel@tonic-gate trp->tr_time == 0; trp = trwalk_nextrec(t))
1670Sstevel@tonic-gate continue;
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate if (t->trw_stop == NULL)
1700Sstevel@tonic-gate continue; /* buffer has been emptied */
1710Sstevel@tonic-gate
1720Sstevel@tonic-gate if (trp->tr_time > oldest_time) {
1730Sstevel@tonic-gate oldest_time = trp->tr_time;
1740Sstevel@tonic-gate oldest_t = t;
1750Sstevel@tonic-gate }
1760Sstevel@tonic-gate }
1770Sstevel@tonic-gate
1780Sstevel@tonic-gate if (oldest_time == 0)
1790Sstevel@tonic-gate return (WALK_DONE);
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate t = oldest_t;
1820Sstevel@tonic-gate trp = t->trw_data.tb_ptr;
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate bcopy(trp, t->trw_xrec, t->trw_data.tb_size);
1850Sstevel@tonic-gate t->trw_xrec->tr_depth = MIN(trp->tr_depth, t->trw_data.tb_frames);
1860Sstevel@tonic-gate t->trw_xrec->tr_stack[t->trw_xrec->tr_depth] = t->trw_tid;
1870Sstevel@tonic-gate
1880Sstevel@tonic-gate status = wsp->walk_callback((uintptr_t)trp - (uintptr_t)
1890Sstevel@tonic-gate t->trw_data.tb_buf + t->trw_base, t->trw_xrec, wsp->walk_cbdata);
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate (void) trwalk_nextrec(t);
1920Sstevel@tonic-gate return (status);
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate static void
trwalk_fini(mdb_walk_state_t * wsp)1960Sstevel@tonic-gate trwalk_fini(mdb_walk_state_t *wsp)
1970Sstevel@tonic-gate {
1980Sstevel@tonic-gate trwalk_state_t *t, *u;
1990Sstevel@tonic-gate
2000Sstevel@tonic-gate for (t = wsp->walk_data; t != NULL; t = u) {
2010Sstevel@tonic-gate u = t->trw_next;
2020Sstevel@tonic-gate mdb_free(t->trw_data.tb_buf,
2030Sstevel@tonic-gate t->trw_data.tb_recs * t->trw_data.tb_size);
2040Sstevel@tonic-gate mdb_free(t->trw_xrec, t->trw_data.tb_size + sizeof (uintptr_t));
2050Sstevel@tonic-gate mdb_free(t, sizeof (trwalk_state_t));
2060Sstevel@tonic-gate }
2070Sstevel@tonic-gate }
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate /*ARGSUSED*/
2100Sstevel@tonic-gate static int
trprint_msg(uintptr_t addr,const fmd_tracerec_t * trp,uintptr_t tid)2110Sstevel@tonic-gate trprint_msg(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid)
2120Sstevel@tonic-gate {
2130Sstevel@tonic-gate if (tid == 0)
2140Sstevel@tonic-gate mdb_printf("%3lu ", trp->tr_stack[trp->tr_depth]);
2150Sstevel@tonic-gate else if (trp->tr_stack[trp->tr_depth] != tid)
2160Sstevel@tonic-gate return (WALK_NEXT);
2170Sstevel@tonic-gate
2180Sstevel@tonic-gate mdb_printf("%016llx %04x %-5u %s\n",
2191193Smws trp->tr_time, 1 << trp->tr_tag, trp->tr_errno, trp->tr_msg);
2200Sstevel@tonic-gate
2210Sstevel@tonic-gate return (WALK_NEXT);
2220Sstevel@tonic-gate }
2230Sstevel@tonic-gate
2240Sstevel@tonic-gate /*ARGSUSED*/
2250Sstevel@tonic-gate static int
trprint_cpp(uintptr_t addr,const fmd_tracerec_t * trp,uintptr_t tid)2260Sstevel@tonic-gate trprint_cpp(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid)
2270Sstevel@tonic-gate {
2280Sstevel@tonic-gate char file[64];
2290Sstevel@tonic-gate
2300Sstevel@tonic-gate if (tid == 0)
2310Sstevel@tonic-gate mdb_printf("%3lu ", trp->tr_stack[trp->tr_depth]);
2320Sstevel@tonic-gate else if (trp->tr_stack[trp->tr_depth] != tid)
2330Sstevel@tonic-gate return (WALK_NEXT);
2340Sstevel@tonic-gate
2350Sstevel@tonic-gate if (mdb_readstr(file, sizeof (file), (uintptr_t)trp->tr_file) <= 0)
2360Sstevel@tonic-gate (void) strcpy(file, "???");
2370Sstevel@tonic-gate
2380Sstevel@tonic-gate mdb_printf("%016llx %04x %s: %u\n",
2391193Smws trp->tr_time, 1 << trp->tr_tag, file, trp->tr_line);
2400Sstevel@tonic-gate
2410Sstevel@tonic-gate return (WALK_NEXT);
2420Sstevel@tonic-gate }
2430Sstevel@tonic-gate
2440Sstevel@tonic-gate static void
trprint_stack(const fmd_tracerec_t * trp)2450Sstevel@tonic-gate trprint_stack(const fmd_tracerec_t *trp)
2460Sstevel@tonic-gate {
2470Sstevel@tonic-gate uint8_t i;
2480Sstevel@tonic-gate
2490Sstevel@tonic-gate for (i = 0; i < trp->tr_depth; i++)
2500Sstevel@tonic-gate mdb_printf("\t%a\n", trp->tr_stack[i]);
2510Sstevel@tonic-gate
2520Sstevel@tonic-gate if (trp->tr_depth != 0)
2530Sstevel@tonic-gate mdb_printf("\n");
2540Sstevel@tonic-gate }
2550Sstevel@tonic-gate
2560Sstevel@tonic-gate static int
trprint_msg_stack(uintptr_t addr,const fmd_tracerec_t * trp,uintptr_t tid)2570Sstevel@tonic-gate trprint_msg_stack(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid)
2580Sstevel@tonic-gate {
2590Sstevel@tonic-gate int status = trprint_msg(addr, trp, tid);
2600Sstevel@tonic-gate trprint_stack(trp);
2610Sstevel@tonic-gate return (status);
2620Sstevel@tonic-gate }
2630Sstevel@tonic-gate
2640Sstevel@tonic-gate static int
trprint_cpp_stack(uintptr_t addr,const fmd_tracerec_t * trp,uintptr_t tid)2650Sstevel@tonic-gate trprint_cpp_stack(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid)
2660Sstevel@tonic-gate {
2670Sstevel@tonic-gate int status = trprint_cpp(addr, trp, tid);
2680Sstevel@tonic-gate trprint_stack(trp);
2690Sstevel@tonic-gate return (status);
2700Sstevel@tonic-gate }
2710Sstevel@tonic-gate
2720Sstevel@tonic-gate static int
fmd_trace(uintptr_t tid,uint_t flags,int argc,const mdb_arg_t * argv)2730Sstevel@tonic-gate fmd_trace(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv)
2740Sstevel@tonic-gate {
2750Sstevel@tonic-gate int (*func)(uintptr_t, const fmd_tracerec_t *, uintptr_t);
2760Sstevel@tonic-gate uint_t opt_c = FALSE, opt_s = FALSE;
2770Sstevel@tonic-gate
2780Sstevel@tonic-gate if (mdb_getopts(argc, argv,
2790Sstevel@tonic-gate 'c', MDB_OPT_SETBITS, TRUE, &opt_c,
2800Sstevel@tonic-gate 's', MDB_OPT_SETBITS, TRUE, &opt_s, NULL) != argc)
2810Sstevel@tonic-gate return (DCMD_USAGE);
2820Sstevel@tonic-gate
2830Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
2840Sstevel@tonic-gate mdb_printf("TID ");
2850Sstevel@tonic-gate tid = 0;
2860Sstevel@tonic-gate }
2870Sstevel@tonic-gate
2880Sstevel@tonic-gate if (opt_c) {
2890Sstevel@tonic-gate mdb_printf("%-16s %-4s FILE:LINE\n", "TIME", "TAG");
2900Sstevel@tonic-gate func = opt_s ? trprint_cpp_stack : trprint_cpp;
2910Sstevel@tonic-gate } else {
2920Sstevel@tonic-gate mdb_printf("%-16s %-4s %-5s MSG\n", "TIME", "TAG", "ERRNO");
2930Sstevel@tonic-gate func = opt_s ? trprint_msg_stack : trprint_msg;
2940Sstevel@tonic-gate }
2950Sstevel@tonic-gate
2960Sstevel@tonic-gate if (mdb_walk("fmd_trace", (mdb_walk_cb_t)func, (void *)tid) == -1) {
2970Sstevel@tonic-gate mdb_warn("failed to walk fmd_trace");
2980Sstevel@tonic-gate return (DCMD_ERR);
2990Sstevel@tonic-gate }
3000Sstevel@tonic-gate
3010Sstevel@tonic-gate return (DCMD_OK);
3020Sstevel@tonic-gate }
3030Sstevel@tonic-gate
3040Sstevel@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)3050Sstevel@tonic-gate hash_walk_init(mdb_walk_state_t *wsp, uintptr_t addr, uint_t hashlen,
3060Sstevel@tonic-gate const char *name, size_t size, size_t next)
3070Sstevel@tonic-gate {
3084451Seschrock hashwalk_data_t *hwp;
3090Sstevel@tonic-gate size_t len = sizeof (uintptr_t) * hashlen;
3100Sstevel@tonic-gate
3114451Seschrock if (len == 0) {
3124451Seschrock mdb_warn("failed to walk hash: invalid hash length\n");
3134451Seschrock return (WALK_ERR);
3144451Seschrock }
3154451Seschrock
3164451Seschrock hwp = mdb_alloc(sizeof (hashwalk_data_t), UM_SLEEP);
3170Sstevel@tonic-gate hwp->hw_hash = mdb_zalloc(len, UM_SLEEP);
3180Sstevel@tonic-gate (void) mdb_vread(hwp->hw_hash, len, addr);
3190Sstevel@tonic-gate hwp->hw_hashlen = hashlen;
3200Sstevel@tonic-gate hwp->hw_hashidx = 0;
3210Sstevel@tonic-gate hwp->hw_name = name;
3220Sstevel@tonic-gate hwp->hw_data = mdb_zalloc(size, UM_SLEEP);
3230Sstevel@tonic-gate hwp->hw_size = size;
3240Sstevel@tonic-gate hwp->hw_next = next;
3250Sstevel@tonic-gate
3260Sstevel@tonic-gate wsp->walk_addr = hwp->hw_hash[0];
3270Sstevel@tonic-gate wsp->walk_data = hwp;
3280Sstevel@tonic-gate
3290Sstevel@tonic-gate return (WALK_NEXT);
3300Sstevel@tonic-gate }
3310Sstevel@tonic-gate
3320Sstevel@tonic-gate static int
hash_walk_step(mdb_walk_state_t * wsp)3330Sstevel@tonic-gate hash_walk_step(mdb_walk_state_t *wsp)
3340Sstevel@tonic-gate {
3350Sstevel@tonic-gate hashwalk_data_t *hwp = wsp->walk_data;
3360Sstevel@tonic-gate int rv;
3370Sstevel@tonic-gate
3380Sstevel@tonic-gate while (wsp->walk_addr == NULL) {
3390Sstevel@tonic-gate if (++hwp->hw_hashidx < hwp->hw_hashlen)
3400Sstevel@tonic-gate wsp->walk_addr = hwp->hw_hash[hwp->hw_hashidx];
3410Sstevel@tonic-gate else
3420Sstevel@tonic-gate return (WALK_DONE);
3430Sstevel@tonic-gate }
3440Sstevel@tonic-gate
3450Sstevel@tonic-gate if (mdb_vread(hwp->hw_data, hwp->hw_size, wsp->walk_addr) == -1) {
3460Sstevel@tonic-gate mdb_warn("failed to read %s at %p",
3470Sstevel@tonic-gate hwp->hw_name, wsp->walk_addr);
3480Sstevel@tonic-gate return (WALK_ERR);
3490Sstevel@tonic-gate }
3500Sstevel@tonic-gate
3510Sstevel@tonic-gate rv = wsp->walk_callback(wsp->walk_addr, hwp->hw_data, wsp->walk_cbdata);
3520Sstevel@tonic-gate wsp->walk_addr = *(uintptr_t *)((uintptr_t)hwp->hw_data + hwp->hw_next);
3530Sstevel@tonic-gate return (rv);
3540Sstevel@tonic-gate }
3550Sstevel@tonic-gate
3560Sstevel@tonic-gate static void
hash_walk_fini(mdb_walk_state_t * wsp)3570Sstevel@tonic-gate hash_walk_fini(mdb_walk_state_t *wsp)
3580Sstevel@tonic-gate {
3590Sstevel@tonic-gate hashwalk_data_t *hwp = wsp->walk_data;
3600Sstevel@tonic-gate
3610Sstevel@tonic-gate mdb_free(hwp->hw_hash, sizeof (uintptr_t) * hwp->hw_hashlen);
3620Sstevel@tonic-gate mdb_free(hwp->hw_data, hwp->hw_size);
3630Sstevel@tonic-gate mdb_free(hwp, sizeof (hashwalk_data_t));
3640Sstevel@tonic-gate }
3650Sstevel@tonic-gate
3660Sstevel@tonic-gate static int
ustat_walk_init(mdb_walk_state_t * wsp)3670Sstevel@tonic-gate ustat_walk_init(mdb_walk_state_t *wsp)
3680Sstevel@tonic-gate {
3690Sstevel@tonic-gate fmd_ustat_t us;
3700Sstevel@tonic-gate
3710Sstevel@tonic-gate if (mdb_vread(&us, sizeof (us), wsp->walk_addr) != sizeof (us)) {
3720Sstevel@tonic-gate mdb_warn("failed to read fmd_ustat_t at %p", wsp->walk_addr);
3730Sstevel@tonic-gate return (WALK_ERR);
3740Sstevel@tonic-gate }
3750Sstevel@tonic-gate
3760Sstevel@tonic-gate return (hash_walk_init(wsp,
3770Sstevel@tonic-gate (uintptr_t)us.us_hash, us.us_hashlen, NULL, 0, 0));
3780Sstevel@tonic-gate }
3790Sstevel@tonic-gate
3800Sstevel@tonic-gate static int
ustat_walk_step(mdb_walk_state_t * wsp)3810Sstevel@tonic-gate ustat_walk_step(mdb_walk_state_t *wsp)
3820Sstevel@tonic-gate {
3830Sstevel@tonic-gate hashwalk_data_t *hwp = wsp->walk_data;
3840Sstevel@tonic-gate fmd_ustat_elem_t ue;
3850Sstevel@tonic-gate fmd_stat_t s;
3860Sstevel@tonic-gate
3870Sstevel@tonic-gate while (wsp->walk_addr == NULL) {
3880Sstevel@tonic-gate if (++hwp->hw_hashidx < hwp->hw_hashlen)
3890Sstevel@tonic-gate wsp->walk_addr = hwp->hw_hash[hwp->hw_hashidx];
3900Sstevel@tonic-gate else
3910Sstevel@tonic-gate return (WALK_DONE);
3920Sstevel@tonic-gate }
3930Sstevel@tonic-gate
3940Sstevel@tonic-gate if (mdb_vread(&ue, sizeof (ue), wsp->walk_addr) != sizeof (ue) ||
3950Sstevel@tonic-gate mdb_vread(&s, sizeof (s), (uintptr_t)ue.use_stat) != sizeof (s)) {
3960Sstevel@tonic-gate mdb_warn("failed to read stat element at %p", wsp->walk_addr);
3970Sstevel@tonic-gate return (WALK_ERR);
3980Sstevel@tonic-gate }
3990Sstevel@tonic-gate
4000Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)ue.use_next;
4010Sstevel@tonic-gate
4020Sstevel@tonic-gate return (wsp->walk_callback(
4030Sstevel@tonic-gate (uintptr_t)ue.use_stat, &s, wsp->walk_cbdata));
4040Sstevel@tonic-gate }
4050Sstevel@tonic-gate
4065433Saf struct fmd_cmd_data {
4075433Saf int argc;
4085433Saf const mdb_arg_t *argv;
4095433Saf };
4105433Saf
4115433Saf /* ARGSUSED */
4125433Saf static int
module_ustat(uintptr_t addr,const void * data,void * wsp)4135433Saf module_ustat(uintptr_t addr, const void *data, void *wsp)
4145433Saf {
4155433Saf fmd_module_t *modp = (fmd_module_t *)data;
4165433Saf char name[PATH_MAX];
4175433Saf const struct fmd_cmd_data *udp = wsp;
4185433Saf
4195433Saf if (mdb_readstr(name, sizeof (name), (uintptr_t)modp->mod_name) <= 0)
4205433Saf (void) mdb_snprintf(name, sizeof (name), "<%p>",
4215433Saf modp->mod_name);
4225433Saf mdb_printf("%s\n", name);
4235433Saf (void) fmd_ustat((uintptr_t)modp->mod_ustat,
4245433Saf DCMD_ADDRSPEC | DCMD_LOOPFIRST, udp->argc, udp->argv);
4255433Saf return (WALK_NEXT);
4265433Saf }
4275433Saf
4280Sstevel@tonic-gate static int
fmd_ustat(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)4290Sstevel@tonic-gate fmd_ustat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
4300Sstevel@tonic-gate {
4315433Saf if (!(flags & DCMD_ADDRSPEC)) {
4325433Saf struct fmd_cmd_data ud;
4335433Saf
4345433Saf ud.argc = argc;
4355433Saf ud.argv = argv;
4365433Saf if (mdb_walk("fmd_module", module_ustat, &ud) == -1) {
4375433Saf mdb_warn("failed to walk 'fmd_module'");
4385433Saf return (DCMD_ERR);
4395433Saf }
4405433Saf return (DCMD_OK);
4415433Saf }
4420Sstevel@tonic-gate
4430Sstevel@tonic-gate if (mdb_pwalk_dcmd("fmd_ustat", "fmd_stat", argc, argv, addr) != 0) {
4440Sstevel@tonic-gate mdb_warn("failed to walk fmd_ustat at %p", addr);
4450Sstevel@tonic-gate return (DCMD_ERR);
4460Sstevel@tonic-gate }
4470Sstevel@tonic-gate
4480Sstevel@tonic-gate return (DCMD_OK);
4490Sstevel@tonic-gate }
4500Sstevel@tonic-gate
4515433Saf /* ARGSUSED */
4525433Saf static int
module_stat(uintptr_t addr,const void * data,void * wsp)4535433Saf module_stat(uintptr_t addr, const void *data, void *wsp)
4545433Saf {
4555433Saf fmd_module_t *modp = (fmd_module_t *)data;
4565433Saf char name[PATH_MAX];
4575433Saf const struct fmd_cmd_data *udp = wsp;
4585433Saf fmd_modstat_t *mod_stats;
4595433Saf
4605433Saf if (mdb_readstr(name, sizeof (name), (uintptr_t)modp->mod_name) <= 0) {
4615433Saf (void) mdb_snprintf(name, sizeof (name), "<%p>",
4625433Saf modp->mod_name);
4635433Saf }
4645433Saf mdb_printf("%s\n", name);
4655433Saf mod_stats = modp->mod_stats;
4665433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_loadtime,
4675433Saf DCMD_ADDRSPEC | DCMD_LOOPFIRST, udp->argc, udp->argv);
4685433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_snaptime,
4695433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4705433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_accepted,
4715433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4725433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_debugdrop,
4735433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4745433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_memtotal,
4755433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4765433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_memlimit,
4775433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4785433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_buftotal,
4795433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4805433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_buflimit,
4815433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4825433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_thrtotal,
4835433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4845433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_thrlimit,
4855433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
486*12967Sgavin.maltby@oracle.com (void) fmd_stat((uintptr_t)&mod_stats->ms_doorthrtotal,
487*12967Sgavin.maltby@oracle.com DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
488*12967Sgavin.maltby@oracle.com (void) fmd_stat((uintptr_t)&mod_stats->ms_doorthrlimit,
489*12967Sgavin.maltby@oracle.com DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4905433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_caseopen,
4915433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4925433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_casesolved,
4935433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4945433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_caseclosed,
4955433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4965433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_save,
4975433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
4985433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_restore,
4995433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5005433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_zeroed,
5015433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5025433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_cnt,
5035433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5045433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_time,
5055433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5065433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_xprtopen,
5075433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5085433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_xprtlimit,
5095433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5105433Saf (void) fmd_stat((uintptr_t)&mod_stats->ms_xprtqlimit,
5115433Saf DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
5125433Saf return (WALK_NEXT);
5135433Saf }
5145433Saf
5150Sstevel@tonic-gate /*ARGSUSED*/
5160Sstevel@tonic-gate static int
fmd_stat(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)5170Sstevel@tonic-gate fmd_stat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
5180Sstevel@tonic-gate {
5190Sstevel@tonic-gate char buf[512];
5200Sstevel@tonic-gate fmd_stat_t s;
5210Sstevel@tonic-gate
5225433Saf if (argc != 0)
5230Sstevel@tonic-gate return (DCMD_USAGE);
5240Sstevel@tonic-gate
5250Sstevel@tonic-gate if (DCMD_HDRSPEC(flags))
5260Sstevel@tonic-gate mdb_printf("%<u>%-11s %-4s %-32s %s%</u>\n",
5270Sstevel@tonic-gate "ADDR", "TYPE", "NAME", "VALUE");
5280Sstevel@tonic-gate
5295433Saf if (!(flags & DCMD_ADDRSPEC)) {
5305433Saf struct fmd_cmd_data ud;
5315433Saf
5325433Saf ud.argc = argc;
5335433Saf ud.argv = argv;
5345433Saf
5355433Saf if (mdb_walk("fmd_module", module_stat, &ud) == -1) {
5365433Saf mdb_warn("failed to walk 'fmd_module'");
5375433Saf return (DCMD_ERR);
5385433Saf }
5395433Saf return (DCMD_OK);
5405433Saf }
5415433Saf
5420Sstevel@tonic-gate if (mdb_vread(&s, sizeof (s), addr) != sizeof (s)) {
5430Sstevel@tonic-gate mdb_warn("failed to read statistic at %p", addr);
5440Sstevel@tonic-gate return (DCMD_ERR);
5450Sstevel@tonic-gate }
5460Sstevel@tonic-gate
5470Sstevel@tonic-gate switch (s.fmds_type) {
5480Sstevel@tonic-gate case FMD_TYPE_BOOL:
5490Sstevel@tonic-gate mdb_printf("%-11p %-4s %-32s %s\n", addr, "bool",
5500Sstevel@tonic-gate s.fmds_name, s.fmds_value.bool ? "true" : "false");
5510Sstevel@tonic-gate break;
5520Sstevel@tonic-gate case FMD_TYPE_INT32:
5530Sstevel@tonic-gate mdb_printf("%-11p %-4s %-32s %d\n", addr, "i32",
5540Sstevel@tonic-gate s.fmds_name, s.fmds_value.i32);
5550Sstevel@tonic-gate break;
5560Sstevel@tonic-gate case FMD_TYPE_UINT32:
5570Sstevel@tonic-gate mdb_printf("%-11p %-4s %-32s %u\n", addr, "ui32",
5580Sstevel@tonic-gate s.fmds_name, s.fmds_value.i32);
5590Sstevel@tonic-gate break;
5600Sstevel@tonic-gate case FMD_TYPE_INT64:
5610Sstevel@tonic-gate mdb_printf("%-11p %-4s %-32s %lld\n", addr, "i64",
5620Sstevel@tonic-gate s.fmds_name, s.fmds_value.i64);
5630Sstevel@tonic-gate break;
5640Sstevel@tonic-gate case FMD_TYPE_UINT64:
5650Sstevel@tonic-gate mdb_printf("%-11p %-4s %-32s %llu\n", addr, "ui64",
5660Sstevel@tonic-gate s.fmds_name, s.fmds_value.ui64);
5670Sstevel@tonic-gate break;
5680Sstevel@tonic-gate case FMD_TYPE_STRING:
5690Sstevel@tonic-gate if (mdb_readstr(buf, sizeof (buf),
5700Sstevel@tonic-gate (uintptr_t)s.fmds_value.str) < 0) {
5710Sstevel@tonic-gate (void) mdb_snprintf(buf, sizeof (buf), "<%p>",
5720Sstevel@tonic-gate s.fmds_value.str);
5730Sstevel@tonic-gate }
5740Sstevel@tonic-gate mdb_printf("%-11p %-4s %-32s %s\n", addr, "str",
5750Sstevel@tonic-gate s.fmds_name, buf);
5760Sstevel@tonic-gate break;
5770Sstevel@tonic-gate case FMD_TYPE_TIME:
5780Sstevel@tonic-gate mdb_printf("%-11p %-4s %-32s %llu\n", addr, "time",
5790Sstevel@tonic-gate s.fmds_name, s.fmds_value.ui64);
5800Sstevel@tonic-gate break;
5810Sstevel@tonic-gate case FMD_TYPE_SIZE:
5820Sstevel@tonic-gate mdb_printf("%-11p %-4s %-32s %llu\n", addr, "size",
5830Sstevel@tonic-gate s.fmds_name, s.fmds_value.ui64);
5840Sstevel@tonic-gate break;
5850Sstevel@tonic-gate default:
5860Sstevel@tonic-gate mdb_printf("%-11p %-4u %-32s ???\n", addr,
5870Sstevel@tonic-gate s.fmds_type, s.fmds_name);
5880Sstevel@tonic-gate break;
5890Sstevel@tonic-gate }
5900Sstevel@tonic-gate
5910Sstevel@tonic-gate return (DCMD_OK);
5920Sstevel@tonic-gate }
5930Sstevel@tonic-gate
5940Sstevel@tonic-gate /*ARGSUSED*/
5950Sstevel@tonic-gate static int
fmd_event(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)5960Sstevel@tonic-gate fmd_event(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
5970Sstevel@tonic-gate {
5980Sstevel@tonic-gate char type[16], name[16];
5990Sstevel@tonic-gate fmd_event_impl_t ev;
6000Sstevel@tonic-gate
6010Sstevel@tonic-gate if (argc != 0)
6020Sstevel@tonic-gate return (DCMD_USAGE);
6030Sstevel@tonic-gate
6040Sstevel@tonic-gate if (mdb_vread(&ev, sizeof (ev), addr) != sizeof (ev)) {
6050Sstevel@tonic-gate mdb_warn("failed to read fmd_event at %p", addr);
6060Sstevel@tonic-gate return (DCMD_ERR);
6070Sstevel@tonic-gate }
6080Sstevel@tonic-gate
6090Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) {
6100Sstevel@tonic-gate mdb_printf("%<u>%-11s %-4s %-5s %-3s %-?s%</u>\n",
6110Sstevel@tonic-gate "ADDR", "TYPE", "STATE", "REF", "NVPAIR");
6120Sstevel@tonic-gate }
6130Sstevel@tonic-gate
6140Sstevel@tonic-gate switch (ev.ev_type) {
6150Sstevel@tonic-gate case FMD_EVT_PROTOCOL:
6160Sstevel@tonic-gate (void) strcpy(type, "PROT");
6170Sstevel@tonic-gate break;
6180Sstevel@tonic-gate case FMD_EVT_GC:
6190Sstevel@tonic-gate (void) strcpy(type, "GC");
6200Sstevel@tonic-gate break;
6210Sstevel@tonic-gate case FMD_EVT_CLOSE:
6220Sstevel@tonic-gate (void) strcpy(type, "CLSE");
6230Sstevel@tonic-gate break;
6240Sstevel@tonic-gate case FMD_EVT_TIMEOUT:
6250Sstevel@tonic-gate (void) strcpy(type, "TIME");
6260Sstevel@tonic-gate break;
6270Sstevel@tonic-gate case FMD_EVT_STATS:
6280Sstevel@tonic-gate (void) strcpy(type, "STAT");
6290Sstevel@tonic-gate break;
6301193Smws case FMD_EVT_PUBLISH:
6311193Smws (void) strcpy(type, "PUBL");
6321193Smws break;
6334198Seschrock case FMD_EVT_TOPO:
6344198Seschrock (void) strcpy(type, "TOPO");
6354198Seschrock break;
6360Sstevel@tonic-gate default:
6370Sstevel@tonic-gate (void) mdb_snprintf(type, sizeof (type), "%u", ev.ev_type);
6380Sstevel@tonic-gate }
6390Sstevel@tonic-gate
6400Sstevel@tonic-gate switch (ev.ev_state) {
6410Sstevel@tonic-gate case FMD_EVS_RECEIVED:
6420Sstevel@tonic-gate (void) strcpy(name, "RECVD");
6430Sstevel@tonic-gate break;
6440Sstevel@tonic-gate case FMD_EVS_ACCEPTED:
6450Sstevel@tonic-gate (void) strcpy(name, "ACCPT");
6460Sstevel@tonic-gate break;
6470Sstevel@tonic-gate case FMD_EVS_DISCARDED:
6480Sstevel@tonic-gate (void) strcpy(name, "DSCRD");
6490Sstevel@tonic-gate break;
6500Sstevel@tonic-gate case FMD_EVS_DIAGNOSED:
6510Sstevel@tonic-gate (void) strcpy(name, "DIAGN");
6520Sstevel@tonic-gate break;
6530Sstevel@tonic-gate default:
6540Sstevel@tonic-gate (void) mdb_snprintf(name, sizeof (name), "%u", ev.ev_state);
6550Sstevel@tonic-gate }
6560Sstevel@tonic-gate
6570Sstevel@tonic-gate mdb_printf("%-11p %-4s %-5s %-3u %p\n",
6580Sstevel@tonic-gate addr, type, name, ev.ev_refs, ev.ev_nvl);
6590Sstevel@tonic-gate
6600Sstevel@tonic-gate return (DCMD_OK);
6610Sstevel@tonic-gate }
6620Sstevel@tonic-gate
6630Sstevel@tonic-gate static int
thread_walk_init(mdb_walk_state_t * wsp)6640Sstevel@tonic-gate thread_walk_init(mdb_walk_state_t *wsp)
6650Sstevel@tonic-gate {
6660Sstevel@tonic-gate fmd_t F;
6670Sstevel@tonic-gate
6680Sstevel@tonic-gate if (mdb_readvar(&F, "fmd") != sizeof (F)) {
6690Sstevel@tonic-gate mdb_warn("failed to read fmd meta-data");
6700Sstevel@tonic-gate return (WALK_ERR);
6710Sstevel@tonic-gate }
6720Sstevel@tonic-gate
6730Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)F.d_thr_list.l_next;
6740Sstevel@tonic-gate return (WALK_NEXT);
6750Sstevel@tonic-gate }
6760Sstevel@tonic-gate
6770Sstevel@tonic-gate static int
thread_walk_step(mdb_walk_state_t * wsp)6780Sstevel@tonic-gate thread_walk_step(mdb_walk_state_t *wsp)
6790Sstevel@tonic-gate {
6800Sstevel@tonic-gate uintptr_t addr = wsp->walk_addr;
6810Sstevel@tonic-gate fmd_thread_t t;
6820Sstevel@tonic-gate
6830Sstevel@tonic-gate if (addr == NULL)
6840Sstevel@tonic-gate return (WALK_DONE);
6850Sstevel@tonic-gate
6860Sstevel@tonic-gate if (mdb_vread(&t, sizeof (t), addr) != sizeof (t)) {
6870Sstevel@tonic-gate mdb_warn("failed to read fmd_thread at %p", addr);
6880Sstevel@tonic-gate return (WALK_ERR);
6890Sstevel@tonic-gate }
6900Sstevel@tonic-gate
6910Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)t.thr_list.l_next;
6920Sstevel@tonic-gate return (wsp->walk_callback(addr, &t, wsp->walk_cbdata));
6930Sstevel@tonic-gate }
6940Sstevel@tonic-gate
6950Sstevel@tonic-gate static int
fmd_thread(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)6960Sstevel@tonic-gate fmd_thread(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
6970Sstevel@tonic-gate {
6980Sstevel@tonic-gate fmd_thread_t thr;
6990Sstevel@tonic-gate
7000Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC))
7010Sstevel@tonic-gate return (mdb_walk_dcmd("fmd_thread", "fmd_thread", argc, argv));
7020Sstevel@tonic-gate
7030Sstevel@tonic-gate if (argc != 0)
7040Sstevel@tonic-gate return (DCMD_USAGE);
7050Sstevel@tonic-gate
7060Sstevel@tonic-gate if (mdb_vread(&thr, sizeof (thr), addr) != sizeof (thr)) {
7070Sstevel@tonic-gate mdb_warn("failed to read fmd_thread at %p", addr);
7080Sstevel@tonic-gate return (DCMD_ERR);
7090Sstevel@tonic-gate }
7100Sstevel@tonic-gate
7110Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) {
7120Sstevel@tonic-gate mdb_printf("%<u>%-11s %-11s %-8s %-16s%</u>\n",
7130Sstevel@tonic-gate "ADDR", "MOD", "TID", "FUNC");
7140Sstevel@tonic-gate }
7150Sstevel@tonic-gate
7160Sstevel@tonic-gate mdb_printf("%-11p %-11p %-8u %a\n",
7170Sstevel@tonic-gate addr, thr.thr_mod, thr.thr_tid, thr.thr_func);
7180Sstevel@tonic-gate
7190Sstevel@tonic-gate return (DCMD_OK);
7200Sstevel@tonic-gate }
7210Sstevel@tonic-gate
7220Sstevel@tonic-gate static int
mod_walk_init(mdb_walk_state_t * wsp)7230Sstevel@tonic-gate mod_walk_init(mdb_walk_state_t *wsp)
7240Sstevel@tonic-gate {
7250Sstevel@tonic-gate fmd_t F;
7260Sstevel@tonic-gate
7270Sstevel@tonic-gate if (mdb_readvar(&F, "fmd") != sizeof (F)) {
7280Sstevel@tonic-gate mdb_warn("failed to read fmd meta-data");
7290Sstevel@tonic-gate return (WALK_ERR);
7300Sstevel@tonic-gate }
7310Sstevel@tonic-gate
7320Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)F.d_mod_list.l_next;
7330Sstevel@tonic-gate return (WALK_NEXT);
7340Sstevel@tonic-gate }
7350Sstevel@tonic-gate
7360Sstevel@tonic-gate static int
mod_walk_step(mdb_walk_state_t * wsp)7370Sstevel@tonic-gate mod_walk_step(mdb_walk_state_t *wsp)
7380Sstevel@tonic-gate {
7390Sstevel@tonic-gate uintptr_t addr = wsp->walk_addr;
7400Sstevel@tonic-gate fmd_module_t m;
7410Sstevel@tonic-gate
7420Sstevel@tonic-gate if (addr == NULL)
7430Sstevel@tonic-gate return (WALK_DONE);
7440Sstevel@tonic-gate
7450Sstevel@tonic-gate if (mdb_vread(&m, sizeof (m), addr) != sizeof (m)) {
7460Sstevel@tonic-gate mdb_warn("failed to read fmd_module at %p", addr);
7470Sstevel@tonic-gate return (WALK_ERR);
7480Sstevel@tonic-gate }
7490Sstevel@tonic-gate
7500Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)m.mod_list.l_next;
7510Sstevel@tonic-gate return (wsp->walk_callback(addr, &m, wsp->walk_cbdata));
7520Sstevel@tonic-gate }
7530Sstevel@tonic-gate
7540Sstevel@tonic-gate static int
fmd_module(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)7550Sstevel@tonic-gate fmd_module(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
7560Sstevel@tonic-gate {
7570Sstevel@tonic-gate fmd_module_t mod;
7585433Saf char name[PATH_MAX];
7590Sstevel@tonic-gate
7600Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC))
7610Sstevel@tonic-gate return (mdb_walk_dcmd("fmd_module", "fmd_module", argc, argv));
7620Sstevel@tonic-gate
7630Sstevel@tonic-gate if (argc != 0)
7640Sstevel@tonic-gate return (DCMD_USAGE);
7650Sstevel@tonic-gate
7660Sstevel@tonic-gate if (mdb_vread(&mod, sizeof (mod), addr) != sizeof (mod)) {
7670Sstevel@tonic-gate mdb_warn("failed to read fmd_module at %p", addr);
7680Sstevel@tonic-gate return (DCMD_ERR);
7690Sstevel@tonic-gate }
7700Sstevel@tonic-gate
7710Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) {
7720Sstevel@tonic-gate mdb_printf("%<u>%-11s %-16s %-11s %-4s %-?s %-16s%</u>\n",
7730Sstevel@tonic-gate "ADDR", "OPS", "DATA", "FLAG", "USTAT", "NAME");
7740Sstevel@tonic-gate }
7750Sstevel@tonic-gate
7760Sstevel@tonic-gate if (mdb_readstr(name, sizeof (name), (uintptr_t)mod.mod_name) <= 0)
7770Sstevel@tonic-gate (void) mdb_snprintf(name, sizeof (name), "<%p>", mod.mod_name);
7780Sstevel@tonic-gate
7790Sstevel@tonic-gate mdb_printf("%-11p %-16a %-11p 0x%02x %-?p %s\n", addr,
7800Sstevel@tonic-gate mod.mod_ops, mod.mod_data, mod.mod_flags, mod.mod_ustat, name);
7810Sstevel@tonic-gate
7820Sstevel@tonic-gate return (DCMD_OK);
7830Sstevel@tonic-gate }
7840Sstevel@tonic-gate
7850Sstevel@tonic-gate static int
case_walk_init(mdb_walk_state_t * wsp)7860Sstevel@tonic-gate case_walk_init(mdb_walk_state_t *wsp)
7870Sstevel@tonic-gate {
7880Sstevel@tonic-gate fmd_module_t mod;
7890Sstevel@tonic-gate fmd_case_hash_t ch;
7900Sstevel@tonic-gate fmd_t F;
7910Sstevel@tonic-gate
7920Sstevel@tonic-gate if (wsp->walk_addr != NULL) {
7930Sstevel@tonic-gate if (mdb_vread(&mod, sizeof (mod), wsp->walk_addr) == -1) {
7940Sstevel@tonic-gate mdb_warn("failed to read module at %p", wsp->walk_addr);
7950Sstevel@tonic-gate return (WALK_ERR);
7960Sstevel@tonic-gate }
7970Sstevel@tonic-gate
7980Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)mod.mod_cases.l_next;
7990Sstevel@tonic-gate return (WALK_NEXT);
8000Sstevel@tonic-gate }
8010Sstevel@tonic-gate
8020Sstevel@tonic-gate if (mdb_readvar(&F, "fmd") != sizeof (F) ||
8030Sstevel@tonic-gate mdb_vread(&ch, sizeof (ch), (uintptr_t)F.d_cases) != sizeof (ch)) {
8040Sstevel@tonic-gate mdb_warn("failed to read fmd meta-data");
8050Sstevel@tonic-gate return (WALK_ERR);
8060Sstevel@tonic-gate }
8070Sstevel@tonic-gate
8080Sstevel@tonic-gate return (hash_walk_init(wsp, (uintptr_t)ch.ch_hash, ch.ch_hashlen,
8090Sstevel@tonic-gate "fmd_case", sizeof (fmd_case_impl_t),
8100Sstevel@tonic-gate OFFSETOF(fmd_case_impl_t, ci_next)));
8110Sstevel@tonic-gate }
8120Sstevel@tonic-gate
8130Sstevel@tonic-gate static int
case_walk_step(mdb_walk_state_t * wsp)8140Sstevel@tonic-gate case_walk_step(mdb_walk_state_t *wsp)
8150Sstevel@tonic-gate {
8160Sstevel@tonic-gate uintptr_t addr = wsp->walk_addr;
8170Sstevel@tonic-gate fmd_case_impl_t ci;
8180Sstevel@tonic-gate
8190Sstevel@tonic-gate if (wsp->walk_data != NULL)
8200Sstevel@tonic-gate return (hash_walk_step(wsp));
8210Sstevel@tonic-gate
8220Sstevel@tonic-gate if (addr == NULL)
8230Sstevel@tonic-gate return (WALK_DONE);
8240Sstevel@tonic-gate
8250Sstevel@tonic-gate if (mdb_vread(&ci, sizeof (ci), addr) != sizeof (ci)) {
8260Sstevel@tonic-gate mdb_warn("failed to read fmd_case at %p", addr);
8270Sstevel@tonic-gate return (WALK_ERR);
8280Sstevel@tonic-gate }
8290Sstevel@tonic-gate
8300Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)ci.ci_list.l_next;
8310Sstevel@tonic-gate return (wsp->walk_callback(addr, &ci, wsp->walk_cbdata));
8320Sstevel@tonic-gate }
8330Sstevel@tonic-gate
8340Sstevel@tonic-gate static void
case_walk_fini(mdb_walk_state_t * wsp)8350Sstevel@tonic-gate case_walk_fini(mdb_walk_state_t *wsp)
8360Sstevel@tonic-gate {
8370Sstevel@tonic-gate if (wsp->walk_data != NULL)
8380Sstevel@tonic-gate hash_walk_fini(wsp);
8390Sstevel@tonic-gate }
8400Sstevel@tonic-gate
8410Sstevel@tonic-gate static int
fmd_case(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)8420Sstevel@tonic-gate fmd_case(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
8430Sstevel@tonic-gate {
8440Sstevel@tonic-gate char uuid[48], name[16];
8450Sstevel@tonic-gate fmd_case_impl_t ci;
8460Sstevel@tonic-gate
8470Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
8480Sstevel@tonic-gate if (mdb_walk_dcmd("fmd_case", "fmd_case", argc, argv) != 0) {
8490Sstevel@tonic-gate mdb_warn("failed to walk fmd_case hash");
8500Sstevel@tonic-gate return (DCMD_ERR);
8510Sstevel@tonic-gate }
8520Sstevel@tonic-gate return (DCMD_OK);
8530Sstevel@tonic-gate }
8540Sstevel@tonic-gate
8550Sstevel@tonic-gate if (mdb_vread(&ci, sizeof (ci), addr) != sizeof (ci)) {
8560Sstevel@tonic-gate mdb_warn("failed to read fmd_case at %p", addr);
8570Sstevel@tonic-gate return (DCMD_ERR);
8580Sstevel@tonic-gate }
8590Sstevel@tonic-gate
8600Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) {
8610Sstevel@tonic-gate mdb_printf("%<u>%-11s %-5s %-3s %-?s %-36s%</u>\n",
8620Sstevel@tonic-gate "ADDR", "STATE", "REF", "DATA", "UUID");
8630Sstevel@tonic-gate }
8640Sstevel@tonic-gate
8650Sstevel@tonic-gate if (mdb_readstr(uuid, sizeof (uuid), (uintptr_t)ci.ci_uuid) <= 0)
8660Sstevel@tonic-gate (void) mdb_snprintf(uuid, sizeof (uuid), "<%p>", ci.ci_uuid);
8670Sstevel@tonic-gate
8680Sstevel@tonic-gate switch (ci.ci_state) {
8690Sstevel@tonic-gate case FMD_CASE_UNSOLVED:
8700Sstevel@tonic-gate (void) strcpy(name, "UNSLV");
8710Sstevel@tonic-gate break;
8720Sstevel@tonic-gate case FMD_CASE_SOLVED:
8730Sstevel@tonic-gate (void) strcpy(name, "SOLVE");
8740Sstevel@tonic-gate break;
8751193Smws case FMD_CASE_CLOSE_WAIT:
8761193Smws (void) strcpy(name, "CWAIT");
8771193Smws break;
8780Sstevel@tonic-gate case FMD_CASE_CLOSED:
8790Sstevel@tonic-gate (void) strcpy(name, "CLOSE");
8800Sstevel@tonic-gate break;
8811193Smws case FMD_CASE_REPAIRED:
8821193Smws (void) strcpy(name, "RPAIR");
8831193Smws break;
884*12967Sgavin.maltby@oracle.com case FMD_CASE_RESOLVED:
885*12967Sgavin.maltby@oracle.com (void) strcpy(name, "RSLVD");
886*12967Sgavin.maltby@oracle.com break;
8870Sstevel@tonic-gate default:
8880Sstevel@tonic-gate (void) mdb_snprintf(name, sizeof (name), "%u", ci.ci_state);
8890Sstevel@tonic-gate }
8900Sstevel@tonic-gate
8910Sstevel@tonic-gate mdb_printf("%-11p %-5s %-3u %-?p %s\n",
8920Sstevel@tonic-gate addr, name, ci.ci_refs, ci.ci_data, uuid);
8930Sstevel@tonic-gate
8940Sstevel@tonic-gate return (DCMD_OK);
8950Sstevel@tonic-gate }
8960Sstevel@tonic-gate
8970Sstevel@tonic-gate static int
buf_walk_init(mdb_walk_state_t * wsp)8980Sstevel@tonic-gate buf_walk_init(mdb_walk_state_t *wsp)
8990Sstevel@tonic-gate {
9000Sstevel@tonic-gate fmd_buf_hash_t bh;
9010Sstevel@tonic-gate
9020Sstevel@tonic-gate if (mdb_vread(&bh, sizeof (bh), wsp->walk_addr) != sizeof (bh)) {
9030Sstevel@tonic-gate mdb_warn("failed to read fmd_buf_hash_t at %p", wsp->walk_addr);
9040Sstevel@tonic-gate return (WALK_ERR);
9050Sstevel@tonic-gate }
9060Sstevel@tonic-gate
9070Sstevel@tonic-gate return (hash_walk_init(wsp, (uintptr_t)bh.bh_hash, bh.bh_hashlen,
9080Sstevel@tonic-gate "fmd_buf", sizeof (fmd_buf_t), OFFSETOF(fmd_buf_t, buf_next)));
9090Sstevel@tonic-gate }
9100Sstevel@tonic-gate
9110Sstevel@tonic-gate /*ARGSUSED*/
9120Sstevel@tonic-gate static int
fmd_buf(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)9130Sstevel@tonic-gate fmd_buf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
9140Sstevel@tonic-gate {
9155433Saf char name[PATH_MAX];
9160Sstevel@tonic-gate fmd_buf_t b;
9170Sstevel@tonic-gate
9180Sstevel@tonic-gate if (argc != 0 || !(flags & DCMD_ADDRSPEC))
9190Sstevel@tonic-gate return (DCMD_USAGE);
9200Sstevel@tonic-gate
9210Sstevel@tonic-gate if (mdb_vread(&b, sizeof (b), addr) != sizeof (b)) {
9220Sstevel@tonic-gate mdb_warn("failed to read fmd_buf at %p", addr);
9230Sstevel@tonic-gate return (DCMD_ERR);
9240Sstevel@tonic-gate }
9250Sstevel@tonic-gate
9260Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) {
9270Sstevel@tonic-gate mdb_printf("%<u>%-11s %-32s %-5s %-?s %s%</u>\n",
9280Sstevel@tonic-gate "ADDR", "NAME", "FLAGS", "DATA", "SIZE");
9290Sstevel@tonic-gate }
9300Sstevel@tonic-gate
9310Sstevel@tonic-gate if (mdb_readstr(name, sizeof (name), (uintptr_t)b.buf_name) <= 0)
9320Sstevel@tonic-gate (void) mdb_snprintf(name, sizeof (name), "<%p>", b.buf_name);
9330Sstevel@tonic-gate
9340Sstevel@tonic-gate mdb_printf("%-11p %-32s %-#5x %-?p %lu\n",
9350Sstevel@tonic-gate addr, name, b.buf_flags, b.buf_data, b.buf_size);
9360Sstevel@tonic-gate
9370Sstevel@tonic-gate return (DCMD_OK);
9380Sstevel@tonic-gate }
9390Sstevel@tonic-gate
9400Sstevel@tonic-gate static int
serd_walk_init(mdb_walk_state_t * wsp)9410Sstevel@tonic-gate serd_walk_init(mdb_walk_state_t *wsp)
9420Sstevel@tonic-gate {
9430Sstevel@tonic-gate fmd_serd_hash_t sh;
9440Sstevel@tonic-gate
9450Sstevel@tonic-gate if (mdb_vread(&sh, sizeof (sh), wsp->walk_addr) != sizeof (sh)) {
9460Sstevel@tonic-gate mdb_warn("failed to read fmd_serd_hash at %p", wsp->walk_addr);
9470Sstevel@tonic-gate return (WALK_ERR);
9480Sstevel@tonic-gate }
9490Sstevel@tonic-gate
9500Sstevel@tonic-gate return (hash_walk_init(wsp, (uintptr_t)sh.sh_hash, sh.sh_hashlen,
9510Sstevel@tonic-gate "fmd_serd_eng", sizeof (fmd_serd_eng_t),
9520Sstevel@tonic-gate OFFSETOF(fmd_serd_eng_t, sg_next)));
9530Sstevel@tonic-gate }
9540Sstevel@tonic-gate
9555433Saf /* ARGSUSED */
9565433Saf static int
module_serd(uintptr_t addr,const void * data,void * wsp)9575433Saf module_serd(uintptr_t addr, const void *data, void *wsp)
9585433Saf {
9595433Saf fmd_module_t *modp = (fmd_module_t *)data;
9605433Saf
9615433Saf if (modp->mod_serds.sh_count != 0) {
9625433Saf modp = (fmd_module_t *)addr;
9635433Saf (void) mdb_pwalk_dcmd("fmd_serd", "fmd_serd", 0, 0,
9645433Saf (uintptr_t)&modp->mod_serds);
9655433Saf }
9665433Saf return (WALK_NEXT);
9675433Saf }
9685433Saf
9690Sstevel@tonic-gate /*ARGSUSED*/
9700Sstevel@tonic-gate static int
fmd_serd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)9710Sstevel@tonic-gate fmd_serd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
9720Sstevel@tonic-gate {
9735433Saf char name[PATH_MAX];
9740Sstevel@tonic-gate fmd_serd_eng_t sg;
9750Sstevel@tonic-gate
9765433Saf if (argc != 0)
9770Sstevel@tonic-gate return (DCMD_USAGE);
9785433Saf if (!(flags & DCMD_ADDRSPEC)) {
9795433Saf if (mdb_walk("fmd_module", module_serd, 0) == -1) {
9805433Saf mdb_warn("failed to walk 'fmd_module'");
9815433Saf return (DCMD_ERR);
9825433Saf }
9835433Saf return (DCMD_OK);
9845433Saf }
9850Sstevel@tonic-gate
9860Sstevel@tonic-gate if (mdb_vread(&sg, sizeof (sg), addr) != sizeof (sg)) {
9870Sstevel@tonic-gate mdb_warn("failed to read fmd_serd_eng at %p", addr);
9880Sstevel@tonic-gate return (DCMD_ERR);
9890Sstevel@tonic-gate }
9900Sstevel@tonic-gate
9910Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) {
9920Sstevel@tonic-gate mdb_printf("%<u>%-11s %-32s %-3s F >%-2s %-16s%</u>\n",
9930Sstevel@tonic-gate "ADDR", "NAME", "CNT", "N", "T");
9940Sstevel@tonic-gate }
9950Sstevel@tonic-gate
9960Sstevel@tonic-gate if (mdb_readstr(name, sizeof (name), (uintptr_t)sg.sg_name) <= 0)
9970Sstevel@tonic-gate (void) mdb_snprintf(name, sizeof (name), "<%p>", sg.sg_name);
9980Sstevel@tonic-gate
9990Sstevel@tonic-gate mdb_printf("%-11p %-32s %-3u %c >%-2u %lluns\n",
10000Sstevel@tonic-gate addr, name, sg.sg_count, (sg.sg_flags & FMD_SERD_FIRED) ? 'F' : ' ',
10010Sstevel@tonic-gate sg.sg_n, (u_longlong_t)sg.sg_t);
10020Sstevel@tonic-gate
10030Sstevel@tonic-gate return (DCMD_OK);
10040Sstevel@tonic-gate }
10050Sstevel@tonic-gate
10060Sstevel@tonic-gate static int
asru_walk_init(mdb_walk_state_t * wsp)10070Sstevel@tonic-gate asru_walk_init(mdb_walk_state_t *wsp)
10080Sstevel@tonic-gate {
10090Sstevel@tonic-gate fmd_asru_hash_t ah;
10100Sstevel@tonic-gate fmd_t F;
10110Sstevel@tonic-gate
10120Sstevel@tonic-gate if (wsp->walk_addr == NULL && mdb_readvar(&F, "fmd") != sizeof (F)) {
10130Sstevel@tonic-gate mdb_warn("failed to read fmd meta-data");
10140Sstevel@tonic-gate return (WALK_ERR);
10150Sstevel@tonic-gate }
10160Sstevel@tonic-gate
10170Sstevel@tonic-gate if (wsp->walk_addr == NULL)
10180Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)F.d_asrus;
10190Sstevel@tonic-gate
10200Sstevel@tonic-gate if (mdb_vread(&ah, sizeof (ah), wsp->walk_addr) != sizeof (ah)) {
10210Sstevel@tonic-gate mdb_warn("failed to read asru_hash at %p", wsp->walk_addr);
10220Sstevel@tonic-gate return (WALK_ERR);
10230Sstevel@tonic-gate }
10240Sstevel@tonic-gate
10250Sstevel@tonic-gate return (hash_walk_init(wsp, (uintptr_t)ah.ah_hash, ah.ah_hashlen,
10260Sstevel@tonic-gate "fmd_asru", sizeof (fmd_asru_t), OFFSETOF(fmd_asru_t, asru_next)));
10270Sstevel@tonic-gate }
10280Sstevel@tonic-gate
10290Sstevel@tonic-gate static int
fmd_asru(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)10300Sstevel@tonic-gate fmd_asru(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
10310Sstevel@tonic-gate {
10325433Saf char uuid[48], name[PATH_MAX];
10330Sstevel@tonic-gate fmd_asru_t a;
10340Sstevel@tonic-gate
10350Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
10360Sstevel@tonic-gate if (mdb_walk_dcmd("fmd_asru", "fmd_asru", argc, argv) != 0) {
10370Sstevel@tonic-gate mdb_warn("failed to walk fmd_asru hash");
10380Sstevel@tonic-gate return (DCMD_ERR);
10390Sstevel@tonic-gate }
10400Sstevel@tonic-gate return (DCMD_OK);
10410Sstevel@tonic-gate }
10420Sstevel@tonic-gate
10430Sstevel@tonic-gate if (mdb_vread(&a, sizeof (a), addr) != sizeof (a)) {
10440Sstevel@tonic-gate mdb_warn("failed to read fmd_asru at %p", addr);
10450Sstevel@tonic-gate return (DCMD_ERR);
10460Sstevel@tonic-gate }
10470Sstevel@tonic-gate
10480Sstevel@tonic-gate if (DCMD_HDRSPEC(flags))
10490Sstevel@tonic-gate mdb_printf("%<u>%-8s %-36s %s%</u>\n", "ADDR", "UUID", "NAME");
10500Sstevel@tonic-gate
10510Sstevel@tonic-gate if (mdb_readstr(uuid, sizeof (uuid), (uintptr_t)a.asru_uuid) <= 0)
10520Sstevel@tonic-gate (void) mdb_snprintf(uuid, sizeof (uuid), "<%p>", a.asru_uuid);
10530Sstevel@tonic-gate if (mdb_readstr(name, sizeof (name), (uintptr_t)a.asru_name) <= 0)
10540Sstevel@tonic-gate (void) mdb_snprintf(name, sizeof (name), "<%p>", a.asru_name);
10550Sstevel@tonic-gate
10560Sstevel@tonic-gate mdb_printf("%-8p %-36s %s\n", addr, uuid, name);
10570Sstevel@tonic-gate return (DCMD_OK);
10580Sstevel@tonic-gate }
10590Sstevel@tonic-gate
10609120SStephen.Hanson@Sun.COM static int
al_walk_init(mdb_walk_state_t * wsp)10619120SStephen.Hanson@Sun.COM al_walk_init(mdb_walk_state_t *wsp)
10629120SStephen.Hanson@Sun.COM {
10639120SStephen.Hanson@Sun.COM fmd_asru_hash_t ah;
10649120SStephen.Hanson@Sun.COM fmd_t F;
10659120SStephen.Hanson@Sun.COM
10669120SStephen.Hanson@Sun.COM if (wsp->walk_addr == NULL && mdb_readvar(&F, "fmd") != sizeof (F)) {
10679120SStephen.Hanson@Sun.COM mdb_warn("failed to read fmd meta-data");
10689120SStephen.Hanson@Sun.COM return (WALK_ERR);
10699120SStephen.Hanson@Sun.COM }
10709120SStephen.Hanson@Sun.COM
10719120SStephen.Hanson@Sun.COM if (wsp->walk_addr == NULL)
10729120SStephen.Hanson@Sun.COM wsp->walk_addr = (uintptr_t)F.d_asrus;
10739120SStephen.Hanson@Sun.COM
10749120SStephen.Hanson@Sun.COM if (mdb_vread(&ah, sizeof (ah), wsp->walk_addr) != sizeof (ah)) {
10759120SStephen.Hanson@Sun.COM mdb_warn("failed to read asru_hash at %p", wsp->walk_addr);
10769120SStephen.Hanson@Sun.COM return (WALK_ERR);
10779120SStephen.Hanson@Sun.COM }
10789120SStephen.Hanson@Sun.COM
10799120SStephen.Hanson@Sun.COM return (hash_walk_init(wsp, (uintptr_t)ah.ah_rsrc_hash, ah.ah_hashlen,
10809120SStephen.Hanson@Sun.COM "fmd_asru_link", sizeof (fmd_asru_link_t), OFFSETOF(fmd_asru_link_t,
10819120SStephen.Hanson@Sun.COM al_rsrc_next)));
10829120SStephen.Hanson@Sun.COM }
10839120SStephen.Hanson@Sun.COM
10849120SStephen.Hanson@Sun.COM static int
fmd_asru_link(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)10859120SStephen.Hanson@Sun.COM fmd_asru_link(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
10869120SStephen.Hanson@Sun.COM {
10879120SStephen.Hanson@Sun.COM char uuid[48], name[PATH_MAX];
10889120SStephen.Hanson@Sun.COM fmd_asru_link_t a;
10899120SStephen.Hanson@Sun.COM
10909120SStephen.Hanson@Sun.COM if (!(flags & DCMD_ADDRSPEC)) {
10919120SStephen.Hanson@Sun.COM if (mdb_walk_dcmd("fmd_asru_link", "fmd_asru_link", argc,
10929120SStephen.Hanson@Sun.COM argv) != 0) {
10939120SStephen.Hanson@Sun.COM mdb_warn("failed to walk fmd_asru_link hash");
10949120SStephen.Hanson@Sun.COM return (DCMD_ERR);
10959120SStephen.Hanson@Sun.COM }
10969120SStephen.Hanson@Sun.COM return (DCMD_OK);
10979120SStephen.Hanson@Sun.COM }
10989120SStephen.Hanson@Sun.COM
10999120SStephen.Hanson@Sun.COM if (mdb_vread(&a, sizeof (a), addr) != sizeof (a)) {
11009120SStephen.Hanson@Sun.COM mdb_warn("failed to read fmd_asru_link at %p", addr);
11019120SStephen.Hanson@Sun.COM return (DCMD_ERR);
11029120SStephen.Hanson@Sun.COM }
11039120SStephen.Hanson@Sun.COM
11049120SStephen.Hanson@Sun.COM if (DCMD_HDRSPEC(flags))
11059120SStephen.Hanson@Sun.COM mdb_printf("%<u>%-8s %-36s %s%</u>\n", "ADDR", "UUID", "NAME");
11069120SStephen.Hanson@Sun.COM
11079120SStephen.Hanson@Sun.COM if (mdb_readstr(uuid, sizeof (uuid), (uintptr_t)a.al_uuid) <= 0)
11089120SStephen.Hanson@Sun.COM (void) mdb_snprintf(uuid, sizeof (uuid), "<%p>", a.al_uuid);
11099120SStephen.Hanson@Sun.COM if (mdb_readstr(name, sizeof (name), (uintptr_t)a.al_rsrc_name) <= 0)
11109120SStephen.Hanson@Sun.COM (void) mdb_snprintf(name, sizeof (name), "<%p>",
11119120SStephen.Hanson@Sun.COM a.al_rsrc_name);
11129120SStephen.Hanson@Sun.COM
11139120SStephen.Hanson@Sun.COM mdb_printf("%-8p %-36s %s\n", addr, uuid, name);
11149120SStephen.Hanson@Sun.COM return (DCMD_OK);
11159120SStephen.Hanson@Sun.COM }
11169120SStephen.Hanson@Sun.COM
11170Sstevel@tonic-gate /*ARGSUSED*/
11180Sstevel@tonic-gate static int
fcf_hdr(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)11190Sstevel@tonic-gate fcf_hdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
11200Sstevel@tonic-gate {
11210Sstevel@tonic-gate fcf_hdr_t h;
11220Sstevel@tonic-gate
11230Sstevel@tonic-gate if (argc != 0)
11240Sstevel@tonic-gate return (DCMD_USAGE);
11250Sstevel@tonic-gate
11260Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC))
11270Sstevel@tonic-gate addr = 0; /* assume base of file in file target */
11280Sstevel@tonic-gate
11290Sstevel@tonic-gate if (mdb_vread(&h, sizeof (h), addr) != sizeof (h)) {
11300Sstevel@tonic-gate mdb_warn("failed to read header at %p", addr);
11310Sstevel@tonic-gate return (DCMD_ERR);
11320Sstevel@tonic-gate }
11330Sstevel@tonic-gate
11340Sstevel@tonic-gate mdb_printf("fcfh_ident.id_magic = 0x%x, %c, %c, %c\n",
11350Sstevel@tonic-gate h.fcfh_ident[FCF_ID_MAG0], h.fcfh_ident[FCF_ID_MAG1],
11360Sstevel@tonic-gate h.fcfh_ident[FCF_ID_MAG2], h.fcfh_ident[FCF_ID_MAG3]);
11370Sstevel@tonic-gate
11380Sstevel@tonic-gate switch (h.fcfh_ident[FCF_ID_MODEL]) {
11390Sstevel@tonic-gate case FCF_MODEL_ILP32:
11400Sstevel@tonic-gate mdb_printf("fcfh_ident.id_model = ILP32\n");
11410Sstevel@tonic-gate break;
11420Sstevel@tonic-gate case FCF_MODEL_LP64:
11430Sstevel@tonic-gate mdb_printf("fcfh_ident.id_model = LP64\n");
11440Sstevel@tonic-gate break;
11450Sstevel@tonic-gate default:
11460Sstevel@tonic-gate mdb_printf("fcfh_ident.id_model = 0x%x\n",
11470Sstevel@tonic-gate h.fcfh_ident[FCF_ID_MODEL]);
11480Sstevel@tonic-gate }
11490Sstevel@tonic-gate
11500Sstevel@tonic-gate switch (h.fcfh_ident[FCF_ID_ENCODING]) {
11510Sstevel@tonic-gate case FCF_ENCODE_LSB:
11520Sstevel@tonic-gate mdb_printf("fcfh_ident.id_encoding = LSB\n");
11530Sstevel@tonic-gate break;
11540Sstevel@tonic-gate case FCF_ENCODE_MSB:
11550Sstevel@tonic-gate mdb_printf("fcfh_ident.id_encoding = MSB\n");
11560Sstevel@tonic-gate break;
11570Sstevel@tonic-gate default:
11580Sstevel@tonic-gate mdb_printf("fcfh_ident.id_encoding = 0x%x\n",
11590Sstevel@tonic-gate h.fcfh_ident[FCF_ID_ENCODING]);
11600Sstevel@tonic-gate }
11610Sstevel@tonic-gate
11620Sstevel@tonic-gate mdb_printf("fcfh_ident.id_version = %u\n",
11630Sstevel@tonic-gate h.fcfh_ident[FCF_ID_VERSION]);
11640Sstevel@tonic-gate
11650Sstevel@tonic-gate mdb_printf("fcfh_flags = 0x%x\n", h.fcfh_flags);
11660Sstevel@tonic-gate mdb_printf("fcfh_hdrsize = %u\n", h.fcfh_hdrsize);
11670Sstevel@tonic-gate mdb_printf("fcfh_secsize = %u\n", h.fcfh_secsize);
11680Sstevel@tonic-gate mdb_printf("fcfh_secnum = %u\n", h.fcfh_secnum);
11690Sstevel@tonic-gate mdb_printf("fcfh_secoff = %llu\n", h.fcfh_secoff);
11700Sstevel@tonic-gate mdb_printf("fcfh_filesz = %llu\n", h.fcfh_filesz);
11710Sstevel@tonic-gate mdb_printf("fcfh_cgen = %llu\n", h.fcfh_cgen);
11720Sstevel@tonic-gate
11730Sstevel@tonic-gate return (DCMD_OK);
11740Sstevel@tonic-gate }
11750Sstevel@tonic-gate
11769694SScott.Rotondo@Sun.COM static int fcf_sec(uintptr_t, uint_t, int, const mdb_arg_t *);
11770Sstevel@tonic-gate /*ARGSUSED*/
11780Sstevel@tonic-gate static int
fcf_sec_one(uintptr_t addr,void * ignored,uint_t * secp)11790Sstevel@tonic-gate fcf_sec_one(uintptr_t addr, void *ignored, uint_t *secp)
11800Sstevel@tonic-gate {
11810Sstevel@tonic-gate
11820Sstevel@tonic-gate mdb_printf("%3d ", (*secp)++);
11830Sstevel@tonic-gate (void) fcf_sec(addr, DCMD_ADDRSPEC | DCMD_LOOP, 0, NULL);
11840Sstevel@tonic-gate return (WALK_NEXT);
11850Sstevel@tonic-gate }
11860Sstevel@tonic-gate
11870Sstevel@tonic-gate /*ARGSUSED*/
11880Sstevel@tonic-gate static int
fcf_sec(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)11890Sstevel@tonic-gate fcf_sec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
11900Sstevel@tonic-gate {
11910Sstevel@tonic-gate static const char *const types[] = {
11920Sstevel@tonic-gate "none", /* FCF_SECT_NONE */
11930Sstevel@tonic-gate "strtab", /* FCF_SECT_STRTAB */
11940Sstevel@tonic-gate "module", /* FCF_SECT_MODULE */
11950Sstevel@tonic-gate "case", /* FCF_SECT_CASE */
11960Sstevel@tonic-gate "bufs", /* FCF_SECT_BUFS */
11970Sstevel@tonic-gate "buffer", /* FCF_SECT_BUFFER */
11980Sstevel@tonic-gate "serd", /* FCF_SECT_SERD */
11990Sstevel@tonic-gate "events", /* FCF_SECT_EVENTS */
12000Sstevel@tonic-gate "nvlists", /* FCF_SECT_NVLISTS */
12010Sstevel@tonic-gate };
12020Sstevel@tonic-gate
12030Sstevel@tonic-gate uint_t sec = 0;
12040Sstevel@tonic-gate fcf_sec_t s;
12050Sstevel@tonic-gate
12060Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC))
12070Sstevel@tonic-gate mdb_printf("%<u>%-3s ", "NDX");
12080Sstevel@tonic-gate
12090Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC) || DCMD_HDRSPEC(flags)) {
12100Sstevel@tonic-gate mdb_printf("%<u>%?s %-10s %-5s %-5s %-5s %-6s %-5s%</u>\n",
12110Sstevel@tonic-gate "ADDR", "TYPE", "ALIGN", "FLAGS", "ENTSZ", "OFF", "SIZE");
12120Sstevel@tonic-gate }
12130Sstevel@tonic-gate
12140Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
12150Sstevel@tonic-gate if (mdb_walk("fcf_sec", (mdb_walk_cb_t)fcf_sec_one, &sec) < 0) {
12160Sstevel@tonic-gate mdb_warn("failed to walk fcf_sec");
12170Sstevel@tonic-gate return (DCMD_ERR);
12180Sstevel@tonic-gate }
12190Sstevel@tonic-gate return (DCMD_OK);
12200Sstevel@tonic-gate }
12210Sstevel@tonic-gate
12220Sstevel@tonic-gate if (argc != 0)
12230Sstevel@tonic-gate return (DCMD_USAGE);
12240Sstevel@tonic-gate
12250Sstevel@tonic-gate if (mdb_vread(&s, sizeof (s), addr) != sizeof (s)) {
12260Sstevel@tonic-gate mdb_warn("failed to read section header at %p", addr);
12270Sstevel@tonic-gate return (DCMD_ERR);
12280Sstevel@tonic-gate }
12290Sstevel@tonic-gate
12300Sstevel@tonic-gate mdb_printf("%?p ", addr);
12310Sstevel@tonic-gate
12320Sstevel@tonic-gate if (s.fcfs_type < sizeof (types) / sizeof (types[0]))
12330Sstevel@tonic-gate mdb_printf("%-10s ", types[s.fcfs_type]);
12340Sstevel@tonic-gate else
12350Sstevel@tonic-gate mdb_printf("%-10u ", s.fcfs_type);
12360Sstevel@tonic-gate
12370Sstevel@tonic-gate mdb_printf("%-5u %-#5x %-#5x %-6llx %-#5llx\n", s.fcfs_align,
12380Sstevel@tonic-gate s.fcfs_flags, s.fcfs_entsize, s.fcfs_offset, s.fcfs_size);
12390Sstevel@tonic-gate
12400Sstevel@tonic-gate return (DCMD_OK);
12410Sstevel@tonic-gate }
12420Sstevel@tonic-gate
12430Sstevel@tonic-gate static int
fcf_sec_walk_init(mdb_walk_state_t * wsp)12440Sstevel@tonic-gate fcf_sec_walk_init(mdb_walk_state_t *wsp)
12450Sstevel@tonic-gate {
12460Sstevel@tonic-gate fcf_hdr_t h, *hp;
12470Sstevel@tonic-gate size_t size;
12480Sstevel@tonic-gate
12490Sstevel@tonic-gate if (mdb_vread(&h, sizeof (h), wsp->walk_addr) != sizeof (h)) {
12500Sstevel@tonic-gate mdb_warn("failed to read FCF header at %p", wsp->walk_addr);
12510Sstevel@tonic-gate return (WALK_ERR);
12520Sstevel@tonic-gate }
12530Sstevel@tonic-gate
12540Sstevel@tonic-gate size = sizeof (fcf_hdr_t) + sizeof (fcf_sec_t) * h.fcfh_secnum;
12550Sstevel@tonic-gate hp = mdb_alloc(size, UM_SLEEP);
12560Sstevel@tonic-gate
12570Sstevel@tonic-gate if (mdb_vread(hp, size, wsp->walk_addr) != size) {
12580Sstevel@tonic-gate mdb_warn("failed to read FCF sections at %p", wsp->walk_addr);
12590Sstevel@tonic-gate mdb_free(hp, size);
12600Sstevel@tonic-gate return (WALK_ERR);
12610Sstevel@tonic-gate }
12620Sstevel@tonic-gate
12630Sstevel@tonic-gate wsp->walk_data = hp;
12640Sstevel@tonic-gate wsp->walk_arg = 0;
12650Sstevel@tonic-gate
12660Sstevel@tonic-gate return (WALK_NEXT);
12670Sstevel@tonic-gate }
12680Sstevel@tonic-gate
12690Sstevel@tonic-gate static int
fcf_sec_walk_step(mdb_walk_state_t * wsp)12700Sstevel@tonic-gate fcf_sec_walk_step(mdb_walk_state_t *wsp)
12710Sstevel@tonic-gate {
12720Sstevel@tonic-gate uint_t i = (uint_t)wsp->walk_arg;
12730Sstevel@tonic-gate size_t off = sizeof (fcf_hdr_t) + sizeof (fcf_sec_t) * i;
12740Sstevel@tonic-gate fcf_hdr_t *hp = wsp->walk_data;
12750Sstevel@tonic-gate fcf_sec_t *sp = (fcf_sec_t *)((uintptr_t)hp + off);
12760Sstevel@tonic-gate
12770Sstevel@tonic-gate if (i >= hp->fcfh_secnum)
12780Sstevel@tonic-gate return (WALK_DONE);
12790Sstevel@tonic-gate
12800Sstevel@tonic-gate wsp->walk_arg = (void *)(i + 1);
12810Sstevel@tonic-gate return (wsp->walk_callback(wsp->walk_addr + off, sp, wsp->walk_cbdata));
12820Sstevel@tonic-gate }
12830Sstevel@tonic-gate
12840Sstevel@tonic-gate static void
fcf_sec_walk_fini(mdb_walk_state_t * wsp)12850Sstevel@tonic-gate fcf_sec_walk_fini(mdb_walk_state_t *wsp)
12860Sstevel@tonic-gate {
12870Sstevel@tonic-gate fcf_hdr_t *hp = wsp->walk_data;
12880Sstevel@tonic-gate mdb_free(hp, sizeof (fcf_hdr_t) + sizeof (fcf_sec_t) * hp->fcfh_secnum);
12890Sstevel@tonic-gate }
12900Sstevel@tonic-gate
12910Sstevel@tonic-gate /*ARGSUSED*/
12920Sstevel@tonic-gate static int
fcf_case(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)12930Sstevel@tonic-gate fcf_case(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
12940Sstevel@tonic-gate {
12950Sstevel@tonic-gate fcf_case_t fcfc;
12960Sstevel@tonic-gate
12970Sstevel@tonic-gate if (argc != 0)
12980Sstevel@tonic-gate return (DCMD_USAGE);
12990Sstevel@tonic-gate
13000Sstevel@tonic-gate if (mdb_vread(&fcfc, sizeof (fcfc), addr) != sizeof (fcfc)) {
13010Sstevel@tonic-gate mdb_warn("failed to read case at %p", addr);
13020Sstevel@tonic-gate return (DCMD_ERR);
13030Sstevel@tonic-gate }
13040Sstevel@tonic-gate
13050Sstevel@tonic-gate mdb_printf("fcfc_uuid = 0x%x\n", fcfc.fcfc_uuid);
13060Sstevel@tonic-gate mdb_printf("fcfc_state = %u\n", fcfc.fcfc_state);
13070Sstevel@tonic-gate mdb_printf("fcfc_bufs = %u\n", fcfc.fcfc_bufs);
13080Sstevel@tonic-gate mdb_printf("fcfc_events = %u\n", fcfc.fcfc_events);
13090Sstevel@tonic-gate mdb_printf("fcfc_suspects = %u\n", fcfc.fcfc_suspects);
13100Sstevel@tonic-gate
13110Sstevel@tonic-gate return (DCMD_OK);
13120Sstevel@tonic-gate }
13130Sstevel@tonic-gate
13140Sstevel@tonic-gate /*ARGSUSED*/
13150Sstevel@tonic-gate static int
fcf_event(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)13160Sstevel@tonic-gate fcf_event(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
13170Sstevel@tonic-gate {
13180Sstevel@tonic-gate fcf_event_t fcfe;
13190Sstevel@tonic-gate
13200Sstevel@tonic-gate if (argc != 0)
13210Sstevel@tonic-gate return (DCMD_USAGE);
13220Sstevel@tonic-gate
13230Sstevel@tonic-gate if (mdb_vread(&fcfe, sizeof (fcfe), addr) != sizeof (fcfe)) {
13240Sstevel@tonic-gate mdb_warn("failed to read event at %p", addr);
13250Sstevel@tonic-gate return (DCMD_ERR);
13260Sstevel@tonic-gate }
13270Sstevel@tonic-gate
13280Sstevel@tonic-gate mdb_printf("fcfe_todsec = %llu (%Y)\n",
13290Sstevel@tonic-gate fcfe.fcfe_todsec, (time_t)fcfe.fcfe_todsec);
13300Sstevel@tonic-gate mdb_printf("fcfe_todnsec = %llu\n", fcfe.fcfe_todnsec);
13310Sstevel@tonic-gate mdb_printf("fcfe_major = %u\n", fcfe.fcfe_major);
13320Sstevel@tonic-gate mdb_printf("fcfe_minor = %u\n", fcfe.fcfe_minor);
13330Sstevel@tonic-gate mdb_printf("fcfe_inode = %llu\n", fcfe.fcfe_inode);
13340Sstevel@tonic-gate mdb_printf("fcfe_offset = %llu\n", fcfe.fcfe_offset);
13350Sstevel@tonic-gate
13360Sstevel@tonic-gate return (DCMD_OK);
13370Sstevel@tonic-gate }
13380Sstevel@tonic-gate
13390Sstevel@tonic-gate /*ARGSUSED*/
13400Sstevel@tonic-gate static int
fcf_serd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)13410Sstevel@tonic-gate fcf_serd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
13420Sstevel@tonic-gate {
13430Sstevel@tonic-gate fcf_serd_t fcfd;
13440Sstevel@tonic-gate
13450Sstevel@tonic-gate if (argc != 0)
13460Sstevel@tonic-gate return (DCMD_USAGE);
13470Sstevel@tonic-gate
13480Sstevel@tonic-gate if (mdb_vread(&fcfd, sizeof (fcfd), addr) != sizeof (fcfd)) {
13490Sstevel@tonic-gate mdb_warn("failed to read serd at %p", addr);
13500Sstevel@tonic-gate return (DCMD_ERR);
13510Sstevel@tonic-gate }
13520Sstevel@tonic-gate
13530Sstevel@tonic-gate mdb_printf("fcfd_name = 0x%x\n", fcfd.fcfd_name);
13540Sstevel@tonic-gate mdb_printf("fcfd_events = %u\n", fcfd.fcfd_events);
13550Sstevel@tonic-gate mdb_printf("fcfd_n = >%u\n", fcfd.fcfd_n);
13560Sstevel@tonic-gate mdb_printf("fcfd_t = %lluns\n", fcfd.fcfd_t);
13570Sstevel@tonic-gate
13580Sstevel@tonic-gate return (DCMD_OK);
13590Sstevel@tonic-gate }
13600Sstevel@tonic-gate
13610Sstevel@tonic-gate static int
tmq_walk_init(mdb_walk_state_t * wsp)13620Sstevel@tonic-gate tmq_walk_init(mdb_walk_state_t *wsp)
13630Sstevel@tonic-gate {
13640Sstevel@tonic-gate fmd_timerq_t tmq;
13650Sstevel@tonic-gate fmd_t F;
13660Sstevel@tonic-gate
13670Sstevel@tonic-gate if (wsp->walk_addr == NULL && mdb_readvar(&F, "fmd") != sizeof (F)) {
13680Sstevel@tonic-gate mdb_warn("failed to read fmd meta-data");
13690Sstevel@tonic-gate return (WALK_ERR);
13700Sstevel@tonic-gate }
13710Sstevel@tonic-gate
13720Sstevel@tonic-gate if (wsp->walk_addr == NULL)
13730Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)F.d_timers;
13740Sstevel@tonic-gate
13750Sstevel@tonic-gate if (mdb_vread(&tmq, sizeof (tmq), wsp->walk_addr) != sizeof (tmq)) {
13760Sstevel@tonic-gate mdb_warn("failed to read timerq at %p", wsp->walk_addr);
13770Sstevel@tonic-gate return (WALK_ERR);
13780Sstevel@tonic-gate }
13790Sstevel@tonic-gate
13800Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)tmq.tmq_list.l_next;
13810Sstevel@tonic-gate return (WALK_NEXT);
13820Sstevel@tonic-gate }
13830Sstevel@tonic-gate
13840Sstevel@tonic-gate static int
tmq_walk_step(mdb_walk_state_t * wsp)13850Sstevel@tonic-gate tmq_walk_step(mdb_walk_state_t *wsp)
13860Sstevel@tonic-gate {
13870Sstevel@tonic-gate uintptr_t addr = wsp->walk_addr;
13880Sstevel@tonic-gate fmd_timer_t tmr;
13890Sstevel@tonic-gate
13900Sstevel@tonic-gate if (addr == NULL)
13910Sstevel@tonic-gate return (WALK_DONE);
13920Sstevel@tonic-gate
13930Sstevel@tonic-gate if (mdb_vread(&tmr, sizeof (tmr), addr) != sizeof (tmr)) {
13940Sstevel@tonic-gate mdb_warn("failed to read fmd_timer at %p", addr);
13950Sstevel@tonic-gate return (WALK_ERR);
13960Sstevel@tonic-gate }
13970Sstevel@tonic-gate
13980Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)tmr.tmr_list.l_next;
13990Sstevel@tonic-gate return (wsp->walk_callback(addr, &tmr, wsp->walk_cbdata));
14000Sstevel@tonic-gate }
14010Sstevel@tonic-gate
14020Sstevel@tonic-gate static int
fmd_timer(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)14030Sstevel@tonic-gate fmd_timer(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
14040Sstevel@tonic-gate {
14050Sstevel@tonic-gate char name[32], func[MDB_SYM_NAMLEN];
14060Sstevel@tonic-gate fmd_timer_t t;
14070Sstevel@tonic-gate
14080Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
14090Sstevel@tonic-gate if (mdb_walk_dcmd("fmd_timerq", "fmd_timer", argc, argv) != 0) {
14100Sstevel@tonic-gate mdb_warn("failed to walk fmd_timerq");
14110Sstevel@tonic-gate return (DCMD_ERR);
14120Sstevel@tonic-gate }
14130Sstevel@tonic-gate return (DCMD_OK);
14140Sstevel@tonic-gate }
14150Sstevel@tonic-gate
14160Sstevel@tonic-gate if (mdb_vread(&t, sizeof (t), addr) != sizeof (t)) {
14170Sstevel@tonic-gate mdb_warn("failed to read fmd_timer at %p", addr);
14180Sstevel@tonic-gate return (DCMD_ERR);
14190Sstevel@tonic-gate }
14200Sstevel@tonic-gate
14210Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) {
14220Sstevel@tonic-gate mdb_printf("%<u>%-8s %-20s %-4s %-18s %-8s %s%</u>\n",
14230Sstevel@tonic-gate "ADDR", "MODULE", "ID", "HRTIME", "ARG", "FUNC");
14240Sstevel@tonic-gate }
14250Sstevel@tonic-gate
14260Sstevel@tonic-gate if (mdb_readstr(name, sizeof (name), (uintptr_t)
14270Sstevel@tonic-gate t.tmr_ids + OFFSETOF(fmd_idspace_t, ids_name)) <= 0)
14280Sstevel@tonic-gate (void) mdb_snprintf(name, sizeof (name), "<%p>", t.tmr_ids);
14290Sstevel@tonic-gate
14300Sstevel@tonic-gate if (mdb_lookup_by_addr((uintptr_t)t.tmr_func, MDB_SYM_FUZZY,
14310Sstevel@tonic-gate func, sizeof (func), NULL) != 0)
14320Sstevel@tonic-gate (void) mdb_snprintf(func, sizeof (func), "<%p>", t.tmr_func);
14330Sstevel@tonic-gate
14340Sstevel@tonic-gate mdb_printf("%-8p %-20s %4d 0x%-16llx %-8p %s\n",
14350Sstevel@tonic-gate addr, name, t.tmr_id, t.tmr_hrt, t.tmr_arg, func);
14360Sstevel@tonic-gate return (DCMD_OK);
14370Sstevel@tonic-gate }
14380Sstevel@tonic-gate
14391193Smws static int
xprt_walk_init(mdb_walk_state_t * wsp)14401193Smws xprt_walk_init(mdb_walk_state_t *wsp)
14411193Smws {
14421193Smws fmd_module_t m;
14431193Smws
14441193Smws if (wsp->walk_addr == NULL) {
14451193Smws mdb_warn("transport walker requires fmd_module_t address\n");
14461193Smws return (WALK_ERR);
14471193Smws }
14481193Smws
14491193Smws if (mdb_vread(&m, sizeof (m), wsp->walk_addr) != sizeof (m)) {
14501193Smws mdb_warn("failed to read module at %p", wsp->walk_addr);
14511193Smws return (WALK_ERR);
14521193Smws }
14531193Smws
14541193Smws wsp->walk_addr = (uintptr_t)m.mod_transports.l_next;
14551193Smws return (WALK_NEXT);
14561193Smws }
14571193Smws
14581193Smws static int
xprt_walk_step(mdb_walk_state_t * wsp)14591193Smws xprt_walk_step(mdb_walk_state_t *wsp)
14601193Smws {
14611193Smws uintptr_t addr = wsp->walk_addr;
14621193Smws fmd_xprt_impl_t xi;
14631193Smws
14641193Smws if (addr == NULL)
14651193Smws return (WALK_DONE);
14661193Smws
14671193Smws if (mdb_vread(&xi, sizeof (xi), addr) != sizeof (xi)) {
14681193Smws mdb_warn("failed to read fmd_xprt at %p", addr);
14691193Smws return (WALK_ERR);
14701193Smws }
14711193Smws
14721193Smws wsp->walk_addr = (uintptr_t)xi.xi_list.l_next;
14731193Smws return (wsp->walk_callback(addr, &xi, wsp->walk_cbdata));
14741193Smws }
14751193Smws
14761193Smws static int
xpc_walk_init(mdb_walk_state_t * wsp)14771193Smws xpc_walk_init(mdb_walk_state_t *wsp)
14781193Smws {
14791193Smws fmd_xprt_class_hash_t xch;
14801193Smws
14811193Smws if (mdb_vread(&xch, sizeof (xch), wsp->walk_addr) != sizeof (xch)) {
14821193Smws mdb_warn("failed to read fmd_xprt_class_hash at %p",
14831193Smws wsp->walk_addr);
14841193Smws return (WALK_ERR);
14851193Smws }
14861193Smws
14871193Smws return (hash_walk_init(wsp, (uintptr_t)xch.xch_hash, xch.xch_hashlen,
14881193Smws "fmd_xprt_class", sizeof (fmd_xprt_class_t),
14891193Smws OFFSETOF(fmd_xprt_class_t, xc_next)));
14901193Smws }
14911193Smws
14921193Smws /*ARGSUSED*/
14931193Smws static int
fmd_xprt_class(uintptr_t addr,const void * data,void * arg)14941193Smws fmd_xprt_class(uintptr_t addr, const void *data, void *arg)
14951193Smws {
14961193Smws const fmd_xprt_class_t *xcp = data;
14971193Smws char name[1024];
14981193Smws
14991193Smws if (mdb_readstr(name, sizeof (name), (uintptr_t)xcp->xc_class) <= 0)
15001193Smws (void) mdb_snprintf(name, sizeof (name), "<%p>", xcp->xc_class);
15011193Smws
15021193Smws mdb_printf("%-8p %-4u %s\n", addr, xcp->xc_refs, name);
15031193Smws return (WALK_NEXT);
15041193Smws }
15051193Smws
15061193Smws static int
fmd_xprt(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)15071193Smws fmd_xprt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
15081193Smws {
15091193Smws uint_t opt_s = FALSE, opt_l = FALSE, opt_r = FALSE, opt_u = FALSE;
15101193Smws fmd_xprt_impl_t xi;
15111193Smws
15121193Smws if (mdb_getopts(argc, argv,
15131193Smws 'l', MDB_OPT_SETBITS, TRUE, &opt_l,
15141193Smws 'r', MDB_OPT_SETBITS, TRUE, &opt_r,
15151193Smws 's', MDB_OPT_SETBITS, TRUE, &opt_s,
15161193Smws 'u', MDB_OPT_SETBITS, TRUE, &opt_u, NULL) != argc)
15171193Smws return (DCMD_USAGE);
15181193Smws
15191193Smws if (!(flags & DCMD_ADDRSPEC)) {
15201193Smws if (mdb_walk_dcmd("fmd_xprt", "fmd_xprt", argc, argv) != 0) {
15211193Smws mdb_warn("failed to walk fmd_xprt");
15221193Smws return (DCMD_ERR);
15231193Smws }
15241193Smws return (DCMD_OK);
15251193Smws }
15261193Smws
15271193Smws if (mdb_vread(&xi, sizeof (xi), addr) != sizeof (xi)) {
15281193Smws mdb_warn("failed to read fmd_xprt at %p", addr);
15291193Smws return (DCMD_ERR);
15301193Smws }
15311193Smws
15321193Smws if (DCMD_HDRSPEC(flags)) {
15331193Smws mdb_printf("%<u>%-8s %-4s %-4s %-5s %s%</u>\n",
15341193Smws "ADDR", "ID", "VERS", "FLAGS", "STATE");
15351193Smws }
15361193Smws
15371193Smws mdb_printf("%-8p %-4d %-4u %-5x %a\n",
15381193Smws addr, xi.xi_id, xi.xi_version, xi.xi_flags, xi.xi_state);
15391193Smws
15401193Smws if (opt_l | opt_s) {
15411193Smws (void) mdb_inc_indent(4);
15421193Smws mdb_printf("Local subscriptions requested by peer:\n");
15431193Smws mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS");
15441193Smws (void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class, &xi,
15451193Smws addr + OFFSETOF(fmd_xprt_impl_t, xi_lsub));
15461193Smws (void) mdb_dec_indent(4);
15471193Smws }
15481193Smws
15491193Smws if (opt_r | opt_s) {
15501193Smws (void) mdb_inc_indent(4);
15511193Smws mdb_printf("Remote subscriptions requested of peer:\n");
15521193Smws mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS");
15531193Smws (void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class, &xi,
15541193Smws addr + OFFSETOF(fmd_xprt_impl_t, xi_rsub));
15551193Smws (void) mdb_dec_indent(4);
15561193Smws }
15571193Smws
15581193Smws if (opt_u | opt_s) {
15591193Smws (void) mdb_inc_indent(4);
15601193Smws mdb_printf("Pending unsubscription acknowledgements:\n");
15611193Smws mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS");
15621193Smws (void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class, &xi,
15631193Smws addr + OFFSETOF(fmd_xprt_impl_t, xi_usub));
15641193Smws (void) mdb_dec_indent(4);
15651193Smws }
15661193Smws
15671193Smws return (DCMD_OK);
15681193Smws }
15691193Smws
157012066SRobert.Johnston@Sun.COM static int
tsnap_walk_init(mdb_walk_state_t * wsp)157112066SRobert.Johnston@Sun.COM tsnap_walk_init(mdb_walk_state_t *wsp)
157212066SRobert.Johnston@Sun.COM {
157312066SRobert.Johnston@Sun.COM fmd_t F;
157412066SRobert.Johnston@Sun.COM
157512066SRobert.Johnston@Sun.COM if (mdb_readvar(&F, "fmd") != sizeof (F)) {
157612066SRobert.Johnston@Sun.COM mdb_warn("failed to read fmd meta-data");
157712066SRobert.Johnston@Sun.COM return (WALK_ERR);
157812066SRobert.Johnston@Sun.COM }
157912066SRobert.Johnston@Sun.COM
158012066SRobert.Johnston@Sun.COM wsp->walk_addr = (uintptr_t)F.d_topo_list.l_next;
158112066SRobert.Johnston@Sun.COM return (WALK_NEXT);
158212066SRobert.Johnston@Sun.COM }
158312066SRobert.Johnston@Sun.COM
158412066SRobert.Johnston@Sun.COM static int
tsnap_walk_step(mdb_walk_state_t * wsp)158512066SRobert.Johnston@Sun.COM tsnap_walk_step(mdb_walk_state_t *wsp)
158612066SRobert.Johnston@Sun.COM {
158712066SRobert.Johnston@Sun.COM uintptr_t addr = wsp->walk_addr;
158812066SRobert.Johnston@Sun.COM fmd_topo_t ftp;
158912066SRobert.Johnston@Sun.COM
159012066SRobert.Johnston@Sun.COM if (addr == NULL)
159112066SRobert.Johnston@Sun.COM return (WALK_DONE);
159212066SRobert.Johnston@Sun.COM
159312066SRobert.Johnston@Sun.COM if (mdb_vread(&ftp, sizeof (ftp), addr) != sizeof (ftp)) {
159412066SRobert.Johnston@Sun.COM mdb_warn("failed to read fmd_topo_t at %p", addr);
159512066SRobert.Johnston@Sun.COM return (WALK_ERR);
159612066SRobert.Johnston@Sun.COM }
159712066SRobert.Johnston@Sun.COM
159812066SRobert.Johnston@Sun.COM wsp->walk_addr = (uintptr_t)ftp.ft_list.l_next;
159912066SRobert.Johnston@Sun.COM return (wsp->walk_callback(addr, &ftp, wsp->walk_cbdata));
160012066SRobert.Johnston@Sun.COM }
160112066SRobert.Johnston@Sun.COM
160212066SRobert.Johnston@Sun.COM static int
mq_walk_init(mdb_walk_state_t * wsp)160312066SRobert.Johnston@Sun.COM mq_walk_init(mdb_walk_state_t *wsp)
160412066SRobert.Johnston@Sun.COM {
160512066SRobert.Johnston@Sun.COM fmd_module_t m;
160612066SRobert.Johnston@Sun.COM struct fmd_eventq eq;
160712066SRobert.Johnston@Sun.COM
160812066SRobert.Johnston@Sun.COM if (wsp->walk_addr == NULL) {
160912066SRobert.Johnston@Sun.COM mdb_warn("NULL fmd_module_t passed in");
161012066SRobert.Johnston@Sun.COM return (WALK_ERR);
161112066SRobert.Johnston@Sun.COM }
161212066SRobert.Johnston@Sun.COM
161312066SRobert.Johnston@Sun.COM if (mdb_vread(&m, sizeof (m), wsp->walk_addr) != sizeof (m)) {
161412066SRobert.Johnston@Sun.COM mdb_warn("failed to read fmd_module_t at %p", wsp->walk_addr);
161512066SRobert.Johnston@Sun.COM return (WALK_ERR);
161612066SRobert.Johnston@Sun.COM }
161712066SRobert.Johnston@Sun.COM if (mdb_vread(&eq, sizeof (eq), (uintptr_t)m.mod_queue)
161812066SRobert.Johnston@Sun.COM != sizeof (eq)) {
161912066SRobert.Johnston@Sun.COM mdb_warn("failed to read fmd_eventq at %p", wsp->walk_addr);
162012066SRobert.Johnston@Sun.COM return (WALK_ERR);
162112066SRobert.Johnston@Sun.COM }
162212066SRobert.Johnston@Sun.COM
162312066SRobert.Johnston@Sun.COM wsp->walk_addr = (uintptr_t)eq.eq_list.l_next;
162412066SRobert.Johnston@Sun.COM
162512066SRobert.Johnston@Sun.COM return (WALK_NEXT);
162612066SRobert.Johnston@Sun.COM }
162712066SRobert.Johnston@Sun.COM
162812066SRobert.Johnston@Sun.COM static int
mq_walk_step(mdb_walk_state_t * wsp)162912066SRobert.Johnston@Sun.COM mq_walk_step(mdb_walk_state_t *wsp)
163012066SRobert.Johnston@Sun.COM {
163112066SRobert.Johnston@Sun.COM uintptr_t addr = wsp->walk_addr;
163212066SRobert.Johnston@Sun.COM fmd_eventqelem_t eqe;
163312066SRobert.Johnston@Sun.COM
163412066SRobert.Johnston@Sun.COM if (addr == NULL)
163512066SRobert.Johnston@Sun.COM return (WALK_DONE);
163612066SRobert.Johnston@Sun.COM
163712066SRobert.Johnston@Sun.COM if (mdb_vread(&eqe, sizeof (eqe), addr) != sizeof (eqe)) {
163812066SRobert.Johnston@Sun.COM mdb_warn("failed to read fmd_eventqelem_t at %p", addr);
163912066SRobert.Johnston@Sun.COM return (WALK_ERR);
164012066SRobert.Johnston@Sun.COM }
164112066SRobert.Johnston@Sun.COM
164212066SRobert.Johnston@Sun.COM wsp->walk_addr = (uintptr_t)eqe.eqe_list.l_next;
164312066SRobert.Johnston@Sun.COM return (wsp->walk_callback(addr, &eqe, wsp->walk_cbdata));
164412066SRobert.Johnston@Sun.COM }
164512066SRobert.Johnston@Sun.COM
16460Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = {
16470Sstevel@tonic-gate { "fcf_case", "?", "print a FCF case", fcf_case },
16480Sstevel@tonic-gate { "fcf_event", "?", "print a FCF event", fcf_event },
16490Sstevel@tonic-gate { "fcf_hdr", "?", "print a FCF header", fcf_hdr },
16500Sstevel@tonic-gate { "fcf_sec", ":", "print a FCF section header", fcf_sec },
16510Sstevel@tonic-gate { "fcf_serd", "?", "print a FCF serd engine", fcf_serd },
16520Sstevel@tonic-gate { "fmd_trace", "?[-cs]", "display thread trace buffer(s)", fmd_trace },
16535433Saf { "fmd_ustat", "[:]", "display statistics collection", fmd_ustat },
16545433Saf { "fmd_stat", "[:]", "display statistic structure", fmd_stat },
16550Sstevel@tonic-gate { "fmd_event", NULL, "display event structure", fmd_event },
16560Sstevel@tonic-gate { "fmd_thread", "?", "display thread or list of threads", fmd_thread },
16570Sstevel@tonic-gate { "fmd_module", "?", "display module or list of modules", fmd_module },
16580Sstevel@tonic-gate { "fmd_case", ":", "display case file structure", fmd_case },
16590Sstevel@tonic-gate { "fmd_buf", ":", "display buffer structure", fmd_buf },
16605433Saf { "fmd_serd", "[:]", "display serd engine structure", fmd_serd },
16610Sstevel@tonic-gate { "fmd_asru", "?", "display asru resource structure", fmd_asru },
16629120SStephen.Hanson@Sun.COM { "fmd_asru_link", "?", "display resource structure", fmd_asru_link },
16630Sstevel@tonic-gate { "fmd_timer", "?", "display pending timer(s)", fmd_timer },
16641193Smws { "fmd_xprt", "?[-lrsu]", "display event transport(s)", fmd_xprt },
16650Sstevel@tonic-gate { NULL }
16660Sstevel@tonic-gate };
16670Sstevel@tonic-gate
16680Sstevel@tonic-gate static const mdb_walker_t walkers[] = {
16690Sstevel@tonic-gate { "fcf_sec", "walk FCF section header table given header address",
16700Sstevel@tonic-gate fcf_sec_walk_init, fcf_sec_walk_step, fcf_sec_walk_fini },
16710Sstevel@tonic-gate { "fmd_trace", "walk per-thread trace buffers",
16720Sstevel@tonic-gate trwalk_init, trwalk_step, trwalk_fini },
16730Sstevel@tonic-gate { "fmd_ustat", "walk per-collection statistics",
16740Sstevel@tonic-gate ustat_walk_init, ustat_walk_step, hash_walk_fini },
16750Sstevel@tonic-gate { "fmd_thread", "walk list of all fmd_thread_t's",
16760Sstevel@tonic-gate thread_walk_init, thread_walk_step, NULL },
16770Sstevel@tonic-gate { "fmd_module", "walk list of all fmd_module_t's",
16780Sstevel@tonic-gate mod_walk_init, mod_walk_step, NULL },
16790Sstevel@tonic-gate { "fmd_case", "walk per-module case objects",
16800Sstevel@tonic-gate case_walk_init, case_walk_step, case_walk_fini },
16810Sstevel@tonic-gate { "fmd_buf", "walk per-buf_hash buffers",
16820Sstevel@tonic-gate buf_walk_init, hash_walk_step, hash_walk_fini },
16830Sstevel@tonic-gate { "fmd_serd", "walk per-serd_hash engines",
16840Sstevel@tonic-gate serd_walk_init, hash_walk_step, hash_walk_fini },
16850Sstevel@tonic-gate { "fmd_asru", "walk asru resource hash",
16860Sstevel@tonic-gate asru_walk_init, hash_walk_step, hash_walk_fini },
16879120SStephen.Hanson@Sun.COM { "fmd_asru_link", "walk resource hash",
16889120SStephen.Hanson@Sun.COM al_walk_init, hash_walk_step, hash_walk_fini },
16890Sstevel@tonic-gate { "fmd_timerq", "walk timer queue",
16900Sstevel@tonic-gate tmq_walk_init, tmq_walk_step, NULL },
16911193Smws { "fmd_xprt", "walk per-module list of transports",
16921193Smws xprt_walk_init, xprt_walk_step, NULL },
16931193Smws { "fmd_xprt_class", "walk hash table of subscription classes",
16941193Smws xpc_walk_init, hash_walk_step, hash_walk_fini },
169512066SRobert.Johnston@Sun.COM { "fmd_topo", "walk fmd's list of topo snapshots",
169612066SRobert.Johnston@Sun.COM tsnap_walk_init, tsnap_walk_step, NULL },
169712066SRobert.Johnston@Sun.COM { "fmd_mod_queue", "walk per-module event queue",
169812066SRobert.Johnston@Sun.COM mq_walk_init, mq_walk_step, NULL },
16990Sstevel@tonic-gate { NULL, NULL, NULL, NULL, NULL }
17000Sstevel@tonic-gate };
17010Sstevel@tonic-gate
17020Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
17030Sstevel@tonic-gate
17040Sstevel@tonic-gate const mdb_modinfo_t *
_mdb_init(void)17050Sstevel@tonic-gate _mdb_init(void)
17060Sstevel@tonic-gate {
17070Sstevel@tonic-gate return (&modinfo);
17080Sstevel@tonic-gate }
1709