summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/sysevent_impl.h
blob: 117452765f598e12e9fc52235f1059a6791c5f5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
 */

#ifndef	_SYS_SYSEVENT_IMPL_H
#define	_SYS_SYSEVENT_IMPL_H

#include <sys/nvpair.h>
#include <sys/id_space.h>
#include <sys/door.h>

#ifdef	__cplusplus
extern "C" {
#endif

typedef uint64_t se_data_t;

/*
 * The following data structure assist in loading and extracting event
 * header and attribute data into contiguous memory.  Access to all typed
 * data done so on 64-bit boundaries.  *Do Not* alter any of the structures
 * defined below without thorough thought and testing.
 */

/* Attribute name */
typedef struct se_name {
	int32_t		name_sz;
	int32_t		name_pad;
	se_data_t	name;	/* 64-bit aligned offset */
} se_name_t;

/* Attribute value */
typedef struct se_value {
	int32_t		value_type;	/* data type */
	int32_t		value_sz;
	se_data_t	value;		/* data value - 64-bit aligned offset */
} se_value_t;

/* sysevent internal attribute name-value pair stored in contiguous memory */
typedef struct sysevent_attr_impl {
	int32_t		se_attr_sz;	/* Size of attribute data */
	int32_t		se_attr_pad;	/* pad */
	se_data_t	se_attr_name;	/* name of data attribute */
	se_data_t	se_attr_val;	/* value and type of data */
} sysevent_attr_impl_t;

/* Attribute list states */
#define	ATTR_DETACHED	0
#define	ATTR_ATTACHED	1

/*
 * The following type definitions describe a sysevent object that is
 * generated by a call to sysevent_alloc and sent to userland.
 */

/*
 * sysevent event header information -
 *	contained in every event generated.  The header and the event
 *	must remain 64-bit aligned.  The header, up to the attribute
 *	offset, can be contained in a single cache line.
 */
typedef struct sysevent_hdr {
	sysevent_id_t	se_id;		/* unique identifier */
	uint32_t	se_version;	/* version of this data structure */
	uint32_t	se_flag;
	uint32_t	se_class;	/* event class id - reserved */
	uint32_t	se_subclass;	/* event subclass id - reserved */
	int32_t		se_payload_sz;	/* size of attr data + strings */
	uint16_t	se_subclass_off; /* offset to subclass string */
	uint16_t	se_pub_off;	/* offset to publisher string */
	uint64_t	se_attr_off;	/* pointer or offset to attr data */
} sysevent_hdr_t;

/* sysevent event buffer - 64-bit aligned offsets */
typedef struct sys_event_impl {
	sysevent_hdr_t	se_header;
	se_data_t	se_class_name;	/* class string in contig memory */
	se_data_t	se_subclass_name; /* subclass string in contig memory */
	se_data_t	se_pub;		/* publisher string in contig mem */
	se_data_t	se_attr_buf;	/* contiguous attribute memory	*/
} sysevent_impl_t;

/* Helpful defines */
#define	seh_version	se_header.se_version
#define	seh_class	se_header.se_class
#define	seh_subclass	se_header.se_subclass
#define	seh_seq		se_header.se_id.eid_seq
#define	seh_time	se_header.se_id.eid_ts
#define	seh_subclass_off se_header.se_subclass_off
#define	seh_pub_off	se_header.se_pub_off
#define	seh_attr_off	se_header.se_attr_off
#define	seh_payload_sz	se_header.se_payload_sz
#define	seh_flag	se_header.se_flag

/* Event buffer version */
#define	SYS_EVENT_VERSION	0

/* Event buffer flags */
#define	SE_PACKED_BUF	1

#define	SYSEVENT_IMPL(ev)	((sysevent_impl_t *)(void *)(ev))
#define	SE_VERSION(ev)		(SYSEVENT_IMPL(ev)->seh_version)
#define	SE_CLASS(ev)		(SYSEVENT_IMPL(ev)->seh_class)
#define	SE_SUBCLASS(ev)		(SYSEVENT_IMPL(ev)->seh_subclass)
#define	SE_SEQ(ev)		(SYSEVENT_IMPL(ev)->seh_seq)
#define	SE_TIME(ev)		(SYSEVENT_IMPL(ev)->seh_time)
#define	SE_SUBCLASS_OFF(ev)	(SYSEVENT_IMPL(ev)->seh_subclass_off)
#define	SE_PUB_OFF(ev)		(SYSEVENT_IMPL(ev)->seh_pub_off)
#define	SE_PAYLOAD_SZ(ev)	(SYSEVENT_IMPL(ev)->seh_payload_sz)
#define	SE_FLAG(ev)		(SYSEVENT_IMPL(ev)->seh_flag)
#define	SE_SIZE(ev)		(sizeof (sysevent_impl_t) + SE_PAYLOAD_SZ(ev))
#define	SE_CLASS_NAME(ev)	((char *)&(SYSEVENT_IMPL(ev)->se_class_name))
#define	SE_SUBCLASS_NAME(ev)	((char *)((caddr_t)(ev) + SE_SUBCLASS_OFF(ev)))
#define	SE_PUB_NAME(ev)		((char *)((caddr_t)(ev) + SE_PUB_OFF(ev)))

/*
 * Attribute data can be stored in contiguous memory or
 * as a list of attribute data elements.  The storage format is determined
 * by the SE_PACKED_BUF flag in the event buffer flags.
 *
 */

/* 64-bit boundary alignment function */
#define	SE_ALIGN(x)	((((ulong_t)x) + 7ul) & ~7ul)

/* Access to unpacked attribute list */
#define	SE_ATTR_PTR(ev)		(SYSEVENT_IMPL(ev)->seh_attr_off)

/* Offset to packed attribute data */
#define	SE_ATTR_OFF(ev)	SE_PUB_OFF(ev) + SE_ALIGN(strlen(SE_PUB_NAME(ev)) + 1)

/* syseventd door */
#define	LOGEVENT_DOOR_UPCALL	"/var/run/sysevent_door"

/*
 * door upcall data structures
 */
typedef struct log_event_upcall_arg {
	int32_t retcode;
	int32_t	pad;
	sysevent_impl_t buf;
} log_event_upcall_arg_t;

typedef struct log_eventq {
	struct log_eventq	*next;
	log_event_upcall_arg_t	arg;
} log_eventq_t;

/* Syseventd Channel structures */

#define	MAX_CHAN	256	/* Maximum channels per system */
#define	MAX_SUBSCRIBERS	100	/* Maximum subscribers per channel */
#define	MAX_PUBLISHERS	1	/* Maximum publishers per channel */

/*
 * Channel-based subscription structures
 */

/* Class hashing defines */
#define	CLASS_HASH_SZ	63
#define	CLASS_HASH(class_name)	((hash_func(class_name) \
				% CLASS_HASH_SZ) + 1)
