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