10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 58397SEric.Schrock@Sun.COM * Common Development and Distribution License (the "License"). 68397SEric.Schrock@Sun.COM * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 21*12967Sgavin.maltby@oracle.com 220Sstevel@tonic-gate /* 23*12967Sgavin.maltby@oracle.com * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #ifndef _SYS_SYSEVENT_IMPL_H 270Sstevel@tonic-gate #define _SYS_SYSEVENT_IMPL_H 280Sstevel@tonic-gate 290Sstevel@tonic-gate #include <sys/nvpair.h> 300Sstevel@tonic-gate #include <sys/id_space.h> 310Sstevel@tonic-gate #include <sys/door.h> 320Sstevel@tonic-gate 330Sstevel@tonic-gate #ifdef __cplusplus 340Sstevel@tonic-gate extern "C" { 350Sstevel@tonic-gate #endif 360Sstevel@tonic-gate 370Sstevel@tonic-gate typedef uint64_t se_data_t; 380Sstevel@tonic-gate 390Sstevel@tonic-gate /* 400Sstevel@tonic-gate * The following data structure assist in loading and extracting event 410Sstevel@tonic-gate * header and attribute data into contiguous memory. Access to all typed 420Sstevel@tonic-gate * data done so on 64-bit boundaries. *Do Not* alter any of the structures 430Sstevel@tonic-gate * defined below without thorough thought and testing. 440Sstevel@tonic-gate */ 450Sstevel@tonic-gate 460Sstevel@tonic-gate /* Attribute name */ 470Sstevel@tonic-gate typedef struct se_name { 480Sstevel@tonic-gate int32_t name_sz; 490Sstevel@tonic-gate int32_t name_pad; 500Sstevel@tonic-gate se_data_t name; /* 64-bit aligned offset */ 510Sstevel@tonic-gate } se_name_t; 520Sstevel@tonic-gate 530Sstevel@tonic-gate /* Attribute value */ 540Sstevel@tonic-gate typedef struct se_value { 550Sstevel@tonic-gate int32_t value_type; /* data type */ 560Sstevel@tonic-gate int32_t value_sz; 570Sstevel@tonic-gate se_data_t value; /* data value - 64-bit aligned offset */ 580Sstevel@tonic-gate } se_value_t; 590Sstevel@tonic-gate 600Sstevel@tonic-gate /* sysevent internal attribute name-value pair stored in contiguous memory */ 610Sstevel@tonic-gate typedef struct sysevent_attr_impl { 620Sstevel@tonic-gate int32_t se_attr_sz; /* Size of attribute data */ 630Sstevel@tonic-gate int32_t se_attr_pad; /* pad */ 640Sstevel@tonic-gate se_data_t se_attr_name; /* name of data attribute */ 650Sstevel@tonic-gate se_data_t se_attr_val; /* value and type of data */ 660Sstevel@tonic-gate } sysevent_attr_impl_t; 670Sstevel@tonic-gate 680Sstevel@tonic-gate /* Attribute list states */ 690Sstevel@tonic-gate #define ATTR_DETACHED 0 700Sstevel@tonic-gate #define ATTR_ATTACHED 1 710Sstevel@tonic-gate 720Sstevel@tonic-gate /* 730Sstevel@tonic-gate * The following type definitions describe a sysevent object that is 740Sstevel@tonic-gate * generated by a call to sysevent_alloc and sent to userland. 750Sstevel@tonic-gate */ 760Sstevel@tonic-gate 770Sstevel@tonic-gate /* 780Sstevel@tonic-gate * sysevent event header information - 79*12967Sgavin.maltby@oracle.com * contained in every event generated. The header and the event 800Sstevel@tonic-gate * must remain 64-bit aligned. The header, up to the attribute 810Sstevel@tonic-gate * offset, can be contained in a single cache line. 820Sstevel@tonic-gate */ 830Sstevel@tonic-gate typedef struct sysevent_hdr { 840Sstevel@tonic-gate sysevent_id_t se_id; /* unique identifier */ 850Sstevel@tonic-gate uint32_t se_version; /* version of this data structure */ 860Sstevel@tonic-gate uint32_t se_flag; 870Sstevel@tonic-gate uint32_t se_class; /* event class id - reserved */ 880Sstevel@tonic-gate uint32_t se_subclass; /* event subclass id - reserved */ 890Sstevel@tonic-gate int32_t se_payload_sz; /* size of attr data + strings */ 900Sstevel@tonic-gate uint16_t se_subclass_off; /* offset to subclass string */ 910Sstevel@tonic-gate uint16_t se_pub_off; /* offset to publisher string */ 920Sstevel@tonic-gate uint64_t se_attr_off; /* pointer or offset to attr data */ 930Sstevel@tonic-gate } sysevent_hdr_t; 940Sstevel@tonic-gate 950Sstevel@tonic-gate /* sysevent event buffer - 64-bit aligned offsets */ 960Sstevel@tonic-gate typedef struct sys_event_impl { 970Sstevel@tonic-gate sysevent_hdr_t se_header; 980Sstevel@tonic-gate se_data_t se_class_name; /* class string in contig memory */ 990Sstevel@tonic-gate se_data_t se_subclass_name; /* subclass string in contig memory */ 1000Sstevel@tonic-gate se_data_t se_pub; /* publisher string in contig mem */ 101*12967Sgavin.maltby@oracle.com se_data_t se_attr_buf; /* contiguous attribute memory */ 1020Sstevel@tonic-gate } sysevent_impl_t; 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate /* Helpful defines */ 1050Sstevel@tonic-gate #define seh_version se_header.se_version 1060Sstevel@tonic-gate #define seh_class se_header.se_class 1070Sstevel@tonic-gate #define seh_subclass se_header.se_subclass 1080Sstevel@tonic-gate #define seh_seq se_header.se_id.eid_seq 1090Sstevel@tonic-gate #define seh_time se_header.se_id.eid_ts 1100Sstevel@tonic-gate #define seh_subclass_off se_header.se_subclass_off 1110Sstevel@tonic-gate #define seh_pub_off se_header.se_pub_off 1120Sstevel@tonic-gate #define seh_attr_off se_header.se_attr_off 1130Sstevel@tonic-gate #define seh_payload_sz se_header.se_payload_sz 1140Sstevel@tonic-gate #define seh_flag se_header.se_flag 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate /* Event buffer version */ 1170Sstevel@tonic-gate #define SYS_EVENT_VERSION 0 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate /* Event buffer flags */ 1200Sstevel@tonic-gate #define SE_PACKED_BUF 1 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate #define SYSEVENT_IMPL(ev) ((sysevent_impl_t *)(void *)(ev)) 1230Sstevel@tonic-gate #define SE_VERSION(ev) (SYSEVENT_IMPL(ev)->seh_version) 1240Sstevel@tonic-gate #define SE_CLASS(ev) (SYSEVENT_IMPL(ev)->seh_class) 1250Sstevel@tonic-gate #define SE_SUBCLASS(ev) (SYSEVENT_IMPL(ev)->seh_subclass) 1260Sstevel@tonic-gate #define SE_SEQ(ev) (SYSEVENT_IMPL(ev)->seh_seq) 1270Sstevel@tonic-gate #define SE_TIME(ev) (SYSEVENT_IMPL(ev)->seh_time) 1280Sstevel@tonic-gate #define SE_SUBCLASS_OFF(ev) (SYSEVENT_IMPL(ev)->seh_subclass_off) 1290Sstevel@tonic-gate #define SE_PUB_OFF(ev) (SYSEVENT_IMPL(ev)->seh_pub_off) 1300Sstevel@tonic-gate #define SE_PAYLOAD_SZ(ev) (SYSEVENT_IMPL(ev)->seh_payload_sz) 1310Sstevel@tonic-gate #define SE_FLAG(ev) (SYSEVENT_IMPL(ev)->seh_flag) 1320Sstevel@tonic-gate #define SE_SIZE(ev) (sizeof (sysevent_impl_t) + SE_PAYLOAD_SZ(ev)) 1330Sstevel@tonic-gate #define SE_CLASS_NAME(ev) ((char *)&(SYSEVENT_IMPL(ev)->se_class_name)) 1340Sstevel@tonic-gate #define SE_SUBCLASS_NAME(ev) ((char *)((caddr_t)(ev) + SE_SUBCLASS_OFF(ev))) 1350Sstevel@tonic-gate #define SE_PUB_NAME(ev) ((char *)((caddr_t)(ev) + SE_PUB_OFF(ev))) 1360Sstevel@tonic-gate 1370Sstevel@tonic-gate /* 1380Sstevel@tonic-gate * Attribute data can be stored in contiguous memory or 1390Sstevel@tonic-gate * as a list of attribute data elements. The storage format is determined 1400Sstevel@tonic-gate * by the SE_PACKED_BUF flag in the event buffer flags. 1410Sstevel@tonic-gate * 1420Sstevel@tonic-gate */ 1430Sstevel@tonic-gate 1440Sstevel@tonic-gate /* 64-bit boundary alignment function */ 1450Sstevel@tonic-gate #define SE_ALIGN(x) ((((ulong_t)x) + 7ul) & ~7ul) 1460Sstevel@tonic-gate 1470Sstevel@tonic-gate /* Access to unpacked attribute list */ 1480Sstevel@tonic-gate #define SE_ATTR_PTR(ev) (SYSEVENT_IMPL(ev)->seh_attr_off) 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate /* Offset to packed attribute data */ 1510Sstevel@tonic-gate #define SE_ATTR_OFF(ev) SE_PUB_OFF(ev) + SE_ALIGN(strlen(SE_PUB_NAME(ev)) + 1) 1520Sstevel@tonic-gate 1530Sstevel@tonic-gate /* syseventd door */ 1548397SEric.Schrock@Sun.COM #define LOGEVENT_DOOR_UPCALL "/var/run/sysevent_door" 1550Sstevel@tonic-gate 1560Sstevel@tonic-gate /* 1570Sstevel@tonic-gate * door upcall data structures 1580Sstevel@tonic-gate */ 1590Sstevel@tonic-gate typedef struct log_event_upcall_arg { 1600Sstevel@tonic-gate int32_t retcode; 1610Sstevel@tonic-gate int32_t pad; 1620Sstevel@tonic-gate sysevent_impl_t buf; 1630Sstevel@tonic-gate } log_event_upcall_arg_t; 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate typedef struct log_eventq { 1660Sstevel@tonic-gate struct log_eventq *next; 1670Sstevel@tonic-gate log_event_upcall_arg_t arg; 1680Sstevel@tonic-gate } log_eventq_t; 1690Sstevel@tonic-gate 1700Sstevel@tonic-gate /* Syseventd Channel structures */ 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate #define MAX_CHAN 256 /* Maximum channels per system */ 1730Sstevel@tonic-gate #define MAX_SUBSCRIBERS 100 /* Maximum subscribers per channel */ 1740Sstevel@tonic-gate #define MAX_PUBLISHERS 1 /* Maximum publishers per channel */ 1750Sstevel@tonic-gate 1760Sstevel@tonic-gate /* 1770Sstevel@tonic-gate * Channel-based subscription structures 1780Sstevel@tonic-gate */ 1790Sstevel@tonic-gate 1800Sstevel@tonic-gate /* Class hashing defines */ 1810Sstevel@tonic-gate #define CLASS_HASH_SZ 63 1820Sstevel@tonic-gate #define CLASS_HASH(class_name) ((hash_func(class_name) \ 1830Sstevel@tonic-gate % CLASS_HASH_SZ) + 1) 1840Sstevel@tonic-gate #define CHAN_HASH_SZ 32 1850Sstevel@tonic-gate 1860Sstevel@tonic-gate typedef struct subclass_lst { 1870Sstevel@tonic-gate struct subclass_lst *sl_next; 1880Sstevel@tonic-gate char *sl_name; 1890Sstevel@tonic-gate uchar_t sl_num[MAX_SUBSCRIBERS + 1]; 1900Sstevel@tonic-gate } subclass_lst_t; 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate typedef struct class_lst { 1930Sstevel@tonic-gate struct class_lst *cl_next; 1940Sstevel@tonic-gate char *cl_name; 1950Sstevel@tonic-gate struct subclass_lst *cl_subclass_list; 1960Sstevel@tonic-gate } class_lst_t; 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate /* User/Kernel Structure to pass event registration modctl data */ 1990Sstevel@tonic-gate typedef struct se_pubsub { 2000Sstevel@tonic-gate uint32_t ps_buflen; 2010Sstevel@tonic-gate uint32_t ps_channel_name_len; 2020Sstevel@tonic-gate uint32_t ps_id; 2030Sstevel@tonic-gate uint32_t ps_op; 2040Sstevel@tonic-gate uint32_t ps_type; 2050Sstevel@tonic-gate } se_pubsub_t; 2060Sstevel@tonic-gate 2070Sstevel@tonic-gate /* op defines */ 2080Sstevel@tonic-gate #define SE_REGISTER 0 2090Sstevel@tonic-gate #define SE_UNREGISTER 1 2100Sstevel@tonic-gate #define SE_CLEANUP 2 2110Sstevel@tonic-gate #define SE_OPEN_REGISTRATION 3 2120Sstevel@tonic-gate #define SE_CLOSE_REGISTRATION 4 2130Sstevel@tonic-gate #define SE_BIND_REGISTRATION 5 2140Sstevel@tonic-gate #define SE_UNBIND_REGISTRATION 6 2150Sstevel@tonic-gate #define SE_GET_REGISTRATION 7 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate /* type defines */ 2180Sstevel@tonic-gate #define SUBSCRIBER 0 2190Sstevel@tonic-gate #define PUBLISHER 1 2200Sstevel@tonic-gate 2210Sstevel@tonic-gate /* nvpair names */ 2220Sstevel@tonic-gate #define CLASS_NAME "class" 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate #ifdef _KERNEL 2250Sstevel@tonic-gate 2260Sstevel@tonic-gate typedef struct sysevent_channel_descriptor { 2270Sstevel@tonic-gate char *scd_channel_name; /* Name of channel */ 2280Sstevel@tonic-gate struct sysevent_channel_descriptor *scd_next; 2290Sstevel@tonic-gate int scd_ref_cnt; /* Reference count of channel opens */ 2300Sstevel@tonic-gate id_space_t *scd_subscriber_cache; /* cache of subscriber ids */ 2310Sstevel@tonic-gate id_space_t *scd_publisher_cache; /* cache of publisher ids */ 2320Sstevel@tonic-gate uchar_t scd_subscriber_ids[MAX_SUBSCRIBERS + 1]; /* used sub ids */ 2330Sstevel@tonic-gate uchar_t scd_publisher_ids[MAX_PUBLISHERS + 1]; /* used pub ids */ 2340Sstevel@tonic-gate class_lst_t *scd_class_list_tbl[CLASS_HASH_SZ + 1]; 2350Sstevel@tonic-gate } sysevent_channel_descriptor_t; 2360Sstevel@tonic-gate 2370Sstevel@tonic-gate /* 2380Sstevel@tonic-gate * log_sysevent private interfaces 2390Sstevel@tonic-gate */ 240*12967Sgavin.maltby@oracle.com extern void log_event_init(void); 241*12967Sgavin.maltby@oracle.com extern void log_sysevent_flushq(int, uint_t); 242*12967Sgavin.maltby@oracle.com extern int log_sysevent_filename(char *); 243*12967Sgavin.maltby@oracle.com extern int log_usr_sysevent(sysevent_t *, int, sysevent_id_t *); 244*12967Sgavin.maltby@oracle.com extern int log_sysevent_copyout_data(sysevent_id_t *, size_t, caddr_t); 245*12967Sgavin.maltby@oracle.com extern int log_sysevent_free_data(sysevent_id_t *); 246*12967Sgavin.maltby@oracle.com extern int log_sysevent_register(char *, char *, se_pubsub_t *); 247*12967Sgavin.maltby@oracle.com extern uint64_t log_sysevent_new_id(void); 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate /* 2500Sstevel@tonic-gate * Structures and definitions for general purpose event channels 2510Sstevel@tonic-gate */ 2520Sstevel@tonic-gate 2530Sstevel@tonic-gate /* Limits */ 2540Sstevel@tonic-gate #define EVCH_MAX_CHANNELS 1024 2550Sstevel@tonic-gate #define EVCH_MAX_BINDS_PER_CHANNEL 512 2560Sstevel@tonic-gate #define EVCH_MAX_SUBSCRIPTIONS 32 2570Sstevel@tonic-gate #define EVCH_SUBPOOLFACT 8 2580Sstevel@tonic-gate #define EVCH_DEFAULT_EVENTS 2000 2590Sstevel@tonic-gate #define EVCH_MAX_TRY_DELIVERY 3 2600Sstevel@tonic-gate 2610Sstevel@tonic-gate /* Linkage element for evch_dlist_t lists */ 2620Sstevel@tonic-gate typedef struct evch_dlelem { 2630Sstevel@tonic-gate struct evch_dlelem *dl_next; 2640Sstevel@tonic-gate struct evch_dlelem *dl_prev; 2650Sstevel@tonic-gate } evch_dlelem_t; 2660Sstevel@tonic-gate 2670Sstevel@tonic-gate /* List head */ 2680Sstevel@tonic-gate typedef struct { 2690Sstevel@tonic-gate evch_dlelem_t dh_head; 2700Sstevel@tonic-gate int dh_count; 2710Sstevel@tonic-gate } evch_dlist_t; 2720Sstevel@tonic-gate 2730Sstevel@tonic-gate /* Placeholder for elements in a evch_squeue_t queue */ 2740Sstevel@tonic-gate typedef struct evch_qelem { 2750Sstevel@tonic-gate struct evch_qelem *q_next; 2760Sstevel@tonic-gate void *q_objref; 2770Sstevel@tonic-gate size_t q_objsize; 2780Sstevel@tonic-gate } evch_qelem_t; 2790Sstevel@tonic-gate 2800Sstevel@tonic-gate /* Queue head data */ 2810Sstevel@tonic-gate typedef struct { 2820Sstevel@tonic-gate evch_qelem_t *sq_head; 2830Sstevel@tonic-gate evch_qelem_t *sq_tail; 284*12967Sgavin.maltby@oracle.com uint32_t sq_count; 285*12967Sgavin.maltby@oracle.com uint32_t sq_highwm; 2860Sstevel@tonic-gate } evch_squeue_t; 2870Sstevel@tonic-gate 2880Sstevel@tonic-gate /* 2890Sstevel@tonic-gate * Defines for event queue routines 2900Sstevel@tonic-gate */ 2910Sstevel@tonic-gate #define EVQ_IGNORE 1 2920Sstevel@tonic-gate #define EVQ_DELIVER 2 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate #define EVQ_CONT 0 2950Sstevel@tonic-gate #define EVQ_AGAIN 1 2960Sstevel@tonic-gate #define EVQ_SLEEP 2 2970Sstevel@tonic-gate 2980Sstevel@tonic-gate /* Call back routine typedefs */ 2990Sstevel@tonic-gate typedef int (*filter_f)(void *, void *); 3000Sstevel@tonic-gate typedef int (*deliver_f)(void *, void *); 3010Sstevel@tonic-gate typedef int (*kerndlv_f)(void *, void *); 3020Sstevel@tonic-gate typedef void (*destr_f)(void *, void *); 3030Sstevel@tonic-gate typedef int (*compare_f)(evch_dlelem_t *, char *); 3040Sstevel@tonic-gate 3050Sstevel@tonic-gate /* 3060Sstevel@tonic-gate * Event structure handled by evch_evq_* functions. Sysevent type events are 3070Sstevel@tonic-gate * stored as the payload. 3080Sstevel@tonic-gate */ 3090Sstevel@tonic-gate typedef struct { 3100Sstevel@tonic-gate uint32_t ge_size; /* Total size of event structure */ 3110Sstevel@tonic-gate uint32_t ge_refcount; /* No of queues event is linked to */ 3120Sstevel@tonic-gate destr_f ge_destruct; /* Destructor for event structure */ 3130Sstevel@tonic-gate uint32_t *ge_dstcookie; /* Cookie for destructor function */ 3140Sstevel@tonic-gate uchar_t ge_payload[1]; /* Placeholder for event data */ 3150Sstevel@tonic-gate } evch_gevent_t; 3160Sstevel@tonic-gate 3170Sstevel@tonic-gate /* 3180Sstevel@tonic-gate * Event queue descriptor 3190Sstevel@tonic-gate */ 3200Sstevel@tonic-gate typedef struct { 3210Sstevel@tonic-gate evch_squeue_t eq_eventq; /* Protected by eq_dtmutex */ 3220Sstevel@tonic-gate kt_did_t eq_thrid; /* Id delivery thread */ 3230Sstevel@tonic-gate kmutex_t eq_queuemx; /* Protect. of this struct and ev q */ 3240Sstevel@tonic-gate kcondvar_t eq_thrsleepcv; /* Delivery thread sleeps on empty q */ 3250Sstevel@tonic-gate int eq_dactive; /* Event delivery is in progress */ 3260Sstevel@tonic-gate kcondvar_t eq_dactivecv; /* Unsubscr. has to wait on this */ 3270Sstevel@tonic-gate evch_dlist_t eq_subscr; /* Chain of all evch_evqsub_t */ 3280Sstevel@tonic-gate uint32_t eq_nsleep; /* Statistic: Publisher set to sleep */ 3290Sstevel@tonic-gate int eq_holdmode; /* Hold event delivery */ 3300Sstevel@tonic-gate evch_gevent_t *eq_curevent; /* Event currently beeing delivered */ 3310Sstevel@tonic-gate evch_qelem_t *eq_nextev; /* For iterating over events in a q */ 3320Sstevel@tonic-gate kcondvar_t eq_onholdcv; /* To signal hold mode of deliv. thr. */ 3330Sstevel@tonic-gate uchar_t eq_tabortflag; /* Request to abort delivery thread */ 3340Sstevel@tonic-gate } evch_eventq_t; 3350Sstevel@tonic-gate 3360Sstevel@tonic-gate /* 3370Sstevel@tonic-gate * Event queue per subscriber structure 3380Sstevel@tonic-gate */ 3390Sstevel@tonic-gate typedef struct { 3400Sstevel@tonic-gate evch_dlelem_t su_link; 3410Sstevel@tonic-gate filter_f su_filter; /* Event filter function pointer */ 3420Sstevel@tonic-gate void *su_fcookie; /* cookie for event filter */ 3430Sstevel@tonic-gate deliver_f su_callb; /* Event delivery callback */ 3440Sstevel@tonic-gate void *su_cbcookie; /* callback cookie */ 3450Sstevel@tonic-gate } evch_evqsub_t; 3460Sstevel@tonic-gate 3470Sstevel@tonic-gate /* Eveny delivery type */ 3480Sstevel@tonic-gate #define EVCH_DELKERN 1 /* Kernel event delivery */ 3490Sstevel@tonic-gate #define EVCH_DELDOOR 2 /* User event delivery via doors */ 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate /* 3520Sstevel@tonic-gate * Per channel subscriber data structure. Chained in a linked list to an 3530Sstevel@tonic-gate * event channel and to a binding. 3540Sstevel@tonic-gate */ 3550Sstevel@tonic-gate typedef struct chsubd { 3560Sstevel@tonic-gate evch_dlelem_t sd_link; /* Links all subscribers of this ch. */ 3570Sstevel@tonic-gate struct chsubd *sd_subnxt; /* Links all subscr. for a binding */ 3580Sstevel@tonic-gate char *sd_ident; /* Subscriber identifier */ 3590Sstevel@tonic-gate evch_eventq_t *sd_queue; /* Event queue for this subscriber */ 3600Sstevel@tonic-gate evch_evqsub_t *sd_msub; /* Main event queue subscr. */ 3610Sstevel@tonic-gate char *sd_classname; /* Filter criteria */ 3620Sstevel@tonic-gate size_t sd_clnsize; /* Size of sd_classname buffer */ 3630Sstevel@tonic-gate evch_evqsub_t *sd_ssub; /* Subscriber queue subscr. */ 3640Sstevel@tonic-gate int sd_type; /* Type of event delivery */ 3650Sstevel@tonic-gate kerndlv_f sd_callback; /* Callback for kernel delivery */ 3660Sstevel@tonic-gate void *sd_cbcookie; /* Cookie for kernel delivery */ 3670Sstevel@tonic-gate door_handle_t sd_door; /* Door handle for user delivery */ 3680Sstevel@tonic-gate int sd_active; /* Subscription is in use indicator */ 3690Sstevel@tonic-gate pid_t sd_pid; /* PID of subscribing process */ 3700Sstevel@tonic-gate uint8_t sd_persist; /* Persistent user land subscription */ 3710Sstevel@tonic-gate uint8_t sd_dump; /* Dump with sysevent_evc_walk_* */ 3720Sstevel@tonic-gate } evch_subd_t; 3730Sstevel@tonic-gate 3740Sstevel@tonic-gate /* 3750Sstevel@tonic-gate * General purpose event channel descriptor structure. This is the main 3760Sstevel@tonic-gate * structure for event subscribing, publishing, delivery to/from an event 3770Sstevel@tonic-gate * channel. 3780Sstevel@tonic-gate */ 3790Sstevel@tonic-gate typedef struct { 3800Sstevel@tonic-gate evch_dlelem_t ch_link; /* Must be first elem. of structure */ 3810Sstevel@tonic-gate char *ch_name; /* Channel name */ 3820Sstevel@tonic-gate size_t ch_namelen; /* Length of channel name buffer */ 3830Sstevel@tonic-gate kmutex_t ch_mutex; /* To protect this structure */ 3840Sstevel@tonic-gate evch_eventq_t *ch_queue; /* Publisher event queue */ 3850Sstevel@tonic-gate evch_dlist_t ch_subscr; /* List of subscr. data (evch_subd_t) */ 3860Sstevel@tonic-gate uint32_t ch_bindings; /* No of bindings to this channel */ 3870Sstevel@tonic-gate int ch_maxbinds; /* Maximum number of binds */ 3880Sstevel@tonic-gate uid_t ch_uid; /* Creators effective user id */ 3890Sstevel@tonic-gate gid_t ch_gid; /* Creators effective group id */ 3900Sstevel@tonic-gate kmutex_t ch_pubmx; /* Mutex for ch_pubcv and ch_nevents */ 3910Sstevel@tonic-gate kcondvar_t ch_pubcv; /* To set publisher to sleep */ 3920Sstevel@tonic-gate uint32_t ch_nevents; /* Current number of events */ 3930Sstevel@tonic-gate uint32_t ch_maxev; /* Maximum number of events */ 3940Sstevel@tonic-gate int ch_maxsubscr; /* Maximum number of subscriptions */ 3950Sstevel@tonic-gate int ch_holdpend; /* Hold pending events mode if != 0 */ 3960Sstevel@tonic-gate time_t ch_ctime; /* Channel creation time */ 397*12967Sgavin.maltby@oracle.com nvlist_t *ch_propnvl; /* Channel properties nvlist */ 398*12967Sgavin.maltby@oracle.com int64_t ch_propnvlgen; /* Properties generation number */ 3990Sstevel@tonic-gate } evch_chan_t; 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate /* 4020Sstevel@tonic-gate * Channel binding structure. Allocated per binding to a channel. Protected 4030Sstevel@tonic-gate * by locking the channel structure 4040Sstevel@tonic-gate */ 4050Sstevel@tonic-gate typedef struct { 4060Sstevel@tonic-gate evch_chan_t *bd_channel; 4070Sstevel@tonic-gate evch_subd_t *bd_sublst; /* chain of all subscriptions */ 4080Sstevel@tonic-gate } evch_bind_t; 4090Sstevel@tonic-gate 4100Sstevel@tonic-gate /* 4110Sstevel@tonic-gate * Structure to keep a snapshot of all events of a channel 4120Sstevel@tonic-gate */ 4130Sstevel@tonic-gate typedef struct { 4140Sstevel@tonic-gate evch_eventq_t *sn_queue; /* Event queue with snapshot of ev's */ 4150Sstevel@tonic-gate sysevent_impl_t *sn_nxtev; /* Pointer to find next event */ 4160Sstevel@tonic-gate } evchanq_t; 4170Sstevel@tonic-gate 418*12967Sgavin.maltby@oracle.com /* Project private interfaces */ 419*12967Sgavin.maltby@oracle.com extern evchan_t *evch_usrchanopen(const char *name, uint32_t flags, int *err); 420*12967Sgavin.maltby@oracle.com extern void evch_usrchanclose(evchan_t *cbp); 421*12967Sgavin.maltby@oracle.com extern sysevent_impl_t *evch_usrallocev(size_t evsize, uint32_t flags); 422*12967Sgavin.maltby@oracle.com extern void evch_usrfreeev(sysevent_impl_t *ev); 423*12967Sgavin.maltby@oracle.com extern int evch_usrpostevent(evchan_t *bp, sysevent_impl_t *ev, uint32_t flags); 424*12967Sgavin.maltby@oracle.com extern int evch_usrsubscribe(evchan_t *bp, const char *sid, const char *class, 4250Sstevel@tonic-gate int d, uint32_t flags); 426*12967Sgavin.maltby@oracle.com extern int evch_usrcontrol_set(evchan_t *bp, int cmd, uint32_t value); 427*12967Sgavin.maltby@oracle.com extern int evch_usrcontrol_get(evchan_t *bp, int cmd, uint32_t *value); 428*12967Sgavin.maltby@oracle.com extern void evch_usrunsubscribe(evchan_t *bp, const char *subid, uint32_t flag); 429*12967Sgavin.maltby@oracle.com extern int evch_usrgetchnames(char *buf, size_t size); 430*12967Sgavin.maltby@oracle.com extern int evch_usrgetchdata(char *chname, void *buf, size_t size); 431*12967Sgavin.maltby@oracle.com extern void evch_usrsetpropnvl(evchan_t *bp, nvlist_t *nvl); 432*12967Sgavin.maltby@oracle.com extern int evch_usrgetpropnvl(evchan_t *bp, nvlist_t **nvlp, int64_t *genp); 4330Sstevel@tonic-gate 434*12967Sgavin.maltby@oracle.com extern void sysevent_evc_init(); 435*12967Sgavin.maltby@oracle.com extern void sysevent_evc_thrinit(); 436*12967Sgavin.maltby@oracle.com extern evchanq_t *sysevent_evc_walk_init(evchan_t *, char *); 437*12967Sgavin.maltby@oracle.com extern sysevent_t *sysevent_evc_walk_step(evchanq_t *); 438*12967Sgavin.maltby@oracle.com extern void sysevent_evc_walk_fini(evchanq_t *); 439*12967Sgavin.maltby@oracle.com extern char *sysevent_evc_event_attr(sysevent_t *, size_t *); 4400Sstevel@tonic-gate 4410Sstevel@tonic-gate #endif /* _KERNEL */ 4420Sstevel@tonic-gate 4430Sstevel@tonic-gate /* 4440Sstevel@tonic-gate * Structures and limits to deliver channel data to syseventadm 4450Sstevel@tonic-gate */ 4460Sstevel@tonic-gate #define EVCH_MAX_DATA_SIZE (1024 * 1024) 4470Sstevel@tonic-gate 4480Sstevel@tonic-gate typedef struct { 4490Sstevel@tonic-gate uint32_t sb_nextoff; /* Offset to next subscr info struct */ 4500Sstevel@tonic-gate uint32_t sb_stroff; /* Offset to strings */ 4510Sstevel@tonic-gate uint32_t sb_clnamoff; /* Offset of class in sb_strings */ 4520Sstevel@tonic-gate uint32_t sb_pid; /* Subscriber process id */ 4530Sstevel@tonic-gate uint32_t sb_nevents; /* Current no of event in sub q */ 4540Sstevel@tonic-gate uint32_t sb_evhwm; /* High watermark of sub q */ 4550Sstevel@tonic-gate uint32_t sb_persist; /* != 0 if subscription persists */ 4560Sstevel@tonic-gate uint32_t sb_status; /* != 0 if subscription is inactive */ 4570Sstevel@tonic-gate uint32_t sb_active; /* > 0 if subscription is in use */ 4580Sstevel@tonic-gate uint32_t sb_dump; /* != 0 if sub will be dumped */ 4590Sstevel@tonic-gate char sb_strings[1]; /* String space for subid and class */ 4600Sstevel@tonic-gate } sev_subinfo_t; 4610Sstevel@tonic-gate 4620Sstevel@tonic-gate typedef struct { 4630Sstevel@tonic-gate uint32_t cd_version; /* Version of this structure */ 4640Sstevel@tonic-gate uint32_t cd_suboffs; /* Offset of subscriber info struct */ 4650Sstevel@tonic-gate uint64_t cd_ctime; /* Creation time */ 4660Sstevel@tonic-gate uint32_t cd_uid; /* User id */ 4670Sstevel@tonic-gate uint32_t cd_gid; /* Owner group id */ 4680Sstevel@tonic-gate uint32_t cd_perms; /* Permission bits */ 4690Sstevel@tonic-gate uint32_t cd_maxev; /* Max number of events */ 4700Sstevel@tonic-gate uint32_t cd_evhwm; /* High watermark of main event queue */ 4710Sstevel@tonic-gate uint32_t cd_nevents; /* current no of events in main ev q */ 4720Sstevel@tonic-gate uint32_t cd_maxsub; /* Max number of subscriptions */ 4730Sstevel@tonic-gate uint32_t cd_nsub; /* Current number of subscriptions */ 4740Sstevel@tonic-gate uint32_t cd_maxbinds; /* Max number of binds */ 4750Sstevel@tonic-gate uint32_t cd_nbinds; /* Current number of binds */ 4760Sstevel@tonic-gate uint32_t cd_holdpend; /* != 0 when HOLDPEND mode is set */ 4770Sstevel@tonic-gate uint32_t cd_limev; /* Limit of events per channel */ 4780Sstevel@tonic-gate sev_subinfo_t cd_subinfo[1]; /* Per subscriber data */ 4790Sstevel@tonic-gate } sev_chinfo_t; 4800Sstevel@tonic-gate 4810Sstevel@tonic-gate /* 4820Sstevel@tonic-gate * Project private flags for sysevent_evc_subscribe. Bits 0 to 7 are reserved 48311102SGavin.Maltby@Sun.COM * for the consolidation private interface, so we must use bits 8-15 here. 4840Sstevel@tonic-gate */ 48511102SGavin.Maltby@Sun.COM #define EVCH_SUB_DUMP (0x01 << 8) 4860Sstevel@tonic-gate 4870Sstevel@tonic-gate /* 4880Sstevel@tonic-gate * Permission flags 4890Sstevel@tonic-gate */ 4900Sstevel@tonic-gate #define EVCH_PUB 0x0004 /* wants to publish events */ 4910Sstevel@tonic-gate #define EVCH_SUB 0x0008 /* wants to subscribe to channel */ 4920Sstevel@tonic-gate 4930Sstevel@tonic-gate #define EVCH_SUBU 0x0001 /* Subscribing allowed for uid */ 4940Sstevel@tonic-gate #define EVCH_PUBU 0x0002 /* Publishing allowed for uid */ 4950Sstevel@tonic-gate #define EVCH_PSUSR 0x0003 /* EVCH_SUBU + EVCH_PUBU */ 4960Sstevel@tonic-gate #define EVCH_SUBG 0x0004 /* Subscribing allowed for gid */ 4970Sstevel@tonic-gate #define EVCH_PUBG 0x0008 /* Publishing allowed for gid */ 4980Sstevel@tonic-gate #define EVCH_PSGRP 0x000C /* EVCH_SUBG + EVCH_PUBG */ 4990Sstevel@tonic-gate #define EVCH_SUBO 0x0010 /* Subscribing allowed to all users */ 5000Sstevel@tonic-gate #define EVCH_PUBO 0x0020 /* Publishing allowed to all users */ 5010Sstevel@tonic-gate #define EVCH_PSOTH 0x0030 /* EVCH_SUBO + EVCH_PUBO */ 5020Sstevel@tonic-gate #define EVCH_PSALL 0x003f /* Mask of all permission bits */ 5030Sstevel@tonic-gate 5040Sstevel@tonic-gate /* 5050Sstevel@tonic-gate * Sysevent driver ioctls 5060Sstevel@tonic-gate */ 5070Sstevel@tonic-gate #define SEV_BASE 0x53455600 5080Sstevel@tonic-gate #define SEV_PUBLISH SEV_BASE | 0x01 5090Sstevel@tonic-gate #define SEV_CHAN_OPEN SEV_BASE | 0x02 5100Sstevel@tonic-gate #define SEV_CHAN_CONTROL SEV_BASE | 0x03 5110Sstevel@tonic-gate #define SEV_SUBSCRIBE SEV_BASE | 0x04 5120Sstevel@tonic-gate #define SEV_UNSUBSCRIBE SEV_BASE | 0x05 5130Sstevel@tonic-gate #define SEV_CHANNAMES SEV_BASE | 0x06 5140Sstevel@tonic-gate #define SEV_CHANDATA SEV_BASE | 0x07 515*12967Sgavin.maltby@oracle.com #define SEV_SETPROPNVL SEV_BASE | 0x08 516*12967Sgavin.maltby@oracle.com #define SEV_GETPROPNVL SEV_BASE | 0x09 5170Sstevel@tonic-gate 5180Sstevel@tonic-gate #define DEVSYSEVENT "/dev/sysevent" 5190Sstevel@tonic-gate #define DEVICESYSEVENT "/devices/pseudo/sysevent@0:sysevent" 5200Sstevel@tonic-gate 5210Sstevel@tonic-gate /* 5220Sstevel@tonic-gate * Maximum allowed binding handles 5230Sstevel@tonic-gate * It's a limit required by bitmap algorithm design (see sys/bitmap.h). 5240Sstevel@tonic-gate * Use pack(4) to make sizeof structs be the same on x86 and amd64. 5250Sstevel@tonic-gate */ 5260Sstevel@tonic-gate #define SYSEVENT_MINOR_MAX SHRT_MAX 5270Sstevel@tonic-gate 5280Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 5290Sstevel@tonic-gate #pragma pack(4) 5300Sstevel@tonic-gate #endif 5310Sstevel@tonic-gate 5320Sstevel@tonic-gate /* copyin/copyout data */ 5330Sstevel@tonic-gate typedef struct box { 5340Sstevel@tonic-gate uint64_t name; /* pointer to something */ 5350Sstevel@tonic-gate uint32_t len; 5360Sstevel@tonic-gate } sev_box_t; 5370Sstevel@tonic-gate 5380Sstevel@tonic-gate typedef struct bind_args { 5390Sstevel@tonic-gate sev_box_t chan_name; 5400Sstevel@tonic-gate uint32_t flags; 5410Sstevel@tonic-gate } sev_bind_args_t; 5420Sstevel@tonic-gate 5430Sstevel@tonic-gate typedef struct control_args { 5440Sstevel@tonic-gate uint32_t cmd; 5450Sstevel@tonic-gate uint32_t value; 5460Sstevel@tonic-gate } sev_control_args_t; 5470Sstevel@tonic-gate 5480Sstevel@tonic-gate typedef struct publish_args { 5490Sstevel@tonic-gate sev_box_t ev; 5500Sstevel@tonic-gate uint32_t flags; 5510Sstevel@tonic-gate } sev_publish_args_t; 5520Sstevel@tonic-gate 5530Sstevel@tonic-gate typedef struct subscribe_args { 5540Sstevel@tonic-gate sev_box_t sid; 5550Sstevel@tonic-gate sev_box_t class_info; 5560Sstevel@tonic-gate int door_desc; 5570Sstevel@tonic-gate uint32_t flags; 5580Sstevel@tonic-gate } sev_subscribe_args_t; 5590Sstevel@tonic-gate 5600Sstevel@tonic-gate typedef struct unsubscribe_args { 5610Sstevel@tonic-gate sev_box_t sid; 5620Sstevel@tonic-gate } sev_unsubscribe_args_t; 5630Sstevel@tonic-gate 5640Sstevel@tonic-gate typedef struct chandata { 5650Sstevel@tonic-gate sev_box_t in_data; 5660Sstevel@tonic-gate sev_box_t out_data; 5670Sstevel@tonic-gate } sev_chandata_args_t; 5680Sstevel@tonic-gate 569*12967Sgavin.maltby@oracle.com typedef struct propnvl_args { 570*12967Sgavin.maltby@oracle.com sev_box_t packednvl; /* input and output */ 571*12967Sgavin.maltby@oracle.com int64_t generation; /* output on get operation */ 572*12967Sgavin.maltby@oracle.com } sev_propnvl_args_t; 573*12967Sgavin.maltby@oracle.com 5740Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 5750Sstevel@tonic-gate #pragma pack() 5760Sstevel@tonic-gate #endif 5770Sstevel@tonic-gate 5780Sstevel@tonic-gate #ifdef __cplusplus 5790Sstevel@tonic-gate } 5800Sstevel@tonic-gate #endif 5810Sstevel@tonic-gate 5820Sstevel@tonic-gate #endif /* _SYS_SYSEVENT_IMPL_H */ 583