#define	CHAN_HASH_SZ	32

typedef struct subclass_lst {
	struct subclass_lst	*sl_next;
	char			*sl_name;
	uchar_t			sl_num[MAX_SUBSCRIBERS + 1];
} subclass_lst_t;

typedef struct class_lst {
	struct class_lst	*cl_next;
	char			*cl_name;
	struct subclass_lst	*cl_subclass_list;
} class_lst_t;

/* User/Kernel Structure to pass event registration modctl data */
typedef struct se_pubsub {
	uint32_t	ps_buflen;
	uint32_t	ps_channel_name_len;
	uint32_t	ps_id;
	uint32_t	ps_op;
	uint32_t	ps_type;
} se_pubsub_t;

/* op defines */
#define	SE_REGISTER		0
#define	SE_UNREGISTER		1
#define	SE_CLEANUP		2
#define	SE_OPEN_REGISTRATION	3
#define	SE_CLOSE_REGISTRATION	4
#define	SE_BIND_REGISTRATION	5
#define	SE_UNBIND_REGISTRATION	6
#define	SE_GET_REGISTRATION	7

/* type defines */
#define	SUBSCRIBER	0
#define	PUBLISHER	1

/* nvpair names */
#define	CLASS_NAME	"class"

#ifdef	_KERNEL

