eventhandler.h revision 307253
1/*- 2 * Copyright (c) 1999 Michael Smith <msmith@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: stable/10/sys/sys/eventhandler.h 307253 2016-10-14 03:11:31Z sephe $ 27 */ 28 29#ifndef SYS_EVENTHANDLER_H 30#define SYS_EVENTHANDLER_H 31 32#include <sys/lock.h> 33#include <sys/ktr.h> 34#include <sys/mutex.h> 35#include <sys/queue.h> 36 37struct eventhandler_entry { 38 TAILQ_ENTRY(eventhandler_entry) ee_link; 39 int ee_priority; 40#define EHE_DEAD_PRIORITY (-1) 41 void *ee_arg; 42}; 43 44#ifdef VIMAGE 45struct eventhandler_entry_vimage { 46 void (* func)(void); /* Original function registered. */ 47 void *ee_arg; /* Original argument registered. */ 48 void *sparep[2]; 49}; 50#endif 51 52struct eventhandler_list { 53 char *el_name; 54 int el_flags; 55#define EHL_INITTED (1<<0) 56 u_int el_runcount; 57 struct mtx el_lock; 58 TAILQ_ENTRY(eventhandler_list) el_link; 59 TAILQ_HEAD(,eventhandler_entry) el_entries; 60}; 61 62typedef struct eventhandler_entry *eventhandler_tag; 63 64#define EHL_LOCK(p) mtx_lock(&(p)->el_lock) 65#define EHL_UNLOCK(p) mtx_unlock(&(p)->el_lock) 66#define EHL_LOCK_ASSERT(p, x) mtx_assert(&(p)->el_lock, x) 67 68/* 69 * Macro to invoke the handlers for a given event. 70 */ 71#define _EVENTHANDLER_INVOKE(name, list, ...) do { \ 72 struct eventhandler_entry *_ep; \ 73 struct eventhandler_entry_ ## name *_t; \ 74 \ 75 KASSERT((list)->el_flags & EHL_INITTED, \ 76 ("eventhandler_invoke: running non-inited list")); \ 77 EHL_LOCK_ASSERT((list), MA_OWNED); \ 78 (list)->el_runcount++; \ 79 KASSERT((list)->el_runcount > 0, \ 80 ("eventhandler_invoke: runcount overflow")); \ 81 CTR0(KTR_EVH, "eventhandler_invoke(\"" __STRING(name) "\")"); \ 82 TAILQ_FOREACH(_ep, &((list)->el_entries), ee_link) { \ 83 if (_ep->ee_priority != EHE_DEAD_PRIORITY) { \ 84 EHL_UNLOCK((list)); \ 85 _t = (struct eventhandler_entry_ ## name *)_ep; \ 86 CTR1(KTR_EVH, "eventhandler_invoke: executing %p", \ 87 (void *)_t->eh_func); \ 88 _t->eh_func(_ep->ee_arg , ## __VA_ARGS__); \ 89 EHL_LOCK((list)); \ 90 } \ 91 } \ 92 KASSERT((list)->el_runcount > 0, \ 93 ("eventhandler_invoke: runcount underflow")); \ 94 (list)->el_runcount--; \ 95 if ((list)->el_runcount == 0) \ 96 eventhandler_prune_list(list); \ 97 EHL_UNLOCK((list)); \ 98} while (0) 99 100/* 101 * Slow handlers are entirely dynamic; lists are created 102 * when entries are added to them, and thus have no concept of "owner", 103 * 104 * Slow handlers need to be declared, but do not need to be defined. The 105 * declaration must be in scope wherever the handler is to be invoked. 106 */ 107#define EVENTHANDLER_DECLARE(name, type) \ 108struct eventhandler_entry_ ## name \ 109{ \ 110 struct eventhandler_entry ee; \ 111 type eh_func; \ 112}; \ 113struct __hack 114 115#define EVENTHANDLER_DEFINE(name, func, arg, priority) \ 116 static eventhandler_tag name ## _tag; \ 117 static void name ## _evh_init(void *ctx) \ 118 { \ 119 name ## _tag = EVENTHANDLER_REGISTER(name, func, ctx, \ 120 priority); \ 121 } \ 122 SYSINIT(name ## _evh_init, SI_SUB_CONFIGURE, SI_ORDER_ANY, \ 123 name ## _evh_init, arg); \ 124 struct __hack 125 126#define EVENTHANDLER_INVOKE(name, ...) \ 127do { \ 128 struct eventhandler_list *_el; \ 129 \ 130 if ((_el = eventhandler_find_list(#name)) != NULL) \ 131 _EVENTHANDLER_INVOKE(name, _el , ## __VA_ARGS__); \ 132} while (0) 133 134#define EVENTHANDLER_REGISTER(name, func, arg, priority) \ 135 eventhandler_register(NULL, #name, func, arg, priority) 136 137#define EVENTHANDLER_DEREGISTER(name, tag) \ 138do { \ 139 struct eventhandler_list *_el; \ 140 \ 141 if ((_el = eventhandler_find_list(#name)) != NULL) \ 142 eventhandler_deregister(_el, tag); \ 143} while(0) 144 145 146eventhandler_tag eventhandler_register(struct eventhandler_list *list, 147 const char *name, void *func, void *arg, int priority); 148void eventhandler_deregister(struct eventhandler_list *list, 149 eventhandler_tag tag); 150struct eventhandler_list *eventhandler_find_list(const char *name); 151void eventhandler_prune_list(struct eventhandler_list *list); 152 153#ifdef VIMAGE 154typedef void (*vimage_iterator_func_t)(void *, ...); 155 156eventhandler_tag vimage_eventhandler_register(struct eventhandler_list *list, 157 const char *name, void *func, void *arg, int priority, 158 vimage_iterator_func_t); 159#endif 160 161/* 162 * Standard system event queues. 163 */ 164 165/* Generic priority levels */ 166#define EVENTHANDLER_PRI_FIRST 0 167#define EVENTHANDLER_PRI_ANY 10000 168#define EVENTHANDLER_PRI_LAST 20000 169 170/* Shutdown events */ 171typedef void (*shutdown_fn)(void *, int); 172 173#define SHUTDOWN_PRI_FIRST EVENTHANDLER_PRI_FIRST 174#define SHUTDOWN_PRI_DEFAULT EVENTHANDLER_PRI_ANY 175#define SHUTDOWN_PRI_LAST EVENTHANDLER_PRI_LAST 176 177EVENTHANDLER_DECLARE(shutdown_pre_sync, shutdown_fn); /* before fs sync */ 178EVENTHANDLER_DECLARE(shutdown_post_sync, shutdown_fn); /* after fs sync */ 179EVENTHANDLER_DECLARE(shutdown_final, shutdown_fn); 180 181/* Power state change events */ 182typedef void (*power_change_fn)(void *); 183EVENTHANDLER_DECLARE(power_resume, power_change_fn); 184EVENTHANDLER_DECLARE(power_suspend, power_change_fn); 185EVENTHANDLER_DECLARE(power_suspend_early, power_change_fn); 186 187/* Low memory event */ 188typedef void (*vm_lowmem_handler_t)(void *, int); 189#define LOWMEM_PRI_DEFAULT EVENTHANDLER_PRI_FIRST 190EVENTHANDLER_DECLARE(vm_lowmem, vm_lowmem_handler_t); 191 192/* Root mounted event */ 193typedef void (*mountroot_handler_t)(void *); 194EVENTHANDLER_DECLARE(mountroot, mountroot_handler_t); 195 196/* File system mount events */ 197struct mount; 198struct vnode; 199struct thread; 200typedef void (*vfs_mounted_notify_fn)(void *, struct mount *, struct vnode *, 201 struct thread *); 202typedef void (*vfs_unmounted_notify_fn)(void *, struct mount *, 203 struct thread *); 204EVENTHANDLER_DECLARE(vfs_mounted, vfs_mounted_notify_fn); 205EVENTHANDLER_DECLARE(vfs_unmounted, vfs_unmounted_notify_fn); 206 207/* VLAN state change events */ 208struct ifnet; 209typedef void (*vlan_config_fn)(void *, struct ifnet *, uint16_t); 210typedef void (*vlan_unconfig_fn)(void *, struct ifnet *, uint16_t); 211EVENTHANDLER_DECLARE(vlan_config, vlan_config_fn); 212EVENTHANDLER_DECLARE(vlan_unconfig, vlan_unconfig_fn); 213 214/* BPF attach/detach events */ 215struct ifnet; 216typedef void (*bpf_track_fn)(void *, struct ifnet *, int /* dlt */, 217 int /* 1 =>'s attach */); 218EVENTHANDLER_DECLARE(bpf_track, bpf_track_fn); 219 220/* 221 * Process events 222 * process_fork and exit handlers are called without Giant. 223 * exec handlers are called with Giant, but that is by accident. 224 */ 225struct proc; 226struct image_params; 227 228typedef void (*exitlist_fn)(void *, struct proc *); 229typedef void (*forklist_fn)(void *, struct proc *, struct proc *, int); 230typedef void (*execlist_fn)(void *, struct proc *, struct image_params *); 231typedef void (*proc_ctor_fn)(void *, struct proc *); 232typedef void (*proc_dtor_fn)(void *, struct proc *); 233typedef void (*proc_init_fn)(void *, struct proc *); 234typedef void (*proc_fini_fn)(void *, struct proc *); 235EVENTHANDLER_DECLARE(process_ctor, proc_ctor_fn); 236EVENTHANDLER_DECLARE(process_dtor, proc_dtor_fn); 237EVENTHANDLER_DECLARE(process_init, proc_init_fn); 238EVENTHANDLER_DECLARE(process_fini, proc_fini_fn); 239EVENTHANDLER_DECLARE(process_exit, exitlist_fn); 240EVENTHANDLER_DECLARE(process_fork, forklist_fn); 241EVENTHANDLER_DECLARE(process_exec, execlist_fn); 242 243/* 244 * application dump event 245 */ 246typedef void (*app_coredump_start_fn)(void *, struct thread *, char *name); 247typedef void (*app_coredump_progress_fn)(void *, struct thread *td, int byte_count); 248typedef void (*app_coredump_finish_fn)(void *, struct thread *td); 249typedef void (*app_coredump_error_fn)(void *, struct thread *td, char *msg, ...); 250 251EVENTHANDLER_DECLARE(app_coredump_start, app_coredump_start_fn); 252EVENTHANDLER_DECLARE(app_coredump_progress, app_coredump_progress_fn); 253EVENTHANDLER_DECLARE(app_coredump_finish, app_coredump_finish_fn); 254EVENTHANDLER_DECLARE(app_coredump_error, app_coredump_error_fn); 255 256typedef void (*thread_ctor_fn)(void *, struct thread *); 257typedef void (*thread_dtor_fn)(void *, struct thread *); 258typedef void (*thread_fini_fn)(void *, struct thread *); 259typedef void (*thread_init_fn)(void *, struct thread *); 260EVENTHANDLER_DECLARE(thread_ctor, thread_ctor_fn); 261EVENTHANDLER_DECLARE(thread_dtor, thread_dtor_fn); 262EVENTHANDLER_DECLARE(thread_init, thread_init_fn); 263EVENTHANDLER_DECLARE(thread_fini, thread_fini_fn); 264 265typedef void (*uma_zone_chfn)(void *); 266EVENTHANDLER_DECLARE(nmbclusters_change, uma_zone_chfn); 267EVENTHANDLER_DECLARE(nmbufs_change, uma_zone_chfn); 268EVENTHANDLER_DECLARE(maxsockets_change, uma_zone_chfn); 269 270/* Kernel linker file load and unload events */ 271struct linker_file; 272typedef void (*kld_load_fn)(void *, struct linker_file *); 273typedef void (*kld_unload_fn)(void *, const char *, caddr_t, size_t); 274typedef void (*kld_unload_try_fn)(void *, struct linker_file *, int *); 275EVENTHANDLER_DECLARE(kld_load, kld_load_fn); 276EVENTHANDLER_DECLARE(kld_unload, kld_unload_fn); 277EVENTHANDLER_DECLARE(kld_unload_try, kld_unload_try_fn); 278 279/* Generic graphics framebuffer interface */ 280struct fb_info; 281typedef void (*register_framebuffer_fn)(void *, struct fb_info *); 282typedef void (*unregister_framebuffer_fn)(void *, struct fb_info *); 283EVENTHANDLER_DECLARE(register_framebuffer, register_framebuffer_fn); 284EVENTHANDLER_DECLARE(unregister_framebuffer, unregister_framebuffer_fn); 285 286/* Veto ada attachment */ 287struct cam_path; 288struct ata_params; 289typedef void (*ada_probe_veto_fn)(void *, struct cam_path *, 290 struct ata_params *, int *); 291EVENTHANDLER_DECLARE(ada_probe_veto, ada_probe_veto_fn); 292 293#endif /* SYS_EVENTHANDLER_H */ 294