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