typedef struct sysevent_channel_descriptor {
	char   *scd_channel_name;	/* Name of channel */
	struct sysevent_channel_descriptor *scd_next;
	int    scd_ref_cnt;		/* Reference count of channel opens */
	id_space_t *scd_subscriber_cache;	/* cache of subscriber ids */
	id_space_t *scd_publisher_cache;	/* cache of publisher ids */
	uchar_t scd_subscriber_ids[MAX_SUBSCRIBERS + 1]; /* used sub ids */
	uchar_t scd_publisher_ids[MAX_PUBLISHERS + 1];	/* used  pub ids */
	class_lst_t *scd_class_list_tbl[CLASS_HASH_SZ + 1];
} sysevent_channel_descriptor_t;

/*
 * log_sysevent private interfaces
 */
extern void log_event_init(void);
extern void log_sysevent_flushq(int, uint_t);
extern int log_sysevent_filename(char *);
extern int log_usr_sysevent(sysevent_t *, int, sysevent_id_t *);
extern int log_sysevent_copyout_data(sysevent_id_t *, size_t, caddr_t);
extern int log_sysevent_free_data(sysevent_id_t *);
extern int log_sysevent_register(char *, char *, se_pubsub_t *);
extern uint64_t log_sysevent_new_id(void);

/*
 * Structures and definitions for general purpose event channels
 */

/* Limits */
#define	EVCH_MAX_CHANNELS		1024
#define	EVCH_MAX_BINDS_PER_CHANNEL	512
#define	EVCH_MAX_SUBSCRIPTIONS		32
#define	EVCH_SUBPOOLFACT		8
#define	EVCH_DEFAULT_EVENTS		2000
#define	EVCH_MAX_TRY_DELIVERY		3

/* Linkage element for evch_dlist_t lists */
typedef struct evch_dlelem {
	struct evch_dlelem	*dl_next;
	struct evch_dlelem	*dl_prev;
} evch_dlelem_t;

/* List head */
typedef struct {
	evch_dlelem_t	dh_head;
	int		dh_count;
} evch_dlist_t;

/* Placeholder for elements in a evch_squeue_t queue */
typedef struct evch_qelem {
	struct evch_qelem	*q_next;
	void			*q_objref;
	size_t			q_objsize;
} evch_qelem_t;

/* Queue head data */
typedef struct {
	evch_qelem_t	*sq_head;
	evch_qelem_t	*sq_tail;
	uint32_t	sq_count;
	uint32_t	sq_highwm;
} evch_squeue_t;

/*
 * Defines for event queue routines
 */
#define	EVQ_IGNORE	1
#define	EVQ_DELIVER	2

#define	EVQ_CONT	0
#define	EVQ_AGAIN	1
#define	EVQ_SLEEP	2

/* Call back routine typedefs */
typedef int (*filter_f)(void *, void *);
typedef int (*deliver_f)(void *, void *);
typedef int (*kerndlv_f)(void *, void *);
typedef void (*destr_f)(void *, void *);
typedef int (*compare_f)(evch_dlelem_t *, char *);

/*
 * Event structure handled by evch_evq_* functions. Sysevent type events are
 * stored as the payload.
 */
typedef struct {
	uint32_t	ge_size;	/* Total size of event structure */
	uint32_t	ge_refcount;	/* No of queues event is linked to */
	destr_f		ge_destruct;	/* Destructor for event structure */
	uint32_t	*ge_dstcookie;	/* Cookie for destructor function */
	uchar_t		ge_payload[1];	/* Placeholder for event data */
} evch_gevent_t;

/*
 * Event queue descriptor
 */
