dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / mdb / common / modules / genunix / sysevent.c
blob878ec9a3a51e99ad28f08717e8e36ed23558dbc7
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 #include "sysevent.h"
30 int
31 sysevent_buf(uintptr_t addr, uint_t flags, uint_t opt_flags)
33 sysevent_hdr_t evh;
34 sysevent_impl_t *ev;
35 int size;
37 if (DCMD_HDRSPEC(flags)) {
38 if ((opt_flags & SYSEVENT_VERBOSE) == 0) {
39 mdb_printf("%<u>%-?s %-16s %-9s %-10s "
40 "%-?s%</u>\n", "ADDRESS", "SEQUENCE ID",
41 "CLASS", "SUBCLASS", "NVPAIR BUF ADDR");
46 * Read in the sysevent buffer header first. After extracting
47 * the size of the buffer, re-read the buffer in its entirety.
49 if (mdb_vread(&evh, sizeof (sysevent_hdr_t), addr) == -1) {
50 mdb_warn("failed to read event header at %p", addr);
51 return (DCMD_ERR);
54 size = SE_SIZE((sysevent_impl_t *)&evh);
55 ev = mdb_alloc(size, UM_SLEEP | UM_GC);
57 if (mdb_vread(ev, size, addr) == -1) {
58 mdb_warn("can not read sysevent at %p", addr);
59 return (DCMD_ERR);
62 if ((opt_flags & SYSEVENT_VERBOSE) == 0) {
63 char ev_class[CLASS_FIELD_MAX];
64 char ev_subclass[SUBCLASS_FIELD_MAX];
66 if (mdb_snprintf(ev_class, CLASS_FIELD_MAX, "%s",
67 SE_CLASS_NAME(ev)) >= CLASS_FIELD_MAX - 1)
68 (void) strcpy(&ev_class[CLASS_FIELD_MAX - 4], "...");
70 if (mdb_snprintf(ev_subclass, SUBCLASS_FIELD_MAX, "%s",
71 SE_SUBCLASS_NAME(ev)) >= SUBCLASS_FIELD_MAX - 1)
72 (void) strcpy(&ev_subclass[SUBCLASS_FIELD_MAX - 4],
73 "...");
75 mdb_printf("%-?p %-16llu %-9s %-10s %-?p%\n",
76 addr, SE_SEQ(ev), ev_class, ev_subclass,
77 addr + SE_ATTR_OFF(ev));
78 } else {
79 mdb_printf("%<b>Sequence ID\t : %llu%</b>\n", SE_SEQ(ev));
80 mdb_printf("%16s : %s\n", "publisher", SE_PUB_NAME(ev));
81 mdb_printf("%16s : %p\n", "event address", (caddr_t)addr);
82 mdb_printf("%16s : %s\n", "class", SE_CLASS_NAME(ev));
83 mdb_printf("%16s : %s\n", "subclass", SE_SUBCLASS_NAME(ev));
84 mdb_printf("%16s : %llu\n", "time stamp", SE_TIME(ev));
85 mdb_printf("%16s : %p\n", "nvpair buf addr",
86 addr + SE_ATTR_OFF(ev));
89 return (DCMD_OK);
92 int
93 sysevent_subclass_list(uintptr_t addr, uint_t flags, int argc,
94 const mdb_arg_t *argv)
96 int subclass_name_sz;
97 char subclass_name[CLASS_LIST_FIELD_MAX];
98 subclass_lst_t sclist;
100 if ((flags & DCMD_ADDRSPEC) == 0)
101 return (DCMD_USAGE);
103 if ((flags & DCMD_LOOP) == 0) {
104 if (mdb_pwalk_dcmd("sysevent_subclass_list",
105 "sysevent_subclass_list", argc, argv, addr) == -1) {
106 mdb_warn("can't walk sysevent subclass list");
107 return (DCMD_ERR);
109 return (DCMD_OK);
112 if (DCMD_HDRSPEC(flags)) {
113 mdb_printf("%<u>%-?s %-24s %-?s%</u>\n",
114 "ADDR", "NAME", "SUBSCRIBER DATA ADDR");
116 if (mdb_vread(&sclist, sizeof (sclist), (uintptr_t)addr) == -1) {
117 mdb_warn("failed to read subclass list at %p", addr);
118 return (DCMD_ERR);
120 if ((subclass_name_sz = mdb_readstr(subclass_name, CLASS_LIST_FIELD_MAX,
121 (uintptr_t)sclist.sl_name)) == -1) {
122 mdb_warn("failed to read class name at %p",
123 sclist.sl_name);
124 return (DCMD_ERR);
126 if (subclass_name_sz >= CLASS_LIST_FIELD_MAX - 1)
127 (void) strcpy(&subclass_name[CLASS_LIST_FIELD_MAX - 4], "...");
129 mdb_printf("%-?p %-24s %-?p\n", addr, subclass_name,
130 addr + offsetof(subclass_lst_t, sl_num));
132 return (DCMD_OK);
137 sysevent_class_list(uintptr_t addr, uint_t flags, int argc,
138 const mdb_arg_t *argv)
140 int class_name_sz;
141 char class_name[CLASS_LIST_FIELD_MAX];
142 class_lst_t clist;
144 if ((flags & DCMD_ADDRSPEC) == 0)
145 return (DCMD_USAGE);
147 if ((flags & DCMD_LOOP) == 0) {
148 if (mdb_pwalk_dcmd("sysevent_class_list", "sysevent_class_list",
149 argc, argv, addr) == -1) {
150 mdb_warn("can't walk sysevent class list");
151 return (DCMD_ERR);
153 return (DCMD_OK);
156 if (DCMD_HDRSPEC(flags))
157 mdb_printf("%<u>%-?s %-24s %-?s%</u>\n",
158 "ADDR", "NAME", "SUBCLASS LIST ADDR");
160 if (mdb_vread(&clist, sizeof (clist),
161 (uintptr_t)addr) == -1) {
162 mdb_warn("failed to read class clist at %p", addr);
163 return (DCMD_ERR);
165 if ((class_name_sz = mdb_readstr(class_name, CLASS_LIST_FIELD_MAX,
166 (uintptr_t)clist.cl_name)) == -1) {
167 mdb_warn("failed to read class name at %p",
168 clist.cl_name);
169 return (DCMD_ERR);
171 if (class_name_sz >= CLASS_LIST_FIELD_MAX - 1)
172 (void) strcpy(&class_name[CLASS_LIST_FIELD_MAX - 4], "...");
174 mdb_printf("%-?p %-24s %-?p\n", addr, class_name,
175 clist.cl_subclass_list);
177 return (DCMD_OK);
181 sysevent_subclass_list_walk_init(mdb_walk_state_t *wsp)
183 if (wsp->walk_addr == (uintptr_t)NULL) {
184 mdb_warn("sysevent_subclass_list does not support global "
185 "walks");
186 return (WALK_ERR);
189 wsp->walk_data = mdb_alloc(sizeof (subclass_lst_t), UM_SLEEP);
190 return (WALK_NEXT);
194 sysevent_subclass_list_walk_step(mdb_walk_state_t *wsp)
196 int status;
198 if (wsp->walk_addr == (uintptr_t)NULL)
199 return (WALK_DONE);
201 if (mdb_vread(wsp->walk_data, sizeof (subclass_lst_t),
202 wsp->walk_addr) == -1) {
203 mdb_warn("failed to read class list at %p", wsp->walk_addr);
204 return (WALK_ERR);
207 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
208 wsp->walk_cbdata);
210 wsp->walk_addr =
211 (uintptr_t)(((subclass_lst_t *)wsp->walk_data)->sl_next);
213 return (status);
216 void
217 sysevent_subclass_list_walk_fini(mdb_walk_state_t *wsp)
219 mdb_free(wsp->walk_data, sizeof (subclass_lst_t));
222 typedef struct class_walk_data {
223 int hash_index;
224 class_lst_t *hash_tbl[CLASS_HASH_SZ + 1];
225 } class_walk_data_t;
228 sysevent_class_list_walk_init(mdb_walk_state_t *wsp)
230 class_walk_data_t *cl_walker;
232 if (wsp->walk_addr == (uintptr_t)NULL) {
233 mdb_warn("sysevent_class_list does not support global walks");
234 return (WALK_ERR);
237 cl_walker = mdb_zalloc(sizeof (class_walk_data_t), UM_SLEEP);
238 if (mdb_vread(cl_walker->hash_tbl,
239 sizeof (cl_walker->hash_tbl), wsp->walk_addr) == -1) {
240 mdb_warn("failed to read class hash table at %p",
241 wsp->walk_addr);
242 return (WALK_ERR);
245 wsp->walk_addr = (uintptr_t)cl_walker->hash_tbl[0];
246 wsp->walk_data = cl_walker;
248 return (WALK_NEXT);
252 sysevent_class_list_walk_step(mdb_walk_state_t *wsp)
254 int status = WALK_NEXT;
255 class_walk_data_t *cl_walker;
256 class_lst_t clist;
258 cl_walker = (class_walk_data_t *)wsp->walk_data;
260 /* Skip over empty class table entries */
261 if (wsp->walk_addr != (uintptr_t)NULL) {
262 if (mdb_vread(&clist, sizeof (class_lst_t),
263 wsp->walk_addr) == -1) {
264 mdb_warn("failed to read class list at %p",
265 wsp->walk_addr);
266 return (WALK_ERR);
269 status = wsp->walk_callback(wsp->walk_addr, NULL,
270 wsp->walk_cbdata);
271 wsp->walk_addr = (uintptr_t)clist.cl_next;
272 } else {
273 if (cl_walker->hash_index > CLASS_HASH_SZ) {
274 return (WALK_DONE);
275 } else {
276 wsp->walk_addr = (uintptr_t)
277 cl_walker->hash_tbl[cl_walker->hash_index];
278 cl_walker->hash_index++;
283 return (status);
286 void
287 sysevent_class_list_walk_fini(mdb_walk_state_t *wsp)
289 class_walk_data_t *cl_walker = wsp->walk_data;
291 mdb_free(cl_walker, sizeof (cl_walker));
294 #ifdef _KERNEL
296 sysevent(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
298 uint_t sys_flags = FALSE;
300 if (mdb_getopts(argc, argv,
301 's', MDB_OPT_SETBITS, SYSEVENT_SENTQ, &sys_flags,
302 'v', MDB_OPT_SETBITS, SYSEVENT_VERBOSE, &sys_flags, NULL) != argc)
303 return (DCMD_USAGE);
305 if ((flags & DCMD_ADDRSPEC) == 0) {
306 if (sys_flags & SYSEVENT_SENTQ) {
307 if (mdb_walk_dcmd("sysevent_sent", "sysevent", argc,
308 argv) == -1) {
309 mdb_warn("can not walk sent queue");
310 return (DCMD_ERR);
312 } else {
313 if (mdb_walk_dcmd("sysevent_pend", "sysevent", argc,
314 argv) == -1) {
315 mdb_warn("can not walk pending queue");
316 return (DCMD_ERR);
319 return (DCMD_OK);
322 return (sysevent_buf(addr, flags, sys_flags));
326 sysevent_channel(uintptr_t addr, uint_t flags, int argc,
327 const mdb_arg_t *argv)
329 ssize_t channel_name_sz;
330 char channel_name[CHAN_FIELD_MAX];
331 sysevent_channel_descriptor_t chan_tbl;
333 if (argc != 0)
334 return (DCMD_USAGE);
336 if ((flags & DCMD_ADDRSPEC) == 0) {
337 if (mdb_walk_dcmd("sysevent_channel", "sysevent_channel",
338 argc, argv) == -1) {
339 mdb_warn("can't walk sysevent channel");
340 return (DCMD_ERR);
342 return (DCMD_OK);
346 if (DCMD_HDRSPEC(flags))
347 mdb_printf("%<u>%-?s %-16s %-8s %-?s%</u>\n",
348 "ADDR", "NAME", "REF CNT", "CLASS LST ADDR");
350 if (mdb_vread(&chan_tbl, sizeof (chan_tbl),
351 (uintptr_t)addr) == -1) {
352 mdb_warn("failed to read channel table at %p", addr);
353 return (DCMD_ERR);
355 if ((channel_name_sz = mdb_readstr(channel_name, CHAN_FIELD_MAX,
356 (uintptr_t)chan_tbl.scd_channel_name)) == -1) {
357 mdb_warn("failed to read channel name at %p",
358 chan_tbl.scd_channel_name);
359 return (DCMD_ERR);
361 if (channel_name_sz >= CHAN_FIELD_MAX - 1)
362 (void) strcpy(&channel_name[CHAN_FIELD_MAX - 4], "...");
364 mdb_printf("%-?p %-16s %-8lu %-?p\n",
365 addr, channel_name, chan_tbl.scd_ref_cnt,
366 addr + offsetof(sysevent_channel_descriptor_t,
367 scd_class_list_tbl));
369 return (DCMD_OK);
372 typedef struct channel_walk_data {
373 int hash_index;
374 sysevent_channel_descriptor_t *hash_tbl[CHAN_HASH_SZ];
375 } channel_walk_data_t;
378 sysevent_channel_walk_init(mdb_walk_state_t *wsp)
380 channel_walk_data_t *ch_walker;
382 if (wsp->walk_addr != (uintptr_t)NULL) {
383 mdb_warn("sysevent_channel supports only global walks");
384 return (WALK_ERR);
387 ch_walker = mdb_zalloc(sizeof (channel_walk_data_t), UM_SLEEP);
388 if (mdb_readvar(ch_walker->hash_tbl, "registered_channels")
389 == -1) {
390 mdb_warn("failed to read 'registered_channels'");
391 return (WALK_ERR);
394 wsp->walk_addr = (uintptr_t)ch_walker->hash_tbl[0];
395 wsp->walk_data = ch_walker;
397 return (WALK_NEXT);
401 sysevent_channel_walk_step(mdb_walk_state_t *wsp)
403 int status = WALK_NEXT;
404 channel_walk_data_t *ch_walker;
405 sysevent_channel_descriptor_t scd;
407 ch_walker = (channel_walk_data_t *)wsp->walk_data;
409 /* Skip over empty hash table entries */
410 if (wsp->walk_addr != (uintptr_t)NULL) {
411 if (mdb_vread(&scd, sizeof (sysevent_channel_descriptor_t),
412 wsp->walk_addr) == -1) {
413 mdb_warn("failed to read channel at %p",
414 wsp->walk_addr);
415 return (WALK_ERR);
418 status = wsp->walk_callback(wsp->walk_addr, NULL,
419 wsp->walk_cbdata);
420 wsp->walk_addr = (uintptr_t)scd.scd_next;
421 } else {
422 if (ch_walker->hash_index == CHAN_HASH_SZ) {
423 return (WALK_DONE);
424 } else {
426 wsp->walk_addr = (uintptr_t)
427 ch_walker->hash_tbl[ch_walker->hash_index];
428 ch_walker->hash_index++;
432 return (status);
435 void
436 sysevent_channel_walk_fini(mdb_walk_state_t *wsp)
438 channel_walk_data_t *ch_walker = wsp->walk_data;
440 mdb_free(ch_walker, sizeof (ch_walker));
444 sysevent_pend_walk_init(mdb_walk_state_t *wsp)
446 if (wsp->walk_addr == (uintptr_t)NULL) {
447 if (mdb_readvar(&wsp->walk_addr, "log_eventq_head") == -1) {
448 mdb_warn("failed to read 'log_eventq_head'");
449 return (WALK_ERR);
453 wsp->walk_data = mdb_alloc(sizeof (log_eventq_t), UM_SLEEP);
454 return (WALK_NEXT);
458 sysevent_walk_step(mdb_walk_state_t *wsp)
460 int status;
461 uintptr_t ev_arg_addr;
463 if (wsp->walk_addr == (uintptr_t)NULL)
464 return (WALK_DONE);
466 if (mdb_vread(wsp->walk_data, sizeof (log_eventq_t),
467 wsp->walk_addr) == -1) {
468 mdb_warn("failed to read event queue at %p", wsp->walk_addr);
469 return (WALK_ERR);
471 ev_arg_addr = wsp->walk_addr + offsetof(log_eventq_t, arg.buf);
473 status = wsp->walk_callback(ev_arg_addr, wsp->walk_data,
474 wsp->walk_cbdata);
475 wsp->walk_addr = (uintptr_t)(((log_eventq_t *)wsp->walk_data)->next);
476 return (status);
480 sysevent_sent_walk_init(mdb_walk_state_t *wsp)
482 if (wsp->walk_addr == (uintptr_t)NULL) {
483 if (mdb_readvar(&wsp->walk_addr, "log_eventq_sent") == -1) {
484 mdb_warn("failed to read 'log_eventq_sent'");
485 return (WALK_ERR);
488 wsp->walk_data = mdb_alloc(sizeof (log_eventq_t), UM_SLEEP);
489 return (WALK_NEXT);
492 void
493 sysevent_walk_fini(mdb_walk_state_t *wsp)
495 mdb_free(wsp->walk_data, sizeof (log_eventq_t));
498 #endif