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 2004 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 #ifndef _SYS_SYSEVENT_IMPL_H 28*0Sstevel@tonic-gate #define _SYS_SYSEVENT_IMPL_H 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate #include <sys/nvpair.h> 33*0Sstevel@tonic-gate #include <sys/id_space.h> 34*0Sstevel@tonic-gate #include <sys/door.h> 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate #ifdef __cplusplus 37*0Sstevel@tonic-gate extern "C" { 38*0Sstevel@tonic-gate #endif 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate typedef uint64_t se_data_t; 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gate /* 43*0Sstevel@tonic-gate * The following data structure assist in loading and extracting event 44*0Sstevel@tonic-gate * header and attribute data into contiguous memory. Access to all typed 45*0Sstevel@tonic-gate * data done so on 64-bit boundaries. *Do Not* alter any of the structures 46*0Sstevel@tonic-gate * defined below without thorough thought and testing. 47*0Sstevel@tonic-gate */ 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate /* Attribute name */ 50*0Sstevel@tonic-gate typedef struct se_name { 51*0Sstevel@tonic-gate int32_t name_sz; 52*0Sstevel@tonic-gate int32_t name_pad; 53*0Sstevel@tonic-gate se_data_t name; /* 64-bit aligned offset */ 54*0Sstevel@tonic-gate } se_name_t; 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate /* Attribute value */ 57*0Sstevel@tonic-gate typedef struct se_value { 58*0Sstevel@tonic-gate int32_t value_type; /* data type */ 59*0Sstevel@tonic-gate int32_t value_sz; 60*0Sstevel@tonic-gate se_data_t value; /* data value - 64-bit aligned offset */ 61*0Sstevel@tonic-gate } se_value_t; 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate /* sysevent internal attribute name-value pair stored in contiguous memory */ 64*0Sstevel@tonic-gate typedef struct sysevent_attr_impl { 65*0Sstevel@tonic-gate int32_t se_attr_sz; /* Size of attribute data */ 66*0Sstevel@tonic-gate int32_t se_attr_pad; /* pad */ 67*0Sstevel@tonic-gate se_data_t se_attr_name; /* name of data attribute */ 68*0Sstevel@tonic-gate se_data_t se_attr_val; /* value and type of data */ 69*0Sstevel@tonic-gate } sysevent_attr_impl_t; 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate /* Attribute list states */ 72*0Sstevel@tonic-gate #define ATTR_DETACHED 0 73*0Sstevel@tonic-gate #define ATTR_ATTACHED 1 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate /* 76*0Sstevel@tonic-gate * The following type definitions describe a sysevent object that is 77*0Sstevel@tonic-gate * generated by a call to sysevent_alloc and sent to userland. 78*0Sstevel@tonic-gate */ 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate /* 81*0Sstevel@tonic-gate * sysevent event header information - 82*0Sstevel@tonic-gate * contained in every event generated. The header and the event 83*0Sstevel@tonic-gate * must remain 64-bit aligned. The header, up to the attribute 84*0Sstevel@tonic-gate * offset, can be contained in a single cache line. 85*0Sstevel@tonic-gate */ 86*0Sstevel@tonic-gate typedef struct sysevent_hdr { 87*0Sstevel@tonic-gate sysevent_id_t se_id; /* unique identifier */ 88*0Sstevel@tonic-gate uint32_t se_version; /* version of this data structure */ 89*0Sstevel@tonic-gate uint32_t se_flag; 90*0Sstevel@tonic-gate uint32_t se_class; /* event class id - reserved */ 91*0Sstevel@tonic-gate uint32_t se_subclass; /* event subclass id - reserved */ 92*0Sstevel@tonic-gate int32_t se_payload_sz; /* size of attr data + strings */ 93*0Sstevel@tonic-gate uint16_t se_subclass_off; /* offset to subclass string */ 94*0Sstevel@tonic-gate uint16_t se_pub_off; /* offset to publisher string */ 95*0Sstevel@tonic-gate uint64_t se_attr_off; /* pointer or offset to attr data */ 96*0Sstevel@tonic-gate } sysevent_hdr_t; 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate /* sysevent event buffer - 64-bit aligned offsets */ 99*0Sstevel@tonic-gate typedef struct sys_event_impl { 100*0Sstevel@tonic-gate sysevent_hdr_t se_header; 101*0Sstevel@tonic-gate se_data_t se_class_name; /* class string in contig memory */ 102*0Sstevel@tonic-gate se_data_t se_subclass_name; /* subclass string in contig memory */ 103*0Sstevel@tonic-gate se_data_t se_pub; /* publisher string in contig mem */ 104*0Sstevel@tonic-gate se_data_t se_attr_buf; /* contiguous attribute memory */ 105*0Sstevel@tonic-gate } sysevent_impl_t; 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gate /* Helpful defines */ 108*0Sstevel@tonic-gate #define seh_version se_header.se_version 109*0Sstevel@tonic-gate #define seh_class se_header.se_class 110*0Sstevel@tonic-gate #define seh_subclass se_header.se_subclass 111*0Sstevel@tonic-gate #define seh_seq se_header.se_id.eid_seq 112*0Sstevel@tonic-gate #define seh_time se_header.se_id.eid_ts 113*0Sstevel@tonic-gate #define seh_subclass_off se_header.se_subclass_off 114*0Sstevel@tonic-gate #define seh_pub_off se_header.se_pub_off 115*0Sstevel@tonic-gate #define seh_attr_off se_header.se_attr_off 116*0Sstevel@tonic-gate #define seh_payload_sz se_header.se_payload_sz 117*0Sstevel@tonic-gate #define seh_flag se_header.se_flag 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate /* Event buffer version */ 120*0Sstevel@tonic-gate #define SYS_EVENT_VERSION 0 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate /* Event buffer flags */ 123*0Sstevel@tonic-gate #define SE_PACKED_BUF 1 124*0Sstevel@tonic-gate 125*0Sstevel@tonic-gate #define SYSEVENT_IMPL(ev) ((sysevent_impl_t *)(void *)(ev)) 126*0Sstevel@tonic-gate #define SE_VERSION(ev) (SYSEVENT_IMPL(ev)->seh_version) 127*0Sstevel@tonic-gate #define SE_CLASS(ev) (SYSEVENT_IMPL(ev)->seh_class) 128*0Sstevel@tonic-gate #define SE_SUBCLASS(ev) (SYSEVENT_IMPL(ev)->seh_subclass) 129*0Sstevel@tonic-gate #define SE_SEQ(ev) (SYSEVENT_IMPL(ev)->seh_seq) 130*0Sstevel@tonic-gate #define SE_TIME(ev) (SYSEVENT_IMPL(ev)->seh_time) 131*0Sstevel@tonic-gate #define SE_SUBCLASS_OFF(ev) (SYSEVENT_IMPL(ev)->seh_subclass_off) 132*0Sstevel@tonic-gate #define SE_PUB_OFF(ev) (SYSEVENT_IMPL(ev)->seh_pub_off) 133*0Sstevel@tonic-gate #define SE_PAYLOAD_SZ(ev) (SYSEVENT_IMPL(ev)->seh_payload_sz) 134*0Sstevel@tonic-gate #define SE_FLAG(ev) (SYSEVENT_IMPL(ev)->seh_flag) 135*0Sstevel@tonic-gate #define SE_SIZE(ev) (sizeof (sysevent_impl_t) + SE_PAYLOAD_SZ(ev)) 136*0Sstevel@tonic-gate #define SE_CLASS_NAME(ev) ((char *)&(SYSEVENT_IMPL(ev)->se_class_name)) 137*0Sstevel@tonic-gate #define SE_SUBCLASS_NAME(ev) ((char *)((caddr_t)(ev) + SE_SUBCLASS_OFF(ev))) 138*0Sstevel@tonic-gate #define SE_PUB_NAME(ev) ((char *)((caddr_t)(ev) + SE_PUB_OFF(ev))) 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate /* 141*0Sstevel@tonic-gate * Attribute data can be stored in contiguous memory or 142*0Sstevel@tonic-gate * as a list of attribute data elements. The storage format is determined 143*0Sstevel@tonic-gate * by the SE_PACKED_BUF flag in the event buffer flags. 144*0Sstevel@tonic-gate * 145*0Sstevel@tonic-gate */ 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate /* 64-bit boundary alignment function */ 148*0Sstevel@tonic-gate #define SE_ALIGN(x) ((((ulong_t)x) + 7ul) & ~7ul) 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate /* Access to unpacked attribute list */ 151*0Sstevel@tonic-gate #define SE_ATTR_PTR(ev) (SYSEVENT_IMPL(ev)->seh_attr_off) 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gate /* Offset to packed attribute data */ 154*0Sstevel@tonic-gate #define SE_ATTR_OFF(ev) SE_PUB_OFF(ev) + SE_ALIGN(strlen(SE_PUB_NAME(ev)) + 1) 155*0Sstevel@tonic-gate 156*0Sstevel@tonic-gate /* syseventd door */ 157*0Sstevel@tonic-gate #define LOGEVENT_DOOR_UPCALL "/etc/sysevent/sysevent_door" 158*0Sstevel@tonic-gate 159*0Sstevel@tonic-gate /* 160*0Sstevel@tonic-gate * door upcall data structures 161*0Sstevel@tonic-gate */ 162*0Sstevel@tonic-gate typedef struct log_event_upcall_arg { 163*0Sstevel@tonic-gate int32_t retcode; 164*0Sstevel@tonic-gate int32_t pad; 165*0Sstevel@tonic-gate sysevent_impl_t buf; 166*0Sstevel@tonic-gate } log_event_upcall_arg_t; 167*0Sstevel@tonic-gate 168*0Sstevel@tonic-gate typedef struct log_eventq { 169*0Sstevel@tonic-gate struct log_eventq *next; 170*0Sstevel@tonic-gate log_event_upcall_arg_t arg; 171*0Sstevel@tonic-gate } log_eventq_t; 172*0Sstevel@tonic-gate 173*0Sstevel@tonic-gate /* Syseventd Channel structures */ 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate #define MAX_CHAN 256 /* Maximum channels per system */ 176*0Sstevel@tonic-gate #define MAX_SUBSCRIBERS 100 /* Maximum subscribers per channel */ 177*0Sstevel@tonic-gate #define MAX_PUBLISHERS 1 /* Maximum publishers per channel */ 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate /* 180*0Sstevel@tonic-gate * Channel-based subscription structures 181*0Sstevel@tonic-gate */ 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate /* Class hashing defines */ 184*0Sstevel@tonic-gate #define CLASS_HASH_SZ 63 185*0Sstevel@tonic-gate #define CLASS_HASH(class_name) ((hash_func(class_name) \ 186*0Sstevel@tonic-gate % CLASS_HASH_SZ) + 1) 187*0Sstevel@tonic-gate #define CHAN_HASH_SZ 32 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate typedef struct subclass_lst { 190*0Sstevel@tonic-gate struct subclass_lst *sl_next; 191*0Sstevel@tonic-gate char *sl_name; 192*0Sstevel@tonic-gate uchar_t sl_num[MAX_SUBSCRIBERS + 1]; 193*0Sstevel@tonic-gate } subclass_lst_t; 194*0Sstevel@tonic-gate 195*0Sstevel@tonic-gate typedef struct class_lst { 196*0Sstevel@tonic-gate struct class_lst *cl_next; 197*0Sstevel@tonic-gate char *cl_name; 198*0Sstevel@tonic-gate struct subclass_lst *cl_subclass_list; 199*0Sstevel@tonic-gate } class_lst_t; 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gate /* User/Kernel Structure to pass event registration modctl data */ 202*0Sstevel@tonic-gate typedef struct se_pubsub { 203*0Sstevel@tonic-gate uint32_t ps_buflen; 204*0Sstevel@tonic-gate uint32_t ps_channel_name_len; 205*0Sstevel@tonic-gate uint32_t ps_id; 206*0Sstevel@tonic-gate uint32_t ps_op; 207*0Sstevel@tonic-gate uint32_t ps_type; 208*0Sstevel@tonic-gate } se_pubsub_t; 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate /* op defines */ 211*0Sstevel@tonic-gate #define SE_REGISTER 0 212*0Sstevel@tonic-gate #define SE_UNREGISTER 1 213*0Sstevel@tonic-gate #define SE_CLEANUP 2 214*0Sstevel@tonic-gate #define SE_OPEN_REGISTRATION 3 215*0Sstevel@tonic-gate #define SE_CLOSE_REGISTRATION 4 216*0Sstevel@tonic-gate #define SE_BIND_REGISTRATION 5 217*0Sstevel@tonic-gate #define SE_UNBIND_REGISTRATION 6 218*0Sstevel@tonic-gate #define SE_GET_REGISTRATION 7 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate /* type defines */ 221*0Sstevel@tonic-gate #define SUBSCRIBER 0 222*0Sstevel@tonic-gate #define PUBLISHER 1 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate /* nvpair names */ 225*0Sstevel@tonic-gate #define CLASS_NAME "class" 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gate #ifdef _KERNEL 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate typedef struct sysevent_channel_descriptor { 230*0Sstevel@tonic-gate char *scd_channel_name; /* Name of channel */ 231*0Sstevel@tonic-gate struct sysevent_channel_descriptor *scd_next; 232*0Sstevel@tonic-gate int scd_ref_cnt; /* Reference count of channel opens */ 233*0Sstevel@tonic-gate id_space_t *scd_subscriber_cache; /* cache of subscriber ids */ 234*0Sstevel@tonic-gate id_space_t *scd_publisher_cache; /* cache of publisher ids */ 235*0Sstevel@tonic-gate uchar_t scd_subscriber_ids[MAX_SUBSCRIBERS + 1]; /* used sub ids */ 236*0Sstevel@tonic-gate uchar_t scd_publisher_ids[MAX_PUBLISHERS + 1]; /* used pub ids */ 237*0Sstevel@tonic-gate class_lst_t *scd_class_list_tbl[CLASS_HASH_SZ + 1]; 238*0Sstevel@tonic-gate } sysevent_channel_descriptor_t; 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gate /* 241*0Sstevel@tonic-gate * log_sysevent private interfaces 242*0Sstevel@tonic-gate */ 243*0Sstevel@tonic-gate void log_event_init(void); 244*0Sstevel@tonic-gate void log_sysevent_flushq(int cmd, uint_t flag); 245*0Sstevel@tonic-gate int log_sysevent_filename(char *file); 246*0Sstevel@tonic-gate int log_usr_sysevent(sysevent_t *ev, int ev_size, sysevent_id_t *eid); 247*0Sstevel@tonic-gate int log_sysevent_copyout_data(sysevent_id_t *eid, size_t ubuflen, caddr_t ubuf); 248*0Sstevel@tonic-gate int log_sysevent_free_data(sysevent_id_t *eid); 249*0Sstevel@tonic-gate int log_sysevent_register(char *channel_name, char *data, se_pubsub_t *udata); 250*0Sstevel@tonic-gate uint64_t log_sysevent_new_id(); 251*0Sstevel@tonic-gate 252*0Sstevel@tonic-gate /* 253*0Sstevel@tonic-gate * Structures and definitions for general purpose event channels 254*0Sstevel@tonic-gate */ 255*0Sstevel@tonic-gate 256*0Sstevel@tonic-gate /* Limits */ 257*0Sstevel@tonic-gate #define EVCH_MAX_CHANNELS 1024 258*0Sstevel@tonic-gate #define EVCH_MAX_BINDS_PER_CHANNEL 512 259*0Sstevel@tonic-gate #define EVCH_MAX_SUBSCRIPTIONS 32 260*0Sstevel@tonic-gate #define EVCH_SUBPOOLFACT 8 261*0Sstevel@tonic-gate #define EVCH_DEFAULT_EVENTS 2000 262*0Sstevel@tonic-gate #define EVCH_MAX_TRY_DELIVERY 3 263*0Sstevel@tonic-gate 264*0Sstevel@tonic-gate /* Linkage element for evch_dlist_t lists */ 265*0Sstevel@tonic-gate typedef struct evch_dlelem { 266*0Sstevel@tonic-gate struct evch_dlelem *dl_next; 267*0Sstevel@tonic-gate struct evch_dlelem *dl_prev; 268*0Sstevel@tonic-gate } evch_dlelem_t; 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate /* List head */ 271*0Sstevel@tonic-gate typedef struct { 272*0Sstevel@tonic-gate evch_dlelem_t dh_head; 273*0Sstevel@tonic-gate int dh_count; 274*0Sstevel@tonic-gate } evch_dlist_t; 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate /* Placeholder for elements in a evch_squeue_t queue */ 277*0Sstevel@tonic-gate typedef struct evch_qelem { 278*0Sstevel@tonic-gate struct evch_qelem *q_next; 279*0Sstevel@tonic-gate void *q_objref; 280*0Sstevel@tonic-gate size_t q_objsize; 281*0Sstevel@tonic-gate } evch_qelem_t; 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate /* Queue head data */ 284*0Sstevel@tonic-gate typedef struct { 285*0Sstevel@tonic-gate evch_qelem_t *sq_head; 286*0Sstevel@tonic-gate evch_qelem_t *sq_tail; 287*0Sstevel@tonic-gate uint32_t sq_count; 288*0Sstevel@tonic-gate uint32_t sq_highwm; 289*0Sstevel@tonic-gate } evch_squeue_t; 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate /* 292*0Sstevel@tonic-gate * Defines for event queue routines 293*0Sstevel@tonic-gate */ 294*0Sstevel@tonic-gate #define EVQ_IGNORE 1 295*0Sstevel@tonic-gate #define EVQ_DELIVER 2 296*0Sstevel@tonic-gate 297*0Sstevel@tonic-gate #define EVQ_CONT 0 298*0Sstevel@tonic-gate #define EVQ_AGAIN 1 299*0Sstevel@tonic-gate #define EVQ_SLEEP 2 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gate /* Call back routine typedefs */ 302*0Sstevel@tonic-gate typedef int (*filter_f)(void *, void *); 303*0Sstevel@tonic-gate typedef int (*deliver_f)(void *, void *); 304*0Sstevel@tonic-gate typedef int (*kerndlv_f)(void *, void *); 305*0Sstevel@tonic-gate typedef void (*destr_f)(void *, void *); 306*0Sstevel@tonic-gate typedef int (*compare_f)(evch_dlelem_t *, char *); 307*0Sstevel@tonic-gate 308*0Sstevel@tonic-gate /* 309*0Sstevel@tonic-gate * Event structure handled by evch_evq_* functions. Sysevent type events are 310*0Sstevel@tonic-gate * stored as the payload. 311*0Sstevel@tonic-gate */ 312*0Sstevel@tonic-gate typedef struct { 313*0Sstevel@tonic-gate uint32_t ge_size; /* Total size of event structure */ 314*0Sstevel@tonic-gate uint32_t ge_refcount; /* No of queues event is linked to */ 315*0Sstevel@tonic-gate destr_f ge_destruct; /* Destructor for event structure */ 316*0Sstevel@tonic-gate uint32_t *ge_dstcookie; /* Cookie for destructor function */ 317*0Sstevel@tonic-gate uchar_t ge_payload[1]; /* Placeholder for event data */ 318*0Sstevel@tonic-gate } evch_gevent_t; 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gate /* 321*0Sstevel@tonic-gate * Event queue descriptor 322*0Sstevel@tonic-gate */ 323*0Sstevel@tonic-gate typedef struct { 324*0Sstevel@tonic-gate evch_squeue_t eq_eventq; /* Protected by eq_dtmutex */ 325*0Sstevel@tonic-gate kt_did_t eq_thrid; /* Id delivery thread */ 326*0Sstevel@tonic-gate kmutex_t eq_queuemx; /* Protect. of this struct and ev q */ 327*0Sstevel@tonic-gate kcondvar_t eq_thrsleepcv; /* Delivery thread sleeps on empty q */ 328*0Sstevel@tonic-gate int eq_dactive; /* Event delivery is in progress */ 329*0Sstevel@tonic-gate kcondvar_t eq_dactivecv; /* Unsubscr. has to wait on this */ 330*0Sstevel@tonic-gate evch_dlist_t eq_subscr; /* Chain of all evch_evqsub_t */ 331*0Sstevel@tonic-gate uint32_t eq_nsleep; /* Statistic: Publisher set to sleep */ 332*0Sstevel@tonic-gate int eq_holdmode; /* Hold event delivery */ 333*0Sstevel@tonic-gate evch_gevent_t *eq_curevent; /* Event currently beeing delivered */ 334*0Sstevel@tonic-gate evch_qelem_t *eq_nextev; /* For iterating over events in a q */ 335*0Sstevel@tonic-gate kcondvar_t eq_onholdcv; /* To signal hold mode of deliv. thr. */ 336*0Sstevel@tonic-gate uchar_t eq_tabortflag; /* Request to abort delivery thread */ 337*0Sstevel@tonic-gate } evch_eventq_t; 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate /* 340*0Sstevel@tonic-gate * Event queue per subscriber structure 341*0Sstevel@tonic-gate */ 342*0Sstevel@tonic-gate typedef struct { 343*0Sstevel@tonic-gate evch_dlelem_t su_link; 344*0Sstevel@tonic-gate filter_f su_filter; /* Event filter function pointer */ 345*0Sstevel@tonic-gate void *su_fcookie; /* cookie for event filter */ 346*0Sstevel@tonic-gate deliver_f su_callb; /* Event delivery callback */ 347*0Sstevel@tonic-gate void *su_cbcookie; /* callback cookie */ 348*0Sstevel@tonic-gate } evch_evqsub_t; 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate /* Eveny delivery type */ 351*0Sstevel@tonic-gate #define EVCH_DELKERN 1 /* Kernel event delivery */ 352*0Sstevel@tonic-gate #define EVCH_DELDOOR 2 /* User event delivery via doors */ 353*0Sstevel@tonic-gate 354*0Sstevel@tonic-gate /* 355*0Sstevel@tonic-gate * Per channel subscriber data structure. Chained in a linked list to an 356*0Sstevel@tonic-gate * event channel and to a binding. 357*0Sstevel@tonic-gate */ 358*0Sstevel@tonic-gate typedef struct chsubd { 359*0Sstevel@tonic-gate evch_dlelem_t sd_link; /* Links all subscribers of this ch. */ 360*0Sstevel@tonic-gate struct chsubd *sd_subnxt; /* Links all subscr. for a binding */ 361*0Sstevel@tonic-gate char *sd_ident; /* Subscriber identifier */ 362*0Sstevel@tonic-gate evch_eventq_t *sd_queue; /* Event queue for this subscriber */ 363*0Sstevel@tonic-gate evch_evqsub_t *sd_msub; /* Main event queue subscr. */ 364*0Sstevel@tonic-gate char *sd_classname; /* Filter criteria */ 365*0Sstevel@tonic-gate size_t sd_clnsize; /* Size of sd_classname buffer */ 366*0Sstevel@tonic-gate evch_evqsub_t *sd_ssub; /* Subscriber queue subscr. */ 367*0Sstevel@tonic-gate int sd_type; /* Type of event delivery */ 368*0Sstevel@tonic-gate kerndlv_f sd_callback; /* Callback for kernel delivery */ 369*0Sstevel@tonic-gate void *sd_cbcookie; /* Cookie for kernel delivery */ 370*0Sstevel@tonic-gate door_handle_t sd_door; /* Door handle for user delivery */ 371*0Sstevel@tonic-gate int sd_active; /* Subscription is in use indicator */ 372*0Sstevel@tonic-gate pid_t sd_pid; /* PID of subscribing process */ 373*0Sstevel@tonic-gate uint8_t sd_persist; /* Persistent user land subscription */ 374*0Sstevel@tonic-gate uint8_t sd_dump; /* Dump with sysevent_evc_walk_* */ 375*0Sstevel@tonic-gate } evch_subd_t; 376*0Sstevel@tonic-gate 377*0Sstevel@tonic-gate /* 378*0Sstevel@tonic-gate * General purpose event channel descriptor structure. This is the main 379*0Sstevel@tonic-gate * structure for event subscribing, publishing, delivery to/from an event 380*0Sstevel@tonic-gate * channel. 381*0Sstevel@tonic-gate */ 382*0Sstevel@tonic-gate typedef struct { 383*0Sstevel@tonic-gate evch_dlelem_t ch_link; /* Must be first elem. of structure */ 384*0Sstevel@tonic-gate char *ch_name; /* Channel name */ 385*0Sstevel@tonic-gate size_t ch_namelen; /* Length of channel name buffer */ 386*0Sstevel@tonic-gate kmutex_t ch_mutex; /* To protect this structure */ 387*0Sstevel@tonic-gate evch_eventq_t *ch_queue; /* Publisher event queue */ 388*0Sstevel@tonic-gate evch_dlist_t ch_subscr; /* List of subscr. data (evch_subd_t) */ 389*0Sstevel@tonic-gate uint32_t ch_bindings; /* No of bindings to this channel */ 390*0Sstevel@tonic-gate int ch_maxbinds; /* Maximum number of binds */ 391*0Sstevel@tonic-gate uid_t ch_uid; /* Creators effective user id */ 392*0Sstevel@tonic-gate gid_t ch_gid; /* Creators effective group id */ 393*0Sstevel@tonic-gate kmutex_t ch_pubmx; /* Mutex for ch_pubcv and ch_nevents */ 394*0Sstevel@tonic-gate kcondvar_t ch_pubcv; /* To set publisher to sleep */ 395*0Sstevel@tonic-gate uint32_t ch_nevents; /* Current number of events */ 396*0Sstevel@tonic-gate uint32_t ch_maxev; /* Maximum number of events */ 397*0Sstevel@tonic-gate int ch_maxsubscr; /* Maximum number of subscriptions */ 398*0Sstevel@tonic-gate int ch_holdpend; /* Hold pending events mode if != 0 */ 399*0Sstevel@tonic-gate time_t ch_ctime; /* Channel creation time */ 400*0Sstevel@tonic-gate } evch_chan_t; 401*0Sstevel@tonic-gate 402*0Sstevel@tonic-gate /* 403*0Sstevel@tonic-gate * Channel binding structure. Allocated per binding to a channel. Protected 404*0Sstevel@tonic-gate * by locking the channel structure 405*0Sstevel@tonic-gate */ 406*0Sstevel@tonic-gate typedef struct { 407*0Sstevel@tonic-gate evch_chan_t *bd_channel; 408*0Sstevel@tonic-gate evch_subd_t *bd_sublst; /* chain of all subscriptions */ 409*0Sstevel@tonic-gate } evch_bind_t; 410*0Sstevel@tonic-gate 411*0Sstevel@tonic-gate /* 412*0Sstevel@tonic-gate * Structure to keep a snapshot of all events of a channel 413*0Sstevel@tonic-gate */ 414*0Sstevel@tonic-gate typedef struct { 415*0Sstevel@tonic-gate evch_eventq_t *sn_queue; /* Event queue with snapshot of ev's */ 416*0Sstevel@tonic-gate sysevent_impl_t *sn_nxtev; /* Pointer to find next event */ 417*0Sstevel@tonic-gate } evchanq_t; 418*0Sstevel@tonic-gate 419*0Sstevel@tonic-gate /* Project privat interfaces */ 420*0Sstevel@tonic-gate evchan_t *evch_usrchanopen(const char *name, uint32_t flags, int *err); 421*0Sstevel@tonic-gate void evch_usrchanclose(evchan_t *cbp); 422*0Sstevel@tonic-gate sysevent_impl_t *evch_usrallocev(size_t evsize, uint32_t flags); 423*0Sstevel@tonic-gate void evch_usrfreeev(sysevent_impl_t *ev); 424*0Sstevel@tonic-gate int evch_usrpostevent(evchan_t *bp, sysevent_impl_t *ev, uint32_t flags); 425*0Sstevel@tonic-gate int evch_usrsubscribe(evchan_t *bp, const char *sid, const char *class, 426*0Sstevel@tonic-gate int d, uint32_t flags); 427*0Sstevel@tonic-gate int evch_usrcontrol_set(evchan_t *bp, int cmd, uint32_t value); 428*0Sstevel@tonic-gate int evch_usrcontrol_get(evchan_t *bp, int cmd, uint32_t *value); 429*0Sstevel@tonic-gate void evch_usrunsubscribe(evchan_t *bp, const char *subid, uint32_t flag); 430*0Sstevel@tonic-gate int evch_usrgetchnames(char *buf, size_t size); 431*0Sstevel@tonic-gate int evch_usrgetchdata(char *chname, void *buf, size_t size); 432*0Sstevel@tonic-gate 433*0Sstevel@tonic-gate void sysevent_evc_init(); 434*0Sstevel@tonic-gate void sysevent_evc_thrinit(); 435*0Sstevel@tonic-gate evchanq_t *sysevent_evc_walk_init(evchan_t *, char *); 436*0Sstevel@tonic-gate sysevent_t *sysevent_evc_walk_step(evchanq_t *); 437*0Sstevel@tonic-gate void sysevent_evc_walk_fini(evchanq_t *); 438*0Sstevel@tonic-gate char *sysevent_evc_event_attr(sysevent_t *, size_t *); 439*0Sstevel@tonic-gate 440*0Sstevel@tonic-gate #endif /* _KERNEL */ 441*0Sstevel@tonic-gate 442*0Sstevel@tonic-gate /* 443*0Sstevel@tonic-gate * Structures and limits to deliver channel data to syseventadm 444*0Sstevel@tonic-gate */ 445*0Sstevel@tonic-gate #define EVCH_MAX_DATA_SIZE (1024 * 1024) 446*0Sstevel@tonic-gate 447*0Sstevel@tonic-gate typedef struct { 448*0Sstevel@tonic-gate uint32_t sb_nextoff; /* Offset to next subscr info struct */ 449*0Sstevel@tonic-gate uint32_t sb_stroff; /* Offset to strings */ 450*0Sstevel@tonic-gate uint32_t sb_clnamoff; /* Offset of class in sb_strings */ 451*0Sstevel@tonic-gate uint32_t sb_pid; /* Subscriber process id */ 452*0Sstevel@tonic-gate uint32_t sb_nevents; /* Current no of event in sub q */ 453*0Sstevel@tonic-gate uint32_t sb_evhwm; /* High watermark of sub q */ 454*0Sstevel@tonic-gate uint32_t sb_persist; /* != 0 if subscription persists */ 455*0Sstevel@tonic-gate uint32_t sb_status; /* != 0 if subscription is inactive */ 456*0Sstevel@tonic-gate uint32_t sb_active; /* > 0 if subscription is in use */ 457*0Sstevel@tonic-gate uint32_t sb_dump; /* != 0 if sub will be dumped */ 458*0Sstevel@tonic-gate char sb_strings[1]; /* String space for subid and class */ 459*0Sstevel@tonic-gate } sev_subinfo_t; 460*0Sstevel@tonic-gate 461*0Sstevel@tonic-gate typedef struct { 462*0Sstevel@tonic-gate uint32_t cd_version; /* Version of this structure */ 463*0Sstevel@tonic-gate uint32_t cd_suboffs; /* Offset of subscriber info struct */ 464*0Sstevel@tonic-gate uint64_t cd_ctime; /* Creation time */ 465*0Sstevel@tonic-gate uint32_t cd_uid; /* User id */ 466*0Sstevel@tonic-gate uint32_t cd_gid; /* Owner group id */ 467*0Sstevel@tonic-gate uint32_t cd_perms; /* Permission bits */ 468*0Sstevel@tonic-gate uint32_t cd_maxev; /* Max number of events */ 469*0Sstevel@tonic-gate uint32_t cd_evhwm; /* High watermark of main event queue */ 470*0Sstevel@tonic-gate uint32_t cd_nevents; /* current no of events in main ev q */ 471*0Sstevel@tonic-gate uint32_t cd_maxsub; /* Max number of subscriptions */ 472*0Sstevel@tonic-gate uint32_t cd_nsub; /* Current number of subscriptions */ 473*0Sstevel@tonic-gate uint32_t cd_maxbinds; /* Max number of binds */ 474*0Sstevel@tonic-gate uint32_t cd_nbinds; /* Current number of binds */ 475*0Sstevel@tonic-gate uint32_t cd_holdpend; /* != 0 when HOLDPEND mode is set */ 476*0Sstevel@tonic-gate uint32_t cd_limev; /* Limit of events per channel */ 477*0Sstevel@tonic-gate sev_subinfo_t cd_subinfo[1]; /* Per subscriber data */ 478*0Sstevel@tonic-gate } sev_chinfo_t; 479*0Sstevel@tonic-gate 480*0Sstevel@tonic-gate /* 481*0Sstevel@tonic-gate * Project private flags for sysevent_evc_subscribe. Bits 0 to 7 are reserved 482*0Sstevel@tonic-gate * for the consolidation private interface. 483*0Sstevel@tonic-gate */ 484*0Sstevel@tonic-gate #define EVCH_SUB_DUMP 0x0100 485*0Sstevel@tonic-gate 486*0Sstevel@tonic-gate /* 487*0Sstevel@tonic-gate * Permission flags 488*0Sstevel@tonic-gate */ 489*0Sstevel@tonic-gate #define EVCH_PUB 0x0004 /* wants to publish events */ 490*0Sstevel@tonic-gate #define EVCH_SUB 0x0008 /* wants to subscribe to channel */ 491*0Sstevel@tonic-gate 492*0Sstevel@tonic-gate #define EVCH_SUBU 0x0001 /* Subscribing allowed for uid */ 493*0Sstevel@tonic-gate #define EVCH_PUBU 0x0002 /* Publishing allowed for uid */ 494*0Sstevel@tonic-gate #define EVCH_PSUSR 0x0003 /* EVCH_SUBU + EVCH_PUBU */ 495*0Sstevel@tonic-gate #define EVCH_SUBG 0x0004 /* Subscribing allowed for gid */ 496*0Sstevel@tonic-gate #define EVCH_PUBG 0x0008 /* Publishing allowed for gid */ 497*0Sstevel@tonic-gate #define EVCH_PSGRP 0x000C /* EVCH_SUBG + EVCH_PUBG */ 498*0Sstevel@tonic-gate #define EVCH_SUBO 0x0010 /* Subscribing allowed to all users */ 499*0Sstevel@tonic-gate #define EVCH_PUBO 0x0020 /* Publishing allowed to all users */ 500*0Sstevel@tonic-gate #define EVCH_PSOTH 0x0030 /* EVCH_SUBO + EVCH_PUBO */ 501*0Sstevel@tonic-gate #define EVCH_PSALL 0x003f /* Mask of all permission bits */ 502*0Sstevel@tonic-gate 503*0Sstevel@tonic-gate /* 504*0Sstevel@tonic-gate * Sysevent driver ioctls 505*0Sstevel@tonic-gate */ 506*0Sstevel@tonic-gate #define SEV_BASE 0x53455600 507*0Sstevel@tonic-gate #define SEV_PUBLISH SEV_BASE | 0x01 508*0Sstevel@tonic-gate #define SEV_CHAN_OPEN SEV_BASE | 0x02 509*0Sstevel@tonic-gate #define SEV_CHAN_CONTROL SEV_BASE | 0x03 510*0Sstevel@tonic-gate #define SEV_SUBSCRIBE SEV_BASE | 0x04 511*0Sstevel@tonic-gate #define SEV_UNSUBSCRIBE SEV_BASE | 0x05 512*0Sstevel@tonic-gate #define SEV_CHANNAMES SEV_BASE | 0x06 513*0Sstevel@tonic-gate #define SEV_CHANDATA SEV_BASE | 0x07 514*0Sstevel@tonic-gate 515*0Sstevel@tonic-gate #define DEVSYSEVENT "/dev/sysevent" 516*0Sstevel@tonic-gate #define DEVICESYSEVENT "/devices/pseudo/sysevent@0:sysevent" 517*0Sstevel@tonic-gate 518*0Sstevel@tonic-gate /* 519*0Sstevel@tonic-gate * Maximum allowed binding handles 520*0Sstevel@tonic-gate * It's a limit required by bitmap algorithm design (see sys/bitmap.h). 521*0Sstevel@tonic-gate * Use pack(4) to make sizeof structs be the same on x86 and amd64. 522*0Sstevel@tonic-gate */ 523*0Sstevel@tonic-gate #define SYSEVENT_MINOR_MAX SHRT_MAX 524*0Sstevel@tonic-gate 525*0Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 526*0Sstevel@tonic-gate #pragma pack(4) 527*0Sstevel@tonic-gate #endif 528*0Sstevel@tonic-gate 529*0Sstevel@tonic-gate /* copyin/copyout data */ 530*0Sstevel@tonic-gate typedef struct box { 531*0Sstevel@tonic-gate uint64_t name; /* pointer to something */ 532*0Sstevel@tonic-gate uint32_t len; 533*0Sstevel@tonic-gate } sev_box_t; 534*0Sstevel@tonic-gate 535*0Sstevel@tonic-gate typedef struct bind_args { 536*0Sstevel@tonic-gate sev_box_t chan_name; 537*0Sstevel@tonic-gate uint32_t flags; 538*0Sstevel@tonic-gate } sev_bind_args_t; 539*0Sstevel@tonic-gate 540*0Sstevel@tonic-gate typedef struct control_args { 541*0Sstevel@tonic-gate uint32_t cmd; 542*0Sstevel@tonic-gate uint32_t value; 543*0Sstevel@tonic-gate } sev_control_args_t; 544*0Sstevel@tonic-gate 545*0Sstevel@tonic-gate typedef struct publish_args { 546*0Sstevel@tonic-gate sev_box_t ev; 547*0Sstevel@tonic-gate uint32_t flags; 548*0Sstevel@tonic-gate } sev_publish_args_t; 549*0Sstevel@tonic-gate 550*0Sstevel@tonic-gate typedef struct subscribe_args { 551*0Sstevel@tonic-gate sev_box_t sid; 552*0Sstevel@tonic-gate sev_box_t class_info; 553*0Sstevel@tonic-gate int door_desc; 554*0Sstevel@tonic-gate uint32_t flags; 555*0Sstevel@tonic-gate } sev_subscribe_args_t; 556*0Sstevel@tonic-gate 557*0Sstevel@tonic-gate typedef struct unsubscribe_args { 558*0Sstevel@tonic-gate sev_box_t sid; 559*0Sstevel@tonic-gate } sev_unsubscribe_args_t; 560*0Sstevel@tonic-gate 561*0Sstevel@tonic-gate typedef struct chandata { 562*0Sstevel@tonic-gate sev_box_t in_data; 563*0Sstevel@tonic-gate sev_box_t out_data; 564*0Sstevel@tonic-gate } sev_chandata_args_t; 565*0Sstevel@tonic-gate 566*0Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 567*0Sstevel@tonic-gate #pragma pack() 568*0Sstevel@tonic-gate #endif 569*0Sstevel@tonic-gate 570*0Sstevel@tonic-gate #ifdef __cplusplus 571*0Sstevel@tonic-gate } 572*0Sstevel@tonic-gate #endif 573*0Sstevel@tonic-gate 574*0Sstevel@tonic-gate #endif /* _SYS_SYSEVENT_IMPL_H */ 575