typedef struct {
	evch_squeue_t	eq_eventq;	/* Protected by eq_dtmutex */
	kt_did_t	eq_thrid;	/* Id delivery thread */
	kmutex_t	eq_queuemx;	/* Protect. of this struct and ev q */
	kcondvar_t	eq_thrsleepcv;	/* Delivery thread sleeps on empty q */
	int		eq_dactive;	/* Event delivery is in progress */
	kcondvar_t	eq_dactivecv;	/* Unsubscr. has to wait on this */
	evch_dlist_t	eq_subscr;	/* Chain of all evch_evqsub_t */
	uint32_t	eq_nsleep;	/* Statistic: Publisher set to sleep */
	int		eq_holdmode;	/* Hold event delivery */
	evch_gevent_t	*eq_curevent;	/* Event currently beeing delivered */
	evch_qelem_t	*eq_nextev;	/* For iterating over events in a q */
	kcondvar_t	eq_onholdcv;	/* To signal hold mode of deliv. thr. */
	uchar_t		eq_tabortflag;	/* Request to abort delivery thread */
} evch_eventq_t;

/*
 * Event queue per subscriber structure
 */
typedef struct {
	evch_dlelem_t	su_link;
	filter_f	su_filter;	/* Event filter function pointer */
	void		*su_fcookie;	/* cookie for event filter */
	deliver_f	su_callb;	/* Event delivery callback */
	void		*su_cbcookie;	/* callback cookie */
} evch_evqsub_t;

/* Eveny delivery type */
#define	EVCH_DELKERN		1	/* Kernel event delivery */
#define	EVCH_DELDOOR		2	/* User event delivery via doors */

/*
 * Per channel subscriber data structure. Chained in a linked list to an
 * event channel and to a binding.
 */
typedef struct chsubd {
	evch_dlelem_t	sd_link;	/* Links all subscribers of this ch. */
	struct chsubd	*sd_subnxt;	/* Links all subscr. for a binding */
	char		*sd_ident;	/* Subscriber identifier */
	evch_eventq_t	*sd_queue;	/* Event queue for this subscriber */
	evch_evqsub_t	*sd_msub;	/* Main event queue subscr. */
	char		*sd_classname;	/* Filter criteria */
	size_t		sd_clnsize;	/* Size of sd_classname buffer */
	evch_evqsub_t	*sd_ssub;	/* Subscriber queue subscr. */
	int		sd_type;	/* Type of event delivery */
	kerndlv_f	sd_callback;	/* Callback for kernel delivery */
	void		*sd_cbcookie;	/* Cookie for kernel delivery */
	door_handle_t	sd_door;	/* Door handle for user delivery */
	int		sd_active;	/* Subscription is in use indicator */
	pid_t		sd_pid;		/* PID of subscribing process */
	uint8_t		sd_persist;	/* Persistent user land subscription */
	uint8_t		sd_dump;	/* Dump with sysevent_evc_walk_* */
} evch_subd_t;

/*
 * General purpose event channel descriptor structure. This is the main
 * structure for event subscribing, publishing, delivery to/from an event
 * channel.
 */
typedef struct {
	evch_dlelem_t	ch_link;	/* Must be first elem. of structure */
	char		*ch_name;	/* Channel name */
	size_t		ch_namelen;	/* Length of channel name buffer */
	kmutex_t	ch_mutex;	/* To protect this structure */
	evch_eventq_t	*ch_queue;	/* Publisher event queue */
	evch_dlist_t	ch_subscr;	/* List of subscr. data (evch_subd_t) */
	uint32_t	ch_bindings;	/* No of bindings to this channel */
	int		ch_maxbinds;	/* Maximum number of binds */
	uid_t		ch_uid;		/* Creators effective user id */
	gid_t		ch_gid;		/* Creators effective group id */
	kmutex_t	ch_pubmx;	/* Mutex for ch_pubcv and ch_nevents */
	kcondvar_t	ch_pubcv;	/* To set publisher to sleep */
	uint32_t	ch_nevents;	/* Current number of events */
	uint32_t	ch_maxev;	/* Maximum number of events */
	int		ch_maxsubscr;	/* Maximum number of subscriptions */
	int		ch_holdpend;	/* Hold pending events mode if != 0 */
	time_t		ch_ctime;	/* Channel creation time */
	nvlist_t	*ch_propnvl;	/* Channel properties nvlist */
	int64_t		ch_propnvlgen;	/* Properties generation number */
} evch_chan_t;

