aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/man/man9/EVENTHANDLER.98
-rw-r--r--sys/kern/kern_linker.c10
-rw-r--r--sys/sys/eventhandler.h7
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 */