aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2013-08-13 03:07:49 +0000
committerMark Johnston <markj@FreeBSD.org>2013-08-13 03:07:49 +0000
commitc9b645b50be5adebc3bd7927726af474caea6098 (patch)
treedcad89fb8dcad3f906701c32834969307169d079
parentc77936e7e54dba25809a0cbed7e13559f6101bef (diff)
downloadsrc-c9b645b50be5adebc3bd7927726af474caea6098.tar.gz
src-c9b645b50be5adebc3bd7927726af474caea6098.zip
Add event handlers for module load and unload events. The load handlers are
called after the module has been loaded, and the unload handlers are called before the module is unloaded. Moreover, the module unload handlers may return an error to prevent the unload from proceeding. Reviewed by: avg MFC after: 2 weeks
Notes
Notes: svn path=/head/; revision=254266
-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 */