/*
 * Channel binding structure. Allocated per binding to a channel. Protected
 * by locking the channel structure
 */
typedef struct {
	evch_chan_t	*bd_channel;
	evch_subd_t	*bd_sublst;	/* chain of all subscriptions */
} evch_bind_t;

/*
 * Structure to keep a snapshot of all events of a channel
 */
typedef struct {
	evch_eventq_t	*sn_queue;	/* Event queue with snapshot of ev's */
	sysevent_impl_t	*sn_nxtev;	/* Pointer to find next event */
} evchanq_t;

/* Project private interfaces */
extern evchan_t *evch_usrchanopen(const char *name, uint32_t flags, int *err);
extern void evch_usrchanclose(evchan_t *cbp);
extern sysevent_impl_t *evch_usrallocev(size_t evsize, uint32_t flags);
extern void evch_usrfreeev(sysevent_impl_t *ev);
extern int evch_usrpostevent(evchan_t *bp, sysevent_impl_t *ev, uint32_t flags);
extern int evch_usrsubscribe(evchan_t *bp, const char *sid, const char *class,
    int d, uint32_t flags);
extern int evch_usrcontrol_set(evchan_t *bp, int cmd, uint32_t value);
extern int evch_usrcontrol_get(evchan_t *bp, int cmd, uint32_t *value);
extern void evch_usrunsubscribe(evchan_t *bp, const char *subid, uint32_t flag);
extern int evch_usrgetchnames(char *buf, size_t size);
extern int evch_usrgetchdata(char *chname, void *buf, size_t size);
extern void evch_usrsetpropnvl(evchan_t *bp, nvlist_t *nvl);
extern int evch_usrgetpropnvl(evchan_t *bp, nvlist_t **nvlp, int64_t *genp);

extern void sysevent_evc_init();
extern void sysevent_evc_thrinit();
extern evchanq_t *sysevent_evc_walk_init(evchan_t *, char *);
extern sysevent_t *sysevent_evc_walk_step(evchanq_t *);
extern void sysevent_evc_walk_fini(evchanq_t *);
extern char *sysevent_evc_event_attr(sysevent_t *, size_t *);

#endif /* _KERNEL */

/*
 * Structures and limits to deliver channel data to syseventadm
 */
#define	EVCH_MAX_DATA_SIZE	(1024 * 1024)

typedef struct {
	uint32_t	sb_nextoff;	/* Offset to next subscr info struct */
	uint32_t	sb_stroff;	/* Offset to strings */
	uint32_t	sb_clnamoff;	/* Offset of class in sb_strings */
	uint32_t	sb_pid;		/* Subscriber process id */
	uint32_t	sb_nevents;	/* Current no of event in sub q */
	uint32_t	sb_evhwm;	/* High watermark of sub q */
	uint32_t	sb_persist;	/* != 0 if subscription persists */
	uint32_t	sb_status;	/* != 0 if subscription is inactive */
	uint32_t	sb_active;	/* > 0 if subscription is in use */
	uint32_t	sb_dump;	/* != 0 if sub will be dumped */
	char		sb_strings[1];	/* String space for subid and class */
} sev_subinfo_t;

typedef struct {
	uint32_t	cd_version;	/* Version of this structure */
	uint32_t	cd_suboffs;	/* Offset of subscriber info struct */
	uint64_t	cd_ctime;	/* Creation time */
	uint32_t	cd_uid;		/* User id */
	uint32_t	cd_gid;		/* Owner group id */
	uint32_t	cd_perms;	/* Permission bits */
	uint32_t	cd_maxev;	/* Max number of events */
	uint32_t	cd_evhwm;	/* High watermark of main event queue */
	uint32_t	cd_nevents;	/* current no of events in main ev q */
	uint32_t	cd_maxsub;	/* Max number of subscriptions */
	uint32_t	cd_nsub;	/* Current number of subscriptions */
	uint32_t	cd_maxbinds;	/* Max number of binds */
	uint32_t	cd_nbinds;	/* Current number of binds */
	uint32_t	cd_holdpend;	/* != 0 when HOLDPEND mode is set */
	uint32_t	cd_limev;	/* Limit of events per channel */
	sev_subinfo_t	cd_subinfo[1];	/* Per subscriber data */
} sev_chinfo_t;

