xref: /onnv-gate/usr/src/cmd/mdb/common/modules/genunix/sysevent.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include "sysevent.h"
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate int
sysevent_buf(uintptr_t addr,uint_t flags,uint_t opt_flags)32*0Sstevel@tonic-gate sysevent_buf(uintptr_t addr, uint_t flags, uint_t opt_flags)
33*0Sstevel@tonic-gate {
34*0Sstevel@tonic-gate 	sysevent_hdr_t evh;
35*0Sstevel@tonic-gate 	sysevent_impl_t *ev;
36*0Sstevel@tonic-gate 	int size;
37*0Sstevel@tonic-gate 
38*0Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
39*0Sstevel@tonic-gate 		if ((opt_flags & SYSEVENT_VERBOSE) == 0) {
40*0Sstevel@tonic-gate 			mdb_printf("%<u>%-?s %-16s %-9s %-10s "
41*0Sstevel@tonic-gate 			    "%-?s%</u>\n", "ADDRESS", "SEQUENCE ID",
42*0Sstevel@tonic-gate 			    "CLASS", "SUBCLASS", "NVPAIR BUF ADDR");
43*0Sstevel@tonic-gate 		}
44*0Sstevel@tonic-gate 	}
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate 	/*
47*0Sstevel@tonic-gate 	 * Read in the sysevent buffer header first.  After extracting
48*0Sstevel@tonic-gate 	 * the size of the buffer, re-read the buffer in its entirety.
49*0Sstevel@tonic-gate 	 */
50*0Sstevel@tonic-gate 	if (mdb_vread(&evh, sizeof (sysevent_hdr_t), addr) == -1) {
51*0Sstevel@tonic-gate 		mdb_warn("failed to read event header at %p", addr);
52*0Sstevel@tonic-gate 		return (DCMD_ERR);
53*0Sstevel@tonic-gate 	}
54*0Sstevel@tonic-gate 
55*0Sstevel@tonic-gate 	size = SE_SIZE((sysevent_impl_t *)&evh);
56*0Sstevel@tonic-gate 	ev = mdb_alloc(size, UM_SLEEP | UM_GC);
57*0Sstevel@tonic-gate 
58*0Sstevel@tonic-gate 	if (mdb_vread(ev, size, addr) == -1) {
59*0Sstevel@tonic-gate 		mdb_warn("can not read sysevent at %p", addr);
60*0Sstevel@tonic-gate 		return (DCMD_ERR);
61*0Sstevel@tonic-gate 	}
62*0Sstevel@tonic-gate 
63*0Sstevel@tonic-gate 	if ((opt_flags & SYSEVENT_VERBOSE) == 0) {
64*0Sstevel@tonic-gate 		char ev_class[CLASS_FIELD_MAX];
65*0Sstevel@tonic-gate 		char ev_subclass[SUBCLASS_FIELD_MAX];
66*0Sstevel@tonic-gate 
67*0Sstevel@tonic-gate 		if (mdb_snprintf(ev_class, CLASS_FIELD_MAX, "%s",
68*0Sstevel@tonic-gate 		    SE_CLASS_NAME(ev)) >= CLASS_FIELD_MAX - 1)
69*0Sstevel@tonic-gate 			(void) strcpy(&ev_class[CLASS_FIELD_MAX - 4], "...");
70*0Sstevel@tonic-gate 
71*0Sstevel@tonic-gate 		if (mdb_snprintf(ev_subclass, SUBCLASS_FIELD_MAX, "%s",
72*0Sstevel@tonic-gate 		    SE_SUBCLASS_NAME(ev)) >= SUBCLASS_FIELD_MAX - 1)
73*0Sstevel@tonic-gate 			(void) strcpy(&ev_subclass[SUBCLASS_FIELD_MAX - 4],
74*0Sstevel@tonic-gate 			    "...");
75*0Sstevel@tonic-gate 
76*0Sstevel@tonic-gate 		mdb_printf("%-?p %-16llu %-9s %-10s %-?p%\n",
77*0Sstevel@tonic-gate 			addr, SE_SEQ(ev), ev_class, ev_subclass,
78*0Sstevel@tonic-gate 			addr + SE_ATTR_OFF(ev));
79*0Sstevel@tonic-gate 	} else {
80*0Sstevel@tonic-gate 		mdb_printf("%<b>Sequence ID\t : %llu%</b>\n", SE_SEQ(ev));
81*0Sstevel@tonic-gate 		mdb_printf("%16s : %s\n", "publisher", SE_PUB_NAME(ev));
82*0Sstevel@tonic-gate 		mdb_printf("%16s : %p\n", "event address", (caddr_t)addr);
83*0Sstevel@tonic-gate 		mdb_printf("%16s : %s\n", "class", SE_CLASS_NAME(ev));
84*0Sstevel@tonic-gate 		mdb_printf("%16s : %s\n", "subclass", SE_SUBCLASS_NAME(ev));
85*0Sstevel@tonic-gate 		mdb_printf("%16s : %llu\n", "time stamp", SE_TIME(ev));
86*0Sstevel@tonic-gate 		mdb_printf("%16s : %p\n", "nvpair buf addr",
87*0Sstevel@tonic-gate 		    addr + SE_ATTR_OFF(ev));
88*0Sstevel@tonic-gate 	}
89*0Sstevel@tonic-gate 
90*0Sstevel@tonic-gate 	return (DCMD_OK);
91*0Sstevel@tonic-gate }
92*0Sstevel@tonic-gate 
93*0Sstevel@tonic-gate int
sysevent_subclass_list(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)94*0Sstevel@tonic-gate sysevent_subclass_list(uintptr_t addr, uint_t flags, int argc,
95*0Sstevel@tonic-gate     const mdb_arg_t *argv)
96*0Sstevel@tonic-gate {
97*0Sstevel@tonic-gate 	int subclass_name_sz;
98*0Sstevel@tonic-gate 	char subclass_name[CLASS_LIST_FIELD_MAX];
99*0Sstevel@tonic-gate 	subclass_lst_t sclist;
100*0Sstevel@tonic-gate 
101*0Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) == 0)
102*0Sstevel@tonic-gate 		return (DCMD_USAGE);
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate 	if ((flags & DCMD_LOOP) == 0) {
105*0Sstevel@tonic-gate 		if (mdb_pwalk_dcmd("sysevent_subclass_list",
106*0Sstevel@tonic-gate 		    "sysevent_subclass_list", argc, argv, addr) == -1) {
107*0Sstevel@tonic-gate 			mdb_warn("can't walk sysevent subclass list");
108*0Sstevel@tonic-gate 			return (DCMD_ERR);
109*0Sstevel@tonic-gate 		}
110*0Sstevel@tonic-gate 		return (DCMD_OK);
111*0Sstevel@tonic-gate 	}
112*0Sstevel@tonic-gate 
113*0Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags)) {
114*0Sstevel@tonic-gate 		mdb_printf("%<u>%-?s %-24s %-?s%</u>\n",
115*0Sstevel@tonic-gate 		    "ADDR", "NAME", "SUBSCRIBER DATA ADDR");
116*0Sstevel@tonic-gate 	}
117*0Sstevel@tonic-gate 	if (mdb_vread(&sclist, sizeof (sclist), (uintptr_t)addr) == -1) {
118*0Sstevel@tonic-gate 		mdb_warn("failed to read subclass list at %p", addr);
119*0Sstevel@tonic-gate 		return (DCMD_ERR);
120*0Sstevel@tonic-gate 	}
121*0Sstevel@tonic-gate 	if ((subclass_name_sz = mdb_readstr(subclass_name, CLASS_LIST_FIELD_MAX,
122*0Sstevel@tonic-gate 	    (uintptr_t)sclist.sl_name)) == -1) {
123*0Sstevel@tonic-gate 		mdb_warn("failed to read class name at %p",
124*0Sstevel@tonic-gate 		    sclist.sl_name);
125*0Sstevel@tonic-gate 		return (DCMD_ERR);
126*0Sstevel@tonic-gate 	}
127*0Sstevel@tonic-gate 	if (subclass_name_sz >= CLASS_LIST_FIELD_MAX - 1)
128*0Sstevel@tonic-gate 		(void) strcpy(&subclass_name[CLASS_LIST_FIELD_MAX - 4], "...");
129*0Sstevel@tonic-gate 
130*0Sstevel@tonic-gate 	mdb_printf("%-?p %-24s %-?p\n", addr, subclass_name,
131*0Sstevel@tonic-gate 	    addr + offsetof(subclass_lst_t, sl_num));
132*0Sstevel@tonic-gate 
133*0Sstevel@tonic-gate 	return (DCMD_OK);
134*0Sstevel@tonic-gate }
135*0Sstevel@tonic-gate 
136*0Sstevel@tonic-gate 
137*0Sstevel@tonic-gate int
sysevent_class_list(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)138*0Sstevel@tonic-gate sysevent_class_list(uintptr_t addr, uint_t flags, int argc,
139*0Sstevel@tonic-gate     const mdb_arg_t *argv)
140*0Sstevel@tonic-gate {
141*0Sstevel@tonic-gate 	int class_name_sz;
142*0Sstevel@tonic-gate 	char class_name[CLASS_LIST_FIELD_MAX];
143*0Sstevel@tonic-gate 	class_lst_t clist;
144*0Sstevel@tonic-gate 
145*0Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) == 0)
146*0Sstevel@tonic-gate 		return (DCMD_USAGE);
147*0Sstevel@tonic-gate 
148*0Sstevel@tonic-gate 	if ((flags & DCMD_LOOP) == 0) {
149*0Sstevel@tonic-gate 		if (mdb_pwalk_dcmd("sysevent_class_list", "sysevent_class_list",
150*0Sstevel@tonic-gate 		    argc, argv, addr) == -1) {
151*0Sstevel@tonic-gate 			mdb_warn("can't walk sysevent class list");
152*0Sstevel@tonic-gate 			return (DCMD_ERR);
153*0Sstevel@tonic-gate 		}
154*0Sstevel@tonic-gate 		return (DCMD_OK);
155*0Sstevel@tonic-gate 	}
156*0Sstevel@tonic-gate 
157*0Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags))
158*0Sstevel@tonic-gate 		mdb_printf("%<u>%-?s %-24s %-?s%</u>\n",
159*0Sstevel@tonic-gate 		    "ADDR", "NAME", "SUBCLASS LIST ADDR");
160*0Sstevel@tonic-gate 
161*0Sstevel@tonic-gate 	if (mdb_vread(&clist, sizeof (clist),
162*0Sstevel@tonic-gate 	    (uintptr_t)addr) == -1) {
163*0Sstevel@tonic-gate 		mdb_warn("failed to read class clist at %p", addr);
164*0Sstevel@tonic-gate 		return (DCMD_ERR);
165*0Sstevel@tonic-gate 	}
166*0Sstevel@tonic-gate 	if ((class_name_sz = mdb_readstr(class_name, CLASS_LIST_FIELD_MAX,
167*0Sstevel@tonic-gate 	    (uintptr_t)clist.cl_name)) == -1) {
168*0Sstevel@tonic-gate 		mdb_warn("failed to read class name at %p",
169*0Sstevel@tonic-gate 		    clist.cl_name);
170*0Sstevel@tonic-gate 		return (DCMD_ERR);
171*0Sstevel@tonic-gate 	}
172*0Sstevel@tonic-gate 	if (class_name_sz >= CLASS_LIST_FIELD_MAX - 1)
173*0Sstevel@tonic-gate 		(void) strcpy(&class_name[CLASS_LIST_FIELD_MAX - 4], "...");
174*0Sstevel@tonic-gate 
175*0Sstevel@tonic-gate 	mdb_printf("%-?p %-24s %-?p\n", addr, class_name,
176*0Sstevel@tonic-gate 	    clist.cl_subclass_list);
177*0Sstevel@tonic-gate 
178*0Sstevel@tonic-gate 	return (DCMD_OK);
179*0Sstevel@tonic-gate }
180*0Sstevel@tonic-gate 
181*0Sstevel@tonic-gate int
sysevent_subclass_list_walk_init(mdb_walk_state_t * wsp)182*0Sstevel@tonic-gate sysevent_subclass_list_walk_init(mdb_walk_state_t *wsp)
183*0Sstevel@tonic-gate {
184*0Sstevel@tonic-gate 	if (wsp->walk_addr == NULL) {
185*0Sstevel@tonic-gate 		mdb_warn("sysevent_subclass_list does not support global "
186*0Sstevel@tonic-gate 		    "walks");
187*0Sstevel@tonic-gate 		return (WALK_ERR);
188*0Sstevel@tonic-gate 	}
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate 	wsp->walk_data = mdb_alloc(sizeof (subclass_lst_t), UM_SLEEP);
191*0Sstevel@tonic-gate 	return (WALK_NEXT);
192*0Sstevel@tonic-gate }
193*0Sstevel@tonic-gate 
194*0Sstevel@tonic-gate int
sysevent_subclass_list_walk_step(mdb_walk_state_t * wsp)195*0Sstevel@tonic-gate sysevent_subclass_list_walk_step(mdb_walk_state_t *wsp)
196*0Sstevel@tonic-gate {
197*0Sstevel@tonic-gate 	int status;
198*0Sstevel@tonic-gate 
199*0Sstevel@tonic-gate 	if (wsp->walk_addr == NULL)
200*0Sstevel@tonic-gate 		return (WALK_DONE);
201*0Sstevel@tonic-gate 
202*0Sstevel@tonic-gate 	if (mdb_vread(wsp->walk_data, sizeof (subclass_lst_t),
203*0Sstevel@tonic-gate 	    wsp->walk_addr) == -1) {
204*0Sstevel@tonic-gate 		mdb_warn("failed to read class list at %p", wsp->walk_addr);
205*0Sstevel@tonic-gate 		return (WALK_ERR);
206*0Sstevel@tonic-gate 	}
207*0Sstevel@tonic-gate 
208*0Sstevel@tonic-gate 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
209*0Sstevel@tonic-gate 	    wsp->walk_cbdata);
210*0Sstevel@tonic-gate 
211*0Sstevel@tonic-gate 	wsp->walk_addr =
212*0Sstevel@tonic-gate 	    (uintptr_t)(((subclass_lst_t *)wsp->walk_data)->sl_next);
213*0Sstevel@tonic-gate 
214*0Sstevel@tonic-gate 	return (status);
215*0Sstevel@tonic-gate }
216*0Sstevel@tonic-gate 
217*0Sstevel@tonic-gate void
sysevent_subclass_list_walk_fini(mdb_walk_state_t * wsp)218*0Sstevel@tonic-gate sysevent_subclass_list_walk_fini(mdb_walk_state_t *wsp)
219*0Sstevel@tonic-gate {
220*0Sstevel@tonic-gate 	mdb_free(wsp->walk_data, sizeof (subclass_lst_t));
221*0Sstevel@tonic-gate }
222*0Sstevel@tonic-gate 
223*0Sstevel@tonic-gate typedef struct class_walk_data {
224*0Sstevel@tonic-gate 	int	hash_index;
225*0Sstevel@tonic-gate 	class_lst_t *hash_tbl[CLASS_HASH_SZ + 1];
226*0Sstevel@tonic-gate } class_walk_data_t;
227*0Sstevel@tonic-gate 
228*0Sstevel@tonic-gate int
sysevent_class_list_walk_init(mdb_walk_state_t * wsp)229*0Sstevel@tonic-gate sysevent_class_list_walk_init(mdb_walk_state_t *wsp)
230*0Sstevel@tonic-gate {
231*0Sstevel@tonic-gate 	class_walk_data_t *cl_walker;
232*0Sstevel@tonic-gate 
233*0Sstevel@tonic-gate 	if (wsp->walk_addr == NULL) {
234*0Sstevel@tonic-gate 		mdb_warn("sysevent_class_list does not support global walks");
235*0Sstevel@tonic-gate 		return (WALK_ERR);
236*0Sstevel@tonic-gate 	}
237*0Sstevel@tonic-gate 
238*0Sstevel@tonic-gate 	cl_walker = mdb_zalloc(sizeof (class_walk_data_t), UM_SLEEP);
239*0Sstevel@tonic-gate 	if (mdb_vread(cl_walker->hash_tbl,
240*0Sstevel@tonic-gate 	    sizeof (cl_walker->hash_tbl), wsp->walk_addr) == -1) {
241*0Sstevel@tonic-gate 		mdb_warn("failed to read class hash table at %p",
242*0Sstevel@tonic-gate 		    wsp->walk_addr);
243*0Sstevel@tonic-gate 		return (WALK_ERR);
244*0Sstevel@tonic-gate 	}
245*0Sstevel@tonic-gate 
246*0Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)cl_walker->hash_tbl[0];
247*0Sstevel@tonic-gate 	wsp->walk_data = cl_walker;
248*0Sstevel@tonic-gate 
249*0Sstevel@tonic-gate 	return (WALK_NEXT);
250*0Sstevel@tonic-gate }
251*0Sstevel@tonic-gate 
252*0Sstevel@tonic-gate int
sysevent_class_list_walk_step(mdb_walk_state_t * wsp)253*0Sstevel@tonic-gate sysevent_class_list_walk_step(mdb_walk_state_t *wsp)
254*0Sstevel@tonic-gate {
255*0Sstevel@tonic-gate 	int status = WALK_NEXT;
256*0Sstevel@tonic-gate 	class_walk_data_t *cl_walker;
257*0Sstevel@tonic-gate 	class_lst_t clist;
258*0Sstevel@tonic-gate 
259*0Sstevel@tonic-gate 	cl_walker = (class_walk_data_t *)wsp->walk_data;
260*0Sstevel@tonic-gate 
261*0Sstevel@tonic-gate 	/* Skip over empty class table entries */
262*0Sstevel@tonic-gate 	if (wsp->walk_addr != NULL) {
263*0Sstevel@tonic-gate 		if (mdb_vread(&clist, sizeof (class_lst_t),
264*0Sstevel@tonic-gate 		    wsp->walk_addr) == -1) {
265*0Sstevel@tonic-gate 			mdb_warn("failed to read class list at %p",
266*0Sstevel@tonic-gate 			    wsp->walk_addr);
267*0Sstevel@tonic-gate 			return (WALK_ERR);
268*0Sstevel@tonic-gate 		}
269*0Sstevel@tonic-gate 
270*0Sstevel@tonic-gate 		status = wsp->walk_callback(wsp->walk_addr, NULL,
271*0Sstevel@tonic-gate 		    wsp->walk_cbdata);
272*0Sstevel@tonic-gate 		wsp->walk_addr = (uintptr_t)clist.cl_next;
273*0Sstevel@tonic-gate 	} else {
274*0Sstevel@tonic-gate 		if (cl_walker->hash_index > CLASS_HASH_SZ) {
275*0Sstevel@tonic-gate 			return (WALK_DONE);
276*0Sstevel@tonic-gate 		} else {
277*0Sstevel@tonic-gate 			wsp->walk_addr = (uintptr_t)
278*0Sstevel@tonic-gate 			    cl_walker->hash_tbl[cl_walker->hash_index];
279*0Sstevel@tonic-gate 			cl_walker->hash_index++;
280*0Sstevel@tonic-gate 		}
281*0Sstevel@tonic-gate 	}
282*0Sstevel@tonic-gate 
283*0Sstevel@tonic-gate 
284*0Sstevel@tonic-gate 	return (status);
285*0Sstevel@tonic-gate }
286*0Sstevel@tonic-gate 
287*0Sstevel@tonic-gate void
sysevent_class_list_walk_fini(mdb_walk_state_t * wsp)288*0Sstevel@tonic-gate sysevent_class_list_walk_fini(mdb_walk_state_t *wsp)
289*0Sstevel@tonic-gate {
290*0Sstevel@tonic-gate 	class_walk_data_t *cl_walker = wsp->walk_data;
291*0Sstevel@tonic-gate 
292*0Sstevel@tonic-gate 	mdb_free(cl_walker, sizeof (cl_walker));
293*0Sstevel@tonic-gate }
294*0Sstevel@tonic-gate 
295*0Sstevel@tonic-gate #ifdef _KERNEL
296*0Sstevel@tonic-gate int
sysevent(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)297*0Sstevel@tonic-gate sysevent(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
298*0Sstevel@tonic-gate {
299*0Sstevel@tonic-gate 	uint_t sys_flags = FALSE;
300*0Sstevel@tonic-gate 
301*0Sstevel@tonic-gate 	if (mdb_getopts(argc, argv,
302*0Sstevel@tonic-gate 	    's', MDB_OPT_SETBITS, SYSEVENT_SENTQ, &sys_flags,
303*0Sstevel@tonic-gate 	    'v', MDB_OPT_SETBITS, SYSEVENT_VERBOSE, &sys_flags, NULL) != argc)
304*0Sstevel@tonic-gate 		return (DCMD_USAGE);
305*0Sstevel@tonic-gate 
306*0Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) == 0) {
307*0Sstevel@tonic-gate 		if (sys_flags & SYSEVENT_SENTQ) {
308*0Sstevel@tonic-gate 			if (mdb_walk_dcmd("sysevent_sent", "sysevent", argc,
309*0Sstevel@tonic-gate 			    argv) == -1) {
310*0Sstevel@tonic-gate 				mdb_warn("can not walk sent queue");
311*0Sstevel@tonic-gate 				return (DCMD_ERR);
312*0Sstevel@tonic-gate 			}
313*0Sstevel@tonic-gate 		} else {
314*0Sstevel@tonic-gate 			if (mdb_walk_dcmd("sysevent_pend", "sysevent", argc,
315*0Sstevel@tonic-gate 			    argv) == -1) {
316*0Sstevel@tonic-gate 				mdb_warn("can not walk pending queue");
317*0Sstevel@tonic-gate 				return (DCMD_ERR);
318*0Sstevel@tonic-gate 			}
319*0Sstevel@tonic-gate 		}
320*0Sstevel@tonic-gate 		return (DCMD_OK);
321*0Sstevel@tonic-gate 	}
322*0Sstevel@tonic-gate 
323*0Sstevel@tonic-gate 	return (sysevent_buf(addr, flags, sys_flags));
324*0Sstevel@tonic-gate }
325*0Sstevel@tonic-gate 
326*0Sstevel@tonic-gate int
sysevent_channel(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)327*0Sstevel@tonic-gate sysevent_channel(uintptr_t addr, uint_t flags, int argc,
328*0Sstevel@tonic-gate     const mdb_arg_t *argv)
329*0Sstevel@tonic-gate {
330*0Sstevel@tonic-gate 	ssize_t channel_name_sz;
331*0Sstevel@tonic-gate 	char channel_name[CHAN_FIELD_MAX];
332*0Sstevel@tonic-gate 	sysevent_channel_descriptor_t chan_tbl;
333*0Sstevel@tonic-gate 
334*0Sstevel@tonic-gate 	if (argc != 0)
335*0Sstevel@tonic-gate 		return (DCMD_USAGE);
336*0Sstevel@tonic-gate 
337*0Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) == 0) {
338*0Sstevel@tonic-gate 		if (mdb_walk_dcmd("sysevent_channel", "sysevent_channel",
339*0Sstevel@tonic-gate 		    argc, argv) == -1) {
340*0Sstevel@tonic-gate 			mdb_warn("can't walk sysevent channel");
341*0Sstevel@tonic-gate 			return (DCMD_ERR);
342*0Sstevel@tonic-gate 		}
343*0Sstevel@tonic-gate 		return (DCMD_OK);
344*0Sstevel@tonic-gate 	}
345*0Sstevel@tonic-gate 
346*0Sstevel@tonic-gate 
347*0Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags))
348*0Sstevel@tonic-gate 		mdb_printf("%<u>%-?s %-16s %-8s %-?s%</u>\n",
349*0Sstevel@tonic-gate 		    "ADDR", "NAME", "REF CNT", "CLASS LST ADDR");
350*0Sstevel@tonic-gate 
351*0Sstevel@tonic-gate 	if (mdb_vread(&chan_tbl, sizeof (chan_tbl),
352*0Sstevel@tonic-gate 	    (uintptr_t)addr) == -1) {
353*0Sstevel@tonic-gate 		mdb_warn("failed to read channel table at %p", addr);
354*0Sstevel@tonic-gate 		return (DCMD_ERR);
355*0Sstevel@tonic-gate 	}
356*0Sstevel@tonic-gate 	if ((channel_name_sz = mdb_readstr(channel_name, CHAN_FIELD_MAX,
357*0Sstevel@tonic-gate 	    (uintptr_t)chan_tbl.scd_channel_name)) == -1) {
358*0Sstevel@tonic-gate 		mdb_warn("failed to read channel name at %p",
359*0Sstevel@tonic-gate 		    chan_tbl.scd_channel_name);
360*0Sstevel@tonic-gate 		return (DCMD_ERR);
361*0Sstevel@tonic-gate 	}
362*0Sstevel@tonic-gate 	if (channel_name_sz >= CHAN_FIELD_MAX - 1)
363*0Sstevel@tonic-gate 		(void) strcpy(&channel_name[CHAN_FIELD_MAX - 4], "...");
364*0Sstevel@tonic-gate 
365*0Sstevel@tonic-gate 	mdb_printf("%-?p %-16s %-8lu %-?p\n",
366*0Sstevel@tonic-gate 	    addr, channel_name, chan_tbl.scd_ref_cnt,
367*0Sstevel@tonic-gate 	    addr + offsetof(sysevent_channel_descriptor_t,
368*0Sstevel@tonic-gate 	    scd_class_list_tbl));
369*0Sstevel@tonic-gate 
370*0Sstevel@tonic-gate 	return (DCMD_OK);
371*0Sstevel@tonic-gate }
372*0Sstevel@tonic-gate 
373*0Sstevel@tonic-gate typedef struct channel_walk_data {
374*0Sstevel@tonic-gate 	int hash_index;
375*0Sstevel@tonic-gate 	sysevent_channel_descriptor_t *hash_tbl[CHAN_HASH_SZ];
376*0Sstevel@tonic-gate } channel_walk_data_t;
377*0Sstevel@tonic-gate 
378*0Sstevel@tonic-gate int
sysevent_channel_walk_init(mdb_walk_state_t * wsp)379*0Sstevel@tonic-gate sysevent_channel_walk_init(mdb_walk_state_t *wsp)
380*0Sstevel@tonic-gate {
381*0Sstevel@tonic-gate 	channel_walk_data_t *ch_walker;
382*0Sstevel@tonic-gate 
383*0Sstevel@tonic-gate 	if (wsp->walk_addr != NULL) {
384*0Sstevel@tonic-gate 		mdb_warn("sysevent_channel supports only global walks");
385*0Sstevel@tonic-gate 		return (WALK_ERR);
386*0Sstevel@tonic-gate 	}
387*0Sstevel@tonic-gate 
388*0Sstevel@tonic-gate 	ch_walker = mdb_zalloc(sizeof (channel_walk_data_t), UM_SLEEP);
389*0Sstevel@tonic-gate 	if (mdb_readvar(ch_walker->hash_tbl, "registered_channels")
390*0Sstevel@tonic-gate 	    == -1) {
391*0Sstevel@tonic-gate 		mdb_warn("failed to read 'registered_channels'");
392*0Sstevel@tonic-gate 		return (WALK_ERR);
393*0Sstevel@tonic-gate 	}
394*0Sstevel@tonic-gate 
395*0Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)ch_walker->hash_tbl[0];
396*0Sstevel@tonic-gate 	wsp->walk_data = ch_walker;
397*0Sstevel@tonic-gate 
398*0Sstevel@tonic-gate 	return (WALK_NEXT);
399*0Sstevel@tonic-gate }
400*0Sstevel@tonic-gate 
401*0Sstevel@tonic-gate int
sysevent_channel_walk_step(mdb_walk_state_t * wsp)402*0Sstevel@tonic-gate sysevent_channel_walk_step(mdb_walk_state_t *wsp)
403*0Sstevel@tonic-gate {
404*0Sstevel@tonic-gate 	int status = WALK_NEXT;
405*0Sstevel@tonic-gate 	channel_walk_data_t *ch_walker;
406*0Sstevel@tonic-gate 	sysevent_channel_descriptor_t scd;
407*0Sstevel@tonic-gate 
408*0Sstevel@tonic-gate 	ch_walker = (channel_walk_data_t *)wsp->walk_data;
409*0Sstevel@tonic-gate 
410*0Sstevel@tonic-gate 	/* Skip over empty hash table entries */
411*0Sstevel@tonic-gate 	if (wsp->walk_addr != NULL) {
412*0Sstevel@tonic-gate 		if (mdb_vread(&scd, sizeof (sysevent_channel_descriptor_t),
413*0Sstevel@tonic-gate 		    wsp->walk_addr) == -1) {
414*0Sstevel@tonic-gate 			mdb_warn("failed to read channel at %p",
415*0Sstevel@tonic-gate 			    wsp->walk_addr);
416*0Sstevel@tonic-gate 			return (WALK_ERR);
417*0Sstevel@tonic-gate 		}
418*0Sstevel@tonic-gate 
419*0Sstevel@tonic-gate 		status = wsp->walk_callback(wsp->walk_addr, NULL,
420*0Sstevel@tonic-gate 		    wsp->walk_cbdata);
421*0Sstevel@tonic-gate 		wsp->walk_addr = (uintptr_t)scd.scd_next;
422*0Sstevel@tonic-gate 	} else {
423*0Sstevel@tonic-gate 		if (ch_walker->hash_index == CHAN_HASH_SZ) {
424*0Sstevel@tonic-gate 			return (WALK_DONE);
425*0Sstevel@tonic-gate 		} else {
426*0Sstevel@tonic-gate 
427*0Sstevel@tonic-gate 			wsp->walk_addr = (uintptr_t)
428*0Sstevel@tonic-gate 			    ch_walker->hash_tbl[ch_walker->hash_index];
429*0Sstevel@tonic-gate 			ch_walker->hash_index++;
430*0Sstevel@tonic-gate 		}
431*0Sstevel@tonic-gate 	}
432*0Sstevel@tonic-gate 
433*0Sstevel@tonic-gate 	return (status);
434*0Sstevel@tonic-gate }
435*0Sstevel@tonic-gate 
436*0Sstevel@tonic-gate void
sysevent_channel_walk_fini(mdb_walk_state_t * wsp)437*0Sstevel@tonic-gate sysevent_channel_walk_fini(mdb_walk_state_t *wsp)
438*0Sstevel@tonic-gate {
439*0Sstevel@tonic-gate 	channel_walk_data_t *ch_walker = wsp->walk_data;
440*0Sstevel@tonic-gate 
441*0Sstevel@tonic-gate 	mdb_free(ch_walker, sizeof (ch_walker));
442*0Sstevel@tonic-gate }
443*0Sstevel@tonic-gate 
444*0Sstevel@tonic-gate int
sysevent_pend_walk_init(mdb_walk_state_t * wsp)445*0Sstevel@tonic-gate sysevent_pend_walk_init(mdb_walk_state_t *wsp)
446*0Sstevel@tonic-gate {
447*0Sstevel@tonic-gate 	if (wsp->walk_addr == NULL) {
448*0Sstevel@tonic-gate 		if (mdb_readvar(&wsp->walk_addr, "log_eventq_head") == -1) {
449*0Sstevel@tonic-gate 			mdb_warn("failed to read 'log_eventq_head'");
450*0Sstevel@tonic-gate 			return (WALK_ERR);
451*0Sstevel@tonic-gate 		}
452*0Sstevel@tonic-gate 	}
453*0Sstevel@tonic-gate 
454*0Sstevel@tonic-gate 	wsp->walk_data = mdb_alloc(sizeof (log_eventq_t), UM_SLEEP);
455*0Sstevel@tonic-gate 	return (WALK_NEXT);
456*0Sstevel@tonic-gate }
457*0Sstevel@tonic-gate 
458*0Sstevel@tonic-gate int
sysevent_walk_step(mdb_walk_state_t * wsp)459*0Sstevel@tonic-gate sysevent_walk_step(mdb_walk_state_t *wsp)
460*0Sstevel@tonic-gate {
461*0Sstevel@tonic-gate 	int status;
462*0Sstevel@tonic-gate 	uintptr_t ev_arg_addr;
463*0Sstevel@tonic-gate 
464*0Sstevel@tonic-gate 	if (wsp->walk_addr == NULL)
465*0Sstevel@tonic-gate 		return (WALK_DONE);
466*0Sstevel@tonic-gate 
467*0Sstevel@tonic-gate 	if (mdb_vread(wsp->walk_data, sizeof (log_eventq_t),
468*0Sstevel@tonic-gate 	    wsp->walk_addr) == -1) {
469*0Sstevel@tonic-gate 		mdb_warn("failed to read event queue at %p", wsp->walk_addr);
470*0Sstevel@tonic-gate 		return (WALK_ERR);
471*0Sstevel@tonic-gate 	}
472*0Sstevel@tonic-gate 	ev_arg_addr = wsp->walk_addr + offsetof(log_eventq_t, arg.buf);
473*0Sstevel@tonic-gate 
474*0Sstevel@tonic-gate 	status = wsp->walk_callback(ev_arg_addr, wsp->walk_data,
475*0Sstevel@tonic-gate 	    wsp->walk_cbdata);
476*0Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)(((log_eventq_t *)wsp->walk_data)->next);
477*0Sstevel@tonic-gate 	return (status);
478*0Sstevel@tonic-gate }
479*0Sstevel@tonic-gate 
480*0Sstevel@tonic-gate int
sysevent_sent_walk_init(mdb_walk_state_t * wsp)481*0Sstevel@tonic-gate sysevent_sent_walk_init(mdb_walk_state_t *wsp)
482*0Sstevel@tonic-gate {
483*0Sstevel@tonic-gate 	if (wsp->walk_addr == NULL) {
484*0Sstevel@tonic-gate 		if (mdb_readvar(&wsp->walk_addr, "log_eventq_sent") == -1) {
485*0Sstevel@tonic-gate 			mdb_warn("failed to read 'log_eventq_sent'");
486*0Sstevel@tonic-gate 			return (WALK_ERR);
487*0Sstevel@tonic-gate 		}
488*0Sstevel@tonic-gate 	}
489*0Sstevel@tonic-gate 	wsp->walk_data = mdb_alloc(sizeof (log_eventq_t), UM_SLEEP);
490*0Sstevel@tonic-gate 	return (WALK_NEXT);
491*0Sstevel@tonic-gate }
492*0Sstevel@tonic-gate 
493*0Sstevel@tonic-gate void
sysevent_walk_fini(mdb_walk_state_t * wsp)494*0Sstevel@tonic-gate sysevent_walk_fini(mdb_walk_state_t *wsp)
495*0Sstevel@tonic-gate {
496*0Sstevel@tonic-gate 	mdb_free(wsp->walk_data, sizeof (log_eventq_t));
497*0Sstevel@tonic-gate }
498*0Sstevel@tonic-gate 
499*0Sstevel@tonic-gate #endif
500