17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5c6fc6dddSEric Schrock * Common Development and Distribution License (the "License"). 6c6fc6dddSEric Schrock * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21*f6e214c7SGavin Maltby 227c478bd9Sstevel@tonic-gate /* 23*f6e214c7SGavin Maltby * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #ifndef _SYS_SYSEVENT_IMPL_H 277c478bd9Sstevel@tonic-gate #define _SYS_SYSEVENT_IMPL_H 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <sys/nvpair.h> 307c478bd9Sstevel@tonic-gate #include <sys/id_space.h> 317c478bd9Sstevel@tonic-gate #include <sys/door.h> 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #ifdef __cplusplus 347c478bd9Sstevel@tonic-gate extern "C" { 357c478bd9Sstevel@tonic-gate #endif 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate typedef uint64_t se_data_t; 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate /* 407c478bd9Sstevel@tonic-gate * The following data structure assist in loading and extracting event 417c478bd9Sstevel@tonic-gate * header and attribute data into contiguous memory. Access to all typed 427c478bd9Sstevel@tonic-gate * data done so on 64-bit boundaries. *Do Not* alter any of the structures 437c478bd9Sstevel@tonic-gate * defined below without thorough thought and testing. 447c478bd9Sstevel@tonic-gate */ 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* Attribute name */ 477c478bd9Sstevel@tonic-gate typedef struct se_name { 487c478bd9Sstevel@tonic-gate int32_t name_sz; 497c478bd9Sstevel@tonic-gate int32_t name_pad; 507c478bd9Sstevel@tonic-gate se_data_t name; /* 64-bit aligned offset */ 517c478bd9Sstevel@tonic-gate } se_name_t; 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate /* Attribute value */ 547c478bd9Sstevel@tonic-gate typedef struct se_value { 557c478bd9Sstevel@tonic-gate int32_t value_type; /* data type */ 567c478bd9Sstevel@tonic-gate int32_t value_sz; 577c478bd9Sstevel@tonic-gate se_data_t value; /* data value - 64-bit aligned offset */ 587c478bd9Sstevel@tonic-gate } se_value_t; 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate /* sysevent internal attribute name-value pair stored in contiguous memory */ 617c478bd9Sstevel@tonic-gate typedef struct sysevent_attr_impl { 627c478bd9Sstevel@tonic-gate int32_t se_attr_sz; /* Size of attribute data */ 637c478bd9Sstevel@tonic-gate int32_t se_attr_pad; /* pad */ 647c478bd9Sstevel@tonic-gate se_data_t se_attr_name; /* name of data attribute */ 657c478bd9Sstevel@tonic-gate se_data_t se_attr_val; /* value and type of data */ 667c478bd9Sstevel@tonic-gate } sysevent_attr_impl_t; 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate /* Attribute list states */ 697c478bd9Sstevel@tonic-gate #define ATTR_DETACHED 0 707c478bd9Sstevel@tonic-gate #define ATTR_ATTACHED 1 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate /* 737c478bd9Sstevel@tonic-gate * The following type definitions describe a sysevent object that is 747c478bd9Sstevel@tonic-gate * generated by a call to sysevent_alloc and sent to userland. 757c478bd9Sstevel@tonic-gate */ 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate /* 787c478bd9Sstevel@tonic-gate * sysevent event header information - 79*f6e214c7SGavin Maltby * contained in every event generated. The header and the event 807c478bd9Sstevel@tonic-gate * must remain 64-bit aligned. The header, up to the attribute 817c478bd9Sstevel@tonic-gate * offset, can be contained in a single cache line. 827c478bd9Sstevel@tonic-gate */ 837c478bd9Sstevel@tonic-gate typedef struct sysevent_hdr { 847c478bd9Sstevel@tonic-gate sysevent_id_t se_id; /* unique identifier */ 857c478bd9Sstevel@tonic-gate uint32_t se_version; /* version of this data structure */ 867c478bd9Sstevel@tonic-gate uint32_t se_flag; 877c478bd9Sstevel@tonic-gate uint32_t se_class; /* event class id - reserved */ 887c478bd9Sstevel@tonic-gate uint32_t se_subclass; /* event subclass id - reserved */ 897c478bd9Sstevel@tonic-gate int32_t se_payload_sz; /* size of attr data + strings */ 907c478bd9Sstevel@tonic-gate uint16_t se_subclass_off; /* offset to subclass string */ 917c478bd9Sstevel@tonic-gate uint16_t se_pub_off; /* offset to publisher string */ 927c478bd9Sstevel@tonic-gate uint64_t se_attr_off; /* pointer or offset to attr data */ 937c478bd9Sstevel@tonic-gate } sysevent_hdr_t; 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate /* sysevent event buffer - 64-bit aligned offsets */ 967c478bd9Sstevel@tonic-gate typedef struct sys_event_impl { 977c478bd9Sstevel@tonic-gate sysevent_hdr_t se_header; 987c478bd9Sstevel@tonic-gate se_data_t se_class_name; /* class string in contig memory */ 997c478bd9Sstevel@tonic-gate se_data_t se_subclass_name; /* subclass string in contig memory */ 1007c478bd9Sstevel@tonic-gate se_data_t se_pub; /* publisher string in contig mem */ 101*f6e214c7SGavin Maltby se_data_t se_attr_buf; /* contiguous attribute memory */ 1027c478bd9Sstevel@tonic-gate } sysevent_impl_t; 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate /* Helpful defines */ 1057c478bd9Sstevel@tonic-gate #define seh_version se_header.se_version 1067c478bd9Sstevel@tonic-gate #define seh_class se_header.se_class 1077c478bd9Sstevel@tonic-gate #define seh_subclass se_header.se_subclass 1087c478bd9Sstevel@tonic-gate #define seh_seq se_header.se_id.eid_seq 1097c478bd9Sstevel@tonic-gate #define seh_time se_header.se_id.eid_ts 1107c478bd9Sstevel@tonic-gate #define seh_subclass_off se_header.se_subclass_off 1117c478bd9Sstevel@tonic-gate #define seh_pub_off se_header.se_pub_off 1127c478bd9Sstevel@tonic-gate #define seh_attr_off se_header.se_attr_off 1137c478bd9Sstevel@tonic-gate #define seh_payload_sz se_header.se_payload_sz 1147c478bd9Sstevel@tonic-gate #define seh_flag se_header.se_flag 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate /* Event buffer version */ 1177c478bd9Sstevel@tonic-gate #define SYS_EVENT_VERSION 0 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate /* Event buffer flags */ 1207c478bd9Sstevel@tonic-gate #define SE_PACKED_BUF 1 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate #define SYSEVENT_IMPL(ev) ((sysevent_impl_t *)(void *)(ev)) 1237c478bd9Sstevel@tonic-gate #define SE_VERSION(ev) (SYSEVENT_IMPL(ev)->seh_version) 1247c478bd9Sstevel@tonic-gate #define SE_CLASS(ev) (SYSEVENT_IMPL(ev)->seh_class) 1257c478bd9Sstevel@tonic-gate #define SE_SUBCLASS(ev) (SYSEVENT_IMPL(ev)->seh_subclass) 1267c478bd9Sstevel@tonic-gate #define SE_SEQ(ev) (SYSEVENT_IMPL(ev)->seh_seq) 1277c478bd9Sstevel@tonic-gate #define SE_TIME(ev) (SYSEVENT_IMPL(ev)->seh_time) 1287c478bd9Sstevel@tonic-gate #define SE_SUBCLASS_OFF(ev) (SYSEVENT_IMPL(ev)->seh_subclass_off) 1297c478bd9Sstevel@tonic-gate #define SE_PUB_OFF(ev) (SYSEVENT_IMPL(ev)->seh_pub_off) 1307c478bd9Sstevel@tonic-gate #define SE_PAYLOAD_SZ(ev) (SYSEVENT_IMPL(ev)->seh_payload_sz) 1317c478bd9Sstevel@tonic-gate #define SE_FLAG(ev) (SYSEVENT_IMPL(ev)->seh_flag) 1327c478bd9Sstevel@tonic-gate #define SE_SIZE(ev) (sizeof (sysevent_impl_t) + SE_PAYLOAD_SZ(ev)) 1337c478bd9Sstevel@tonic-gate #define SE_CLASS_NAME(ev) ((char *)&(SYSEVENT_IMPL(ev)->se_class_name)) 1347c478bd9Sstevel@tonic-gate #define SE_SUBCLASS_NAME(ev) ((char *)((caddr_t)(ev) + SE_SUBCLASS_OFF(ev))) 1357c478bd9Sstevel@tonic-gate #define SE_PUB_NAME(ev) ((char *)((caddr_t)(ev) + SE_PUB_OFF(ev))) 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate /* 1387c478bd9Sstevel@tonic-gate * Attribute data can be stored in contiguous memory or 1397c478bd9Sstevel@tonic-gate * as a list of attribute data elements. The storage format is determined 1407c478bd9Sstevel@tonic-gate * by the SE_PACKED_BUF flag in the event buffer flags. 1417c478bd9Sstevel@tonic-gate * 1427c478bd9Sstevel@tonic-gate */ 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate /* 64-bit boundary alignment function */ 1457c478bd9Sstevel@tonic-gate #define SE_ALIGN(x) ((((ulong_t)x) + 7ul) & ~7ul) 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate /* Access to unpacked attribute list */ 1487c478bd9Sstevel@tonic-gate #define SE_ATTR_PTR(ev) (SYSEVENT_IMPL(ev)->seh_attr_off) 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate /* Offset to packed attribute data */ 1517c478bd9Sstevel@tonic-gate #define SE_ATTR_OFF(ev) SE_PUB_OFF(ev) + SE_ALIGN(strlen(SE_PUB_NAME(ev)) + 1) 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate /* syseventd door */ 154c6fc6dddSEric Schrock #define LOGEVENT_DOOR_UPCALL "/var/run/sysevent_door" 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate /* 1577c478bd9Sstevel@tonic-gate * door upcall data structures 1587c478bd9Sstevel@tonic-gate */ 1597c478bd9Sstevel@tonic-gate typedef struct log_event_upcall_arg { 1607c478bd9Sstevel@tonic-gate int32_t retcode; 1617c478bd9Sstevel@tonic-gate int32_t pad; 1627c478bd9Sstevel@tonic-gate sysevent_impl_t buf; 1637c478bd9Sstevel@tonic-gate } log_event_upcall_arg_t; 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate typedef struct log_eventq { 1667c478bd9Sstevel@tonic-gate struct log_eventq *next; 1677c478bd9Sstevel@tonic-gate log_event_upcall_arg_t arg; 1687c478bd9Sstevel@tonic-gate } log_eventq_t; 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate /* Syseventd Channel structures */ 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate #define MAX_CHAN 256 /* Maximum channels per system */ 1737c478bd9Sstevel@tonic-gate #define MAX_SUBSCRIBERS 100 /* Maximum subscribers per channel */ 1747c478bd9Sstevel@tonic-gate #define MAX_PUBLISHERS 1 /* Maximum publishers per channel */ 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate /* 1777c478bd9Sstevel@tonic-gate * Channel-based subscription structures 1787c478bd9Sstevel@tonic-gate */ 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate /* Class hashing defines */ 1817c478bd9Sstevel@tonic-gate #define CLASS_HASH_SZ 63 1827c478bd9Sstevel@tonic-gate #define CLASS_HASH(class_name) ((hash_func(class_name) \ 1837c478bd9Sstevel@tonic-gate % CLASS_HASH_SZ) + 1) 1847c478bd9Sstevel@tonic-gate #define CHAN_HASH_SZ 32 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate typedef struct subclass_lst { 1877c478bd9Sstevel@tonic-gate struct subclass_lst *sl_next; 1887c478bd9Sstevel@tonic-gate char *sl_name; 1897c478bd9Sstevel@tonic-gate uchar_t sl_num[MAX_SUBSCRIBERS + 1]; 1907c478bd9Sstevel@tonic-gate } subclass_lst_t; 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate typedef struct class_lst { 1937c478bd9Sstevel@tonic-gate struct class_lst *cl_next; 1947c478bd9Sstevel@tonic-gate char *cl_name; 1957c478bd9Sstevel@tonic-gate struct subclass_lst *cl_subclass_list; 1967c478bd9Sstevel@tonic-gate } class_lst_t; 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate /* User/Kernel Structure to pass event registration modctl data */ 1997c478bd9Sstevel@tonic-gate typedef struct se_pubsub { 2007c478bd9Sstevel@tonic-gate uint32_t ps_buflen; 2017c478bd9Sstevel@tonic-gate uint32_t ps_channel_name_len; 2027c478bd9Sstevel@tonic-gate uint32_t ps_id; 2037c478bd9Sstevel@tonic-gate uint32_t ps_op; 2047c478bd9Sstevel@tonic-gate uint32_t ps_type; 2057c478bd9Sstevel@tonic-gate } se_pubsub_t; 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate /* op defines */ 2087c478bd9Sstevel@tonic-gate #define SE_REGISTER 0 2097c478bd9Sstevel@tonic-gate #define SE_UNREGISTER 1 2107c478bd9Sstevel@tonic-gate #define SE_CLEANUP 2 2117c478bd9Sstevel@tonic-gate #define SE_OPEN_REGISTRATION 3 2127c478bd9Sstevel@tonic-gate #define SE_CLOSE_REGISTRATION 4 2137c478bd9Sstevel@tonic-gate #define SE_BIND_REGISTRATION 5 2147c478bd9Sstevel@tonic-gate #define SE_UNBIND_REGISTRATION 6 2157c478bd9Sstevel@tonic-gate #define SE_GET_REGISTRATION 7 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate /* type defines */ 2187c478bd9Sstevel@tonic-gate #define SUBSCRIBER 0 2197c478bd9Sstevel@tonic-gate #define PUBLISHER 1 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate /* nvpair names */ 2227c478bd9Sstevel@tonic-gate #define CLASS_NAME "class" 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate #ifdef _KERNEL 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate typedef struct sysevent_channel_descriptor { 2277c478bd9Sstevel@tonic-gate char *scd_channel_name; /* Name of channel */ 2287c478bd9Sstevel@tonic-gate struct sysevent_channel_descriptor *scd_next; 2297c478bd9Sstevel@tonic-gate int scd_ref_cnt; /* Reference count of channel opens */ 2307c478bd9Sstevel@tonic-gate id_space_t *scd_subscriber_cache; /* cache of subscriber ids */ 2317c478bd9Sstevel@tonic-gate id_space_t *scd_publisher_cache; /* cache of publisher ids */ 2327c478bd9Sstevel@tonic-gate uchar_t scd_subscriber_ids[MAX_SUBSCRIBERS + 1]; /* used sub ids */ 2337c478bd9Sstevel@tonic-gate uchar_t scd_publisher_ids[MAX_PUBLISHERS + 1]; /* used pub ids */ 2347c478bd9Sstevel@tonic-gate class_lst_t *scd_class_list_tbl[CLASS_HASH_SZ + 1]; 2357c478bd9Sstevel@tonic-gate } sysevent_channel_descriptor_t; 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate /* 2387c478bd9Sstevel@tonic-gate * log_sysevent private interfaces 2397c478bd9Sstevel@tonic-gate */ 240*f6e214c7SGavin Maltby extern void log_event_init(void); 241*f6e214c7SGavin Maltby extern void log_sysevent_flushq(int, uint_t); 242*f6e214c7SGavin Maltby extern int log_sysevent_filename(char *); 243*f6e214c7SGavin Maltby extern int log_usr_sysevent(sysevent_t *, int, sysevent_id_t *); 244*f6e214c7SGavin Maltby extern int log_sysevent_copyout_data(sysevent_id_t *, size_t, caddr_t); 245*f6e214c7SGavin Maltby extern int log_sysevent_free_data(sysevent_id_t *); 246*f6e214c7SGavin Maltby extern int log_sysevent_register(char *, char *, se_pubsub_t *); 247*f6e214c7SGavin Maltby extern uint64_t log_sysevent_new_id(void); 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate /* 2507c478bd9Sstevel@tonic-gate * Structures and definitions for general purpose event channels 2517c478bd9Sstevel@tonic-gate */ 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate /* Limits */ 2547c478bd9Sstevel@tonic-gate #define EVCH_MAX_CHANNELS 1024 2557c478bd9Sstevel@tonic-gate #define EVCH_MAX_BINDS_PER_CHANNEL 512 2567c478bd9Sstevel@tonic-gate #define EVCH_MAX_SUBSCRIPTIONS 32 2577c478bd9Sstevel@tonic-gate #define EVCH_SUBPOOLFACT 8 2587c478bd9Sstevel@tonic-gate #define EVCH_DEFAULT_EVENTS 2000 2597c478bd9Sstevel@tonic-gate #define EVCH_MAX_TRY_DELIVERY 3 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate /* Linkage element for evch_dlist_t lists */ 2627c478bd9Sstevel@tonic-gate typedef struct evch_dlelem { 2637c478bd9Sstevel@tonic-gate struct evch_dlelem *dl_next; 2647c478bd9Sstevel@tonic-gate struct evch_dlelem *dl_prev; 2657c478bd9Sstevel@tonic-gate } evch_dlelem_t; 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate /* List head */ 2687c478bd9Sstevel@tonic-gate typedef struct { 2697c478bd9Sstevel@tonic-gate evch_dlelem_t dh_head; 2707c478bd9Sstevel@tonic-gate int dh_count; 2717c478bd9Sstevel@tonic-gate } evch_dlist_t; 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate /* Placeholder for elements in a evch_squeue_t queue */ 2747c478bd9Sstevel@tonic-gate typedef struct evch_qelem { 2757c478bd9Sstevel@tonic-gate struct evch_qelem *q_next; 2767c478bd9Sstevel@tonic-gate void *q_objref; 2777c478bd9Sstevel@tonic-gate size_t q_objsize; 2787c478bd9Sstevel@tonic-gate } evch_qelem_t; 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate /* Queue head data */ 2817c478bd9Sstevel@tonic-gate typedef struct { 2827c478bd9Sstevel@tonic-gate evch_qelem_t *sq_head; 2837c478bd9Sstevel@tonic-gate evch_qelem_t *sq_tail; 284*f6e214c7SGavin Maltby uint32_t sq_count; 285*f6e214c7SGavin Maltby uint32_t sq_highwm; 2867c478bd9Sstevel@tonic-gate } evch_squeue_t; 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate /* 2897c478bd9Sstevel@tonic-gate * Defines for event queue routines 2907c478bd9Sstevel@tonic-gate */ 2917c478bd9Sstevel@tonic-gate #define EVQ_IGNORE 1 2927c478bd9Sstevel@tonic-gate #define EVQ_DELIVER 2 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate #define EVQ_CONT 0 2957c478bd9Sstevel@tonic-gate #define EVQ_AGAIN 1 2967c478bd9Sstevel@tonic-gate #define EVQ_SLEEP 2 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate /* Call back routine typedefs */ 2997c478bd9Sstevel@tonic-gate typedef int (*filter_f)(void *, void *); 3007c478bd9Sstevel@tonic-gate typedef int (*deliver_f)(void *, void *); 3017c478bd9Sstevel@tonic-gate typedef int (*kerndlv_f)(void *, void *); 3027c478bd9Sstevel@tonic-gate typedef void (*destr_f)(void *, void *); 3037c478bd9Sstevel@tonic-gate typedef int (*compare_f)(evch_dlelem_t *, char *); 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate /* 3067c478bd9Sstevel@tonic-gate * Event structure handled by evch_evq_* functions. Sysevent type events are 3077c478bd9Sstevel@tonic-gate * stored as the payload. 3087c478bd9Sstevel@tonic-gate */ 3097c478bd9Sstevel@tonic-gate typedef struct { 3107c478bd9Sstevel@tonic-gate uint32_t ge_size; /* Total size of event structure */ 3117c478bd9Sstevel@tonic-gate uint32_t ge_refcount; /* No of queues event is linked to */ 3127c478bd9Sstevel@tonic-gate destr_f ge_destruct; /* Destructor for event structure */ 3137c478bd9Sstevel@tonic-gate uint32_t *ge_dstcookie; /* Cookie for destructor function */ 3147c478bd9Sstevel@tonic-gate uchar_t ge_payload[1]; /* Placeholder for event data */ 3157c478bd9Sstevel@tonic-gate } evch_gevent_t; 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate /* 3187c478bd9Sstevel@tonic-gate * Event queue descriptor 3197c478bd9Sstevel@tonic-gate */ 3207c478bd9Sstevel@tonic-gate typedef struct { 3217c478bd9Sstevel@tonic-gate evch_squeue_t eq_eventq; /* Protected by eq_dtmutex */ 3227c478bd9Sstevel@tonic-gate kt_did_t eq_thrid; /* Id delivery thread */ 3237c478bd9Sstevel@tonic-gate kmutex_t eq_queuemx; /* Protect. of this struct and ev q */ 3247c478bd9Sstevel@tonic-gate kcondvar_t eq_thrsleepcv; /* Delivery thread sleeps on empty q */ 3257c478bd9Sstevel@tonic-gate int eq_dactive; /* Event delivery is in progress */ 3267c478bd9Sstevel@tonic-gate kcondvar_t eq_dactivecv; /* Unsubscr. has to wait on this */ 3277c478bd9Sstevel@tonic-gate evch_dlist_t eq_subscr; /* Chain of all evch_evqsub_t */ 3287c478bd9Sstevel@tonic-gate uint32_t eq_nsleep; /* Statistic: Publisher set to sleep */ 3297c478bd9Sstevel@tonic-gate int eq_holdmode; /* Hold event delivery */ 3307c478bd9Sstevel@tonic-gate evch_gevent_t *eq_curevent; /* Event currently beeing delivered */ 3317c478bd9Sstevel@tonic-gate evch_qelem_t *eq_nextev; /* For iterating over events in a q */ 3327c478bd9Sstevel@tonic-gate kcondvar_t eq_onholdcv; /* To signal hold mode of deliv. thr. */ 3337c478bd9Sstevel@tonic-gate uchar_t eq_tabortflag; /* Request to abort delivery thread */ 3347c478bd9Sstevel@tonic-gate } evch_eventq_t; 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate /* 3377c478bd9Sstevel@tonic-gate * Event queue per subscriber structure 3387c478bd9Sstevel@tonic-gate */ 3397c478bd9Sstevel@tonic-gate typedef struct { 3407c478bd9Sstevel@tonic-gate evch_dlelem_t su_link; 3417c478bd9Sstevel@tonic-gate filter_f su_filter; /* Event filter function pointer */ 3427c478bd9Sstevel@tonic-gate void *su_fcookie; /* cookie for event filter */ 3437c478bd9Sstevel@tonic-gate deliver_f su_callb; /* Event delivery callback */ 3447c478bd9Sstevel@tonic-gate void *su_cbcookie; /* callback cookie */ 3457c478bd9Sstevel@tonic-gate } evch_evqsub_t; 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate /* Eveny delivery type */ 3487c478bd9Sstevel@tonic-gate #define EVCH_DELKERN 1 /* Kernel event delivery */ 3497c478bd9Sstevel@tonic-gate #define EVCH_DELDOOR 2 /* User event delivery via doors */ 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate /* 3527c478bd9Sstevel@tonic-gate * Per channel subscriber data structure. Chained in a linked list to an 3537c478bd9Sstevel@tonic-gate * event channel and to a binding. 3547c478bd9Sstevel@tonic-gate */ 3557c478bd9Sstevel@tonic-gate typedef struct chsubd { 3567c478bd9Sstevel@tonic-gate evch_dlelem_t sd_link; /* Links all subscribers of this ch. */ 3577c478bd9Sstevel@tonic-gate struct chsubd *sd_subnxt; /* Links all subscr. for a binding */ 3587c478bd9Sstevel@tonic-gate char *sd_ident; /* Subscriber identifier */ 3597c478bd9Sstevel@tonic-gate evch_eventq_t *sd_queue; /* Event queue for this subscriber */ 3607c478bd9Sstevel@tonic-gate evch_evqsub_t *sd_msub; /* Main event queue subscr. */ 3617c478bd9Sstevel@tonic-gate char *sd_classname; /* Filter criteria */ 3627c478bd9Sstevel@tonic-gate size_t sd_clnsize; /* Size of sd_classname buffer */ 3637c478bd9Sstevel@tonic-gate evch_evqsub_t *sd_ssub; /* Subscriber queue subscr. */ 3647c478bd9Sstevel@tonic-gate int sd_type; /* Type of event delivery */ 3657c478bd9Sstevel@tonic-gate kerndlv_f sd_callback; /* Callback for kernel delivery */ 3667c478bd9Sstevel@tonic-gate void *sd_cbcookie; /* Cookie for kernel delivery */ 3677c478bd9Sstevel@tonic-gate door_handle_t sd_door; /* Door handle for user delivery */ 3687c478bd9Sstevel@tonic-gate int sd_active; /* Subscription is in use indicator */ 3697c478bd9Sstevel@tonic-gate pid_t sd_pid; /* PID of subscribing process */ 3707c478bd9Sstevel@tonic-gate uint8_t sd_persist; /* Persistent user land subscription */ 3717c478bd9Sstevel@tonic-gate uint8_t sd_dump; /* Dump with sysevent_evc_walk_* */ 3727c478bd9Sstevel@tonic-gate } evch_subd_t; 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate /* 3757c478bd9Sstevel@tonic-gate * General purpose event channel descriptor structure. This is the main 3767c478bd9Sstevel@tonic-gate * structure for event subscribing, publishing, delivery to/from an event 3777c478bd9Sstevel@tonic-gate * channel. 3787c478bd9Sstevel@tonic-gate */ 3797c478bd9Sstevel@tonic-gate typedef struct { 3807c478bd9Sstevel@tonic-gate evch_dlelem_t ch_link; /* Must be first elem. of structure */ 3817c478bd9Sstevel@tonic-gate char *ch_name; /* Channel name */ 3827c478bd9Sstevel@tonic-gate size_t ch_namelen; /* Length of channel name buffer */ 3837c478bd9Sstevel@tonic-gate kmutex_t ch_mutex; /* To protect this structure */ 3847c478bd9Sstevel@tonic-gate evch_eventq_t *ch_queue; /* Publisher event queue */ 3857c478bd9Sstevel@tonic-gate evch_dlist_t ch_subscr; /* List of subscr. data (evch_subd_t) */ 3867c478bd9Sstevel@tonic-gate uint32_t ch_bindings; /* No of bindings to this channel */ 3877c478bd9Sstevel@tonic-gate int ch_maxbinds; /* Maximum number of binds */ 3887c478bd9Sstevel@tonic-gate uid_t ch_uid; /* Creators effective user id */ 3897c478bd9Sstevel@tonic-gate gid_t ch_gid; /* Creators effective group id */ 3907c478bd9Sstevel@tonic-gate kmutex_t ch_pubmx; /* Mutex for ch_pubcv and ch_nevents */ 3917c478bd9Sstevel@tonic-gate kcondvar_t ch_pubcv; /* To set publisher to sleep */ 3927c478bd9Sstevel@tonic-gate uint32_t ch_nevents; /* Current number of events */ 3937c478bd9Sstevel@tonic-gate uint32_t ch_maxev; /* Maximum number of events */ 3947c478bd9Sstevel@tonic-gate int ch_maxsubscr; /* Maximum number of subscriptions */ 3957c478bd9Sstevel@tonic-gate int ch_holdpend; /* Hold pending events mode if != 0 */ 3967c478bd9Sstevel@tonic-gate time_t ch_ctime; /* Channel creation time */ 397*f6e214c7SGavin Maltby nvlist_t *ch_propnvl; /* Channel properties nvlist */ 398*f6e214c7SGavin Maltby int64_t ch_propnvlgen; /* Properties generation number */ 3997c478bd9Sstevel@tonic-gate } evch_chan_t; 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate /* 4027c478bd9Sstevel@tonic-gate * Channel binding structure. Allocated per binding to a channel. Protected 4037c478bd9Sstevel@tonic-gate * by locking the channel structure 4047c478bd9Sstevel@tonic-gate */ 4057c478bd9Sstevel@tonic-gate typedef struct { 4067c478bd9Sstevel@tonic-gate evch_chan_t *bd_channel; 4077c478bd9Sstevel@tonic-gate evch_subd_t *bd_sublst; /* chain of all subscriptions */ 4087c478bd9Sstevel@tonic-gate } evch_bind_t; 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate /* 4117c478bd9Sstevel@tonic-gate * Structure to keep a snapshot of all events of a channel 4127c478bd9Sstevel@tonic-gate */ 4137c478bd9Sstevel@tonic-gate typedef struct { 4147c478bd9Sstevel@tonic-gate evch_eventq_t *sn_queue; /* Event queue with snapshot of ev's */ 4157c478bd9Sstevel@tonic-gate sysevent_impl_t *sn_nxtev; /* Pointer to find next event */ 4167c478bd9Sstevel@tonic-gate } evchanq_t; 4177c478bd9Sstevel@tonic-gate 418*f6e214c7SGavin Maltby /* Project private interfaces */ 419*f6e214c7SGavin Maltby extern evchan_t *evch_usrchanopen(const char *name, uint32_t flags, int *err); 420*f6e214c7SGavin Maltby extern void evch_usrchanclose(evchan_t *cbp); 421*f6e214c7SGavin Maltby extern sysevent_impl_t *evch_usrallocev(size_t evsize, uint32_t flags); 422*f6e214c7SGavin Maltby extern void evch_usrfreeev(sysevent_impl_t *ev); 423*f6e214c7SGavin Maltby extern int evch_usrpostevent(evchan_t *bp, sysevent_impl_t *ev, uint32_t flags); 424*f6e214c7SGavin Maltby extern int evch_usrsubscribe(evchan_t *bp, const char *sid, const char *class, 4257c478bd9Sstevel@tonic-gate int d, uint32_t flags); 426*f6e214c7SGavin Maltby extern int evch_usrcontrol_set(evchan_t *bp, int cmd, uint32_t value); 427*f6e214c7SGavin Maltby extern int evch_usrcontrol_get(evchan_t *bp, int cmd, uint32_t *value); 428*f6e214c7SGavin Maltby extern void evch_usrunsubscribe(evchan_t *bp, const char *subid, uint32_t flag); 429*f6e214c7SGavin Maltby extern int evch_usrgetchnames(char *buf, size_t size); 430*f6e214c7SGavin Maltby extern int evch_usrgetchdata(char *chname, void *buf, size_t size); 431*f6e214c7SGavin Maltby extern void evch_usrsetpropnvl(evchan_t *bp, nvlist_t *nvl); 432*f6e214c7SGavin Maltby extern int evch_usrgetpropnvl(evchan_t *bp, nvlist_t **nvlp, int64_t *genp); 433*f6e214c7SGavin Maltby 434*f6e214c7SGavin Maltby extern void sysevent_evc_init(); 435*f6e214c7SGavin Maltby extern void sysevent_evc_thrinit(); 436*f6e214c7SGavin Maltby extern evchanq_t *sysevent_evc_walk_init(evchan_t *, char *); 437*f6e214c7SGavin Maltby extern sysevent_t *sysevent_evc_walk_step(evchanq_t *); 438*f6e214c7SGavin Maltby extern void sysevent_evc_walk_fini(evchanq_t *); 439*f6e214c7SGavin Maltby extern char *sysevent_evc_event_attr(sysevent_t *, size_t *); 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate /* 4447c478bd9Sstevel@tonic-gate * Structures and limits to deliver channel data to syseventadm 4457c478bd9Sstevel@tonic-gate */ 4467c478bd9Sstevel@tonic-gate #define EVCH_MAX_DATA_SIZE (1024 * 1024) 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate typedef struct { 4497c478bd9Sstevel@tonic-gate uint32_t sb_nextoff; /* Offset to next subscr info struct */ 4507c478bd9Sstevel@tonic-gate uint32_t sb_stroff; /* Offset to strings */ 4517c478bd9Sstevel@tonic-gate uint32_t sb_clnamoff; /* Offset of class in sb_strings */ 4527c478bd9Sstevel@tonic-gate uint32_t sb_pid; /* Subscriber process id */ 4537c478bd9Sstevel@tonic-gate uint32_t sb_nevents; /* Current no of event in sub q */ 4547c478bd9Sstevel@tonic-gate uint32_t sb_evhwm; /* High watermark of sub q */ 4557c478bd9Sstevel@tonic-gate uint32_t sb_persist; /* != 0 if subscription persists */ 4567c478bd9Sstevel@tonic-gate uint32_t sb_status; /* != 0 if subscription is inactive */ 4577c478bd9Sstevel@tonic-gate uint32_t sb_active; /* > 0 if subscription is in use */ 4587c478bd9Sstevel@tonic-gate uint32_t sb_dump; /* != 0 if sub will be dumped */ 4597c478bd9Sstevel@tonic-gate char sb_strings[1]; /* String space for subid and class */ 4607c478bd9Sstevel@tonic-gate } sev_subinfo_t; 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate typedef struct { 4637c478bd9Sstevel@tonic-gate uint32_t cd_version; /* Version of this structure */ 4647c478bd9Sstevel@tonic-gate uint32_t cd_suboffs; /* Offset of subscriber info struct */ 4657c478bd9Sstevel@tonic-gate uint64_t cd_ctime; /* Creation time */ 4667c478bd9Sstevel@tonic-gate uint32_t cd_uid; /* User id */ 4677c478bd9Sstevel@tonic-gate uint32_t cd_gid; /* Owner group id */ 4687c478bd9Sstevel@tonic-gate uint32_t cd_perms; /* Permission bits */ 4697c478bd9Sstevel@tonic-gate uint32_t cd_maxev; /* Max number of events */ 4707c478bd9Sstevel@tonic-gate uint32_t cd_evhwm; /* High watermark of main event queue */ 4717c478bd9Sstevel@tonic-gate uint32_t cd_nevents; /* current no of events in main ev q */ 4727c478bd9Sstevel@tonic-gate uint32_t cd_maxsub; /* Max number of subscriptions */ 4737c478bd9Sstevel@tonic-gate uint32_t cd_nsub; /* Current number of subscriptions */ 4747c478bd9Sstevel@tonic-gate uint32_t cd_maxbinds; /* Max number of binds */ 4757c478bd9Sstevel@tonic-gate uint32_t cd_nbinds; /* Current number of binds */ 4767c478bd9Sstevel@tonic-gate uint32_t cd_holdpend; /* != 0 when HOLDPEND mode is set */ 4777c478bd9Sstevel@tonic-gate uint32_t cd_limev; /* Limit of events per channel */ 4787c478bd9Sstevel@tonic-gate sev_subinfo_t cd_subinfo[1]; /* Per subscriber data */ 4797c478bd9Sstevel@tonic-gate } sev_chinfo_t; 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate /* 4827c478bd9Sstevel@tonic-gate * Project private flags for sysevent_evc_subscribe. Bits 0 to 7 are reserved 48349b225e1SGavin Maltby * for the consolidation private interface, so we must use bits 8-15 here. 4847c478bd9Sstevel@tonic-gate */ 48549b225e1SGavin Maltby #define EVCH_SUB_DUMP (0x01 << 8) 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate /* 4887c478bd9Sstevel@tonic-gate * Permission flags 4897c478bd9Sstevel@tonic-gate */ 4907c478bd9Sstevel@tonic-gate #define EVCH_PUB 0x0004 /* wants to publish events */ 4917c478bd9Sstevel@tonic-gate #define EVCH_SUB 0x0008 /* wants to subscribe to channel */ 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate #define EVCH_SUBU 0x0001 /* Subscribing allowed for uid */ 4947c478bd9Sstevel@tonic-gate #define EVCH_PUBU 0x0002 /* Publishing allowed for uid */ 4957c478bd9Sstevel@tonic-gate #define EVCH_PSUSR 0x0003 /* EVCH_SUBU + EVCH_PUBU */ 4967c478bd9Sstevel@tonic-gate #define EVCH_SUBG 0x0004 /* Subscribing allowed for gid */ 4977c478bd9Sstevel@tonic-gate #define EVCH_PUBG 0x0008 /* Publishing allowed for gid */ 4987c478bd9Sstevel@tonic-gate #define EVCH_PSGRP 0x000C /* EVCH_SUBG + EVCH_PUBG */ 4997c478bd9Sstevel@tonic-gate #define EVCH_SUBO 0x0010 /* Subscribing allowed to all users */ 5007c478bd9Sstevel@tonic-gate #define EVCH_PUBO 0x0020 /* Publishing allowed to all users */ 5017c478bd9Sstevel@tonic-gate #define EVCH_PSOTH 0x0030 /* EVCH_SUBO + EVCH_PUBO */ 5027c478bd9Sstevel@tonic-gate #define EVCH_PSALL 0x003f /* Mask of all permission bits */ 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate /* 5057c478bd9Sstevel@tonic-gate * Sysevent driver ioctls 5067c478bd9Sstevel@tonic-gate */ 5077c478bd9Sstevel@tonic-gate #define SEV_BASE 0x53455600 5087c478bd9Sstevel@tonic-gate #define SEV_PUBLISH SEV_BASE | 0x01 5097c478bd9Sstevel@tonic-gate #define SEV_CHAN_OPEN SEV_BASE | 0x02 5107c478bd9Sstevel@tonic-gate #define SEV_CHAN_CONTROL SEV_BASE | 0x03 5117c478bd9Sstevel@tonic-gate #define SEV_SUBSCRIBE SEV_BASE | 0x04 5127c478bd9Sstevel@tonic-gate #define SEV_UNSUBSCRIBE SEV_BASE | 0x05 5137c478bd9Sstevel@tonic-gate #define SEV_CHANNAMES SEV_BASE | 0x06 5147c478bd9Sstevel@tonic-gate #define SEV_CHANDATA SEV_BASE | 0x07 515*f6e214c7SGavin Maltby #define SEV_SETPROPNVL SEV_BASE | 0x08 516*f6e214c7SGavin Maltby #define SEV_GETPROPNVL SEV_BASE | 0x09 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate #define DEVSYSEVENT "/dev/sysevent" 5197c478bd9Sstevel@tonic-gate #define DEVICESYSEVENT "/devices/pseudo/sysevent@0:sysevent" 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate /* 5227c478bd9Sstevel@tonic-gate * Maximum allowed binding handles 5237c478bd9Sstevel@tonic-gate * It's a limit required by bitmap algorithm design (see sys/bitmap.h). 5247c478bd9Sstevel@tonic-gate * Use pack(4) to make sizeof structs be the same on x86 and amd64. 5257c478bd9Sstevel@tonic-gate */ 5267c478bd9Sstevel@tonic-gate #define SYSEVENT_MINOR_MAX SHRT_MAX 5277c478bd9Sstevel@tonic-gate 5287c478bd9Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 5297c478bd9Sstevel@tonic-gate #pragma pack(4) 5307c478bd9Sstevel@tonic-gate #endif 5317c478bd9Sstevel@tonic-gate 5327c478bd9Sstevel@tonic-gate /* copyin/copyout data */ 5337c478bd9Sstevel@tonic-gate typedef struct box { 5347c478bd9Sstevel@tonic-gate uint64_t name; /* pointer to something */ 5357c478bd9Sstevel@tonic-gate uint32_t len; 5367c478bd9Sstevel@tonic-gate } sev_box_t; 5377c478bd9Sstevel@tonic-gate 5387c478bd9Sstevel@tonic-gate typedef struct bind_args { 5397c478bd9Sstevel@tonic-gate sev_box_t chan_name; 5407c478bd9Sstevel@tonic-gate uint32_t flags; 5417c478bd9Sstevel@tonic-gate } sev_bind_args_t; 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate typedef struct control_args { 5447c478bd9Sstevel@tonic-gate uint32_t cmd; 5457c478bd9Sstevel@tonic-gate uint32_t value; 5467c478bd9Sstevel@tonic-gate } sev_control_args_t; 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate typedef struct publish_args { 5497c478bd9Sstevel@tonic-gate sev_box_t ev; 5507c478bd9Sstevel@tonic-gate uint32_t flags; 5517c478bd9Sstevel@tonic-gate } sev_publish_args_t; 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate typedef struct subscribe_args { 5547c478bd9Sstevel@tonic-gate sev_box_t sid; 5557c478bd9Sstevel@tonic-gate sev_box_t class_info; 5567c478bd9Sstevel@tonic-gate int door_desc; 5577c478bd9Sstevel@tonic-gate uint32_t flags; 5587c478bd9Sstevel@tonic-gate } sev_subscribe_args_t; 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate typedef struct unsubscribe_args { 5617c478bd9Sstevel@tonic-gate sev_box_t sid; 5627c478bd9Sstevel@tonic-gate } sev_unsubscribe_args_t; 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate typedef struct chandata { 5657c478bd9Sstevel@tonic-gate sev_box_t in_data; 5667c478bd9Sstevel@tonic-gate sev_box_t out_data; 5677c478bd9Sstevel@tonic-gate } sev_chandata_args_t; 5687c478bd9Sstevel@tonic-gate 569*f6e214c7SGavin Maltby typedef struct propnvl_args { 570*f6e214c7SGavin Maltby sev_box_t packednvl; /* input and output */ 571*f6e214c7SGavin Maltby int64_t generation; /* output on get operation */ 572*f6e214c7SGavin Maltby } sev_propnvl_args_t; 573*f6e214c7SGavin Maltby 5747c478bd9Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 5757c478bd9Sstevel@tonic-gate #pragma pack() 5767c478bd9Sstevel@tonic-gate #endif 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate #ifdef __cplusplus 5797c478bd9Sstevel@tonic-gate } 5807c478bd9Sstevel@tonic-gate #endif 5817c478bd9Sstevel@tonic-gate 5827c478bd9Sstevel@tonic-gate #endif /* _SYS_SYSEVENT_IMPL_H */ 583