/*
 * Project private flags for sysevent_evc_subscribe. Bits 0 to 7 are reserved
 * for the consolidation private interface, so we must use bits 8-15 here.
 */
#define	EVCH_SUB_DUMP		(0x01 << 8)

/*
 * Permission flags
 */
#define	EVCH_PUB		0x0004	/* wants to publish events */
#define	EVCH_SUB		0x0008	/* wants to subscribe to channel */

#define	EVCH_SUBU		0x0001	/* Subscribing allowed for uid */
#define	EVCH_PUBU		0x0002	/* Publishing allowed for uid */
#define	EVCH_PSUSR		0x0003	/* EVCH_SUBU + EVCH_PUBU */
#define	EVCH_SUBG		0x0004	/* Subscribing allowed for gid */
#define	EVCH_PUBG		0x0008	/* Publishing allowed for gid */
#define	EVCH_PSGRP		0x000C	/* EVCH_SUBG + EVCH_PUBG */
#define	EVCH_SUBO		0x0010	/* Subscribing allowed to all users */
#define	EVCH_PUBO		0x0020	/* Publishing allowed to all users */
#define	EVCH_PSOTH		0x0030	/* EVCH_SUBO + EVCH_PUBO */
#define	EVCH_PSALL		0x003f	/* Mask of all permission bits */

/*
 * Sysevent driver ioctls
 */
#define	SEV_BASE		0x53455600
#define	SEV_PUBLISH		SEV_BASE | 0x01
#define	SEV_CHAN_OPEN		SEV_BASE | 0x02
#define	SEV_CHAN_CONTROL	SEV_BASE | 0x03
#define	SEV_SUBSCRIBE		SEV_BASE | 0x04
#define	SEV_UNSUBSCRIBE		SEV_BASE | 0x05
#define	SEV_CHANNAMES		SEV_BASE | 0x06
#define	SEV_CHANDATA		SEV_BASE | 0x07
#define	SEV_SETPROPNVL		SEV_BASE | 0x08
#define	SEV_GETPROPNVL		SEV_BASE | 0x09

#define	DEVSYSEVENT	"/dev/sysevent"
#define	DEVICESYSEVENT	"/devices/pseudo/sysevent@0:sysevent"

/*
 * Maximum allowed binding handles
 * It's a limit required by bitmap algorithm design (see sys/bitmap.h).
 * Use pack(4) to make sizeof structs be the same on x86 and amd64.
 */
#define	SYSEVENT_MINOR_MAX	SHRT_MAX

#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack(4)
#endif

/* copyin/copyout data */
typedef struct box {
	uint64_t name;		/* pointer to something */
	uint32_t len;
} sev_box_t;

typedef struct bind_args {
	sev_box_t chan_name;
	uint32_t flags;
} sev_bind_args_t;

typedef struct control_args {
	uint32_t cmd;
	uint32_t value;
} sev_control_args_t;

typedef struct publish_args {
	sev_box_t ev;
	uint32_t flags;
} sev_publish_args_t;

typedef struct subscribe_args {
	sev_box_t sid;
	sev_box_t class_info;
	int door_desc;
	uint32_t flags;
} sev_subscribe_args_t;

typedef struct unsubscribe_args {
	sev_box_t sid;
} sev_unsubscribe_args_t;

typedef struct chandata {
	sev_box_t in_data;
	sev_box_t out_data;
} sev_chandata_args_t;

typedef struct propnvl_args {
	sev_box_t packednvl;	/* input and output */
	int64_t generation;	/* output on get operation */
} sev_propnvl_args_t;

#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack()
#endif

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_SYSEVENT_IMPL_H */