xref: /onnv-gate/usr/src/uts/common/sys/sysevent_impl.h (revision 0:68f95e015346)
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