diff options
-rw-r--r-- | share/man/man9/EVENTHANDLER.9 | 8 | ||||
-rw-r--r-- | sys/kern/kern_linker.c | 10 | ||||
-rw-r--r-- | sys/sys/eventhandler.h | 7 |
3 files changed, 22 insertions, 3 deletions
diff --git a/share/man/man9/EVENTHANDLER.9 b/share/man/man9/EVENTHANDLER.9 index 4a1666087c9b..ee015cd7909e 100644 --- a/share/man/man9/EVENTHANDLER.9 +++ b/share/man/man9/EVENTHANDLER.9 @@ -23,7 +23,7 @@ .\" SUCH DAMAGE. .\" $FreeBSD$ .\" -.Dd May 11, 2012 +.Dd August 1, 2013 .Dt EVENTHANDLER 9 .Os .Sh NAME @@ -199,6 +199,12 @@ Callbacks invoked when a new network interface appears. Callbacks invoked when a network interface is taken down. .It Vt bpf_track Callbacks invoked when a BPF listener attaches to/detaches from network interface. +.It Vt mod_load +Callbacks invoked after a module has been loaded. +.It Vt mod_unload +Callbacks invoked before a module is about to be unloaded. +These callbacks may be used to return an error and prevent the unload from +proceeding. .It Vt power_profile_change Callbacks invoked when the power profile of the system changes. .It Vt process_exec diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index b3ab4df35a27..883752b613d1 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/mount.h> #include <sys/linker.h> +#include <sys/eventhandler.h> #include <sys/fcntl.h> #include <sys/jail.h> #include <sys/libkern.h> @@ -1046,6 +1047,9 @@ kern_kldload(struct thread *td, const char *file, int *fileid) lf->userrefs++; if (fileid != NULL) *fileid = lf->id; + + EVENTHANDLER_INVOKE(mod_load, lf); + #ifdef HWPMC_HOOKS KLD_DOWNGRADE(); pkm.pm_file = lf->filename; @@ -1101,8 +1105,10 @@ kern_kldunload(struct thread *td, int fileid, int flags) if (lf) { KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs)); - /* Check if there are DTrace probes enabled on this file. */ - if (lf->nenabled > 0) { + EVENTHANDLER_INVOKE(mod_unload, lf, &error); + if (error != 0) + error = EBUSY; + else if (lf->nenabled > 0) { printf("kldunload: attempt to unload file that has" " DTrace probes enabled\n"); error = EBUSY; diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h index 02fbeaa816d1..7e1eee2ecd00 100644 --- a/sys/sys/eventhandler.h +++ b/sys/sys/eventhandler.h @@ -266,4 +266,11 @@ EVENTHANDLER_DECLARE(nmbclusters_change, uma_zone_chfn); EVENTHANDLER_DECLARE(nmbufs_change, uma_zone_chfn); EVENTHANDLER_DECLARE(maxsockets_change, uma_zone_chfn); +/* Module load and unload events */ +struct linker_file; +typedef void (*mod_load_fn)(void *, struct linker_file *); +typedef void (*mod_unload_fn)(void *, struct linker_file *, int *); +EVENTHANDLER_DECLARE(mod_load, mod_load_fn); +EVENTHANDLER_DECLARE(mod_unload, mod_unload_fn); + #endif /* SYS_EVENTHANDLER_H */ |