diff options
author | avg <avg@FreeBSD.org> | 2014-02-17 12:45:35 +0000 |
---|---|---|
committer | avg <avg@FreeBSD.org> | 2014-02-17 12:45:35 +0000 |
commit | 8fc9b71c182955a02d9e27d7d251b29970ad489f (patch) | |
tree | 2c328b9e40e967f770a130b7c66dfd94e8e50466 /sys/kern/kern_linker.c | |
parent | 3d0e3b0c687508a344a27f4ddd94dceb2e2ca5df (diff) | |
download | FreeBSD-src-8fc9b71c182955a02d9e27d7d251b29970ad489f.zip FreeBSD-src-8fc9b71c182955a02d9e27d7d251b29970ad489f.tar.gz |
MFC r259587: Invoke the kld_* event handlers from linker_load_file() ...
Diffstat (limited to 'sys/kern/kern_linker.c')
-rw-r--r-- | sys/kern/kern_linker.c | 38 |
1 files changed, 14 insertions, 24 deletions
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 7d32260..fa09b3f 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -434,6 +434,7 @@ linker_load_file(const char *filename, linker_file_t *result) linker_file_unload(lf, LINKER_UNLOAD_FORCE); return (ENOEXEC); } + EVENTHANDLER_INVOKE(kld_load, lf); *result = lf; return (0); } @@ -609,6 +610,12 @@ linker_file_unload(linker_file_t file, int flags) return (0); } + /* Give eventhandlers a chance to prevent the unload. */ + error = 0; + EVENTHANDLER_INVOKE(kld_unload_try, file, &error); + if (error != 0) + return (EBUSY); + KLD_DPF(FILE, ("linker_file_unload: file is unloading," " informing modules\n")); @@ -690,6 +697,10 @@ linker_file_unload(linker_file_t file, int flags) } LINKER_UNLOAD(file); + + EVENTHANDLER_INVOKE(kld_unload, file->filename, file->address, + file->size); + if (file->filename) { free(file->filename, M_LINKER); file->filename = NULL; @@ -1033,10 +1044,7 @@ kern_kldload(struct thread *td, const char *file, int *fileid) lf->userrefs++; if (fileid != NULL) *fileid = lf->id; - - sx_downgrade(&kld_sx); - EVENTHANDLER_INVOKE(kld_load, lf); - sx_sunlock(&kld_sx); + sx_xunlock(&kld_sx); done: CURVNET_RESTORE(); @@ -1066,9 +1074,6 @@ int kern_kldunload(struct thread *td, int fileid, int flags) { linker_file_t lf; - char *filename = NULL; - caddr_t address; - size_t size; int error = 0; if ((error = securelevel_gt(td->td_ucred, 0)) != 0) @@ -1083,10 +1088,7 @@ kern_kldunload(struct thread *td, int fileid, int flags) if (lf) { KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs)); - EVENTHANDLER_INVOKE(kld_unload_try, lf, &error); - if (error != 0) - error = EBUSY; - else if (lf->userrefs == 0) { + if (lf->userrefs == 0) { /* * XXX: maybe LINKER_UNLOAD_FORCE should override ? */ @@ -1094,11 +1096,6 @@ kern_kldunload(struct thread *td, int fileid, int flags) " loaded by the kernel\n"); error = EBUSY; } else { - /* Save data needed for the kld_unload callbacks. */ - filename = strdup(lf->filename, M_TEMP); - address = lf->address; - size = lf->size; - lf->userrefs--; error = linker_file_unload(lf, flags); if (error) @@ -1106,14 +1103,7 @@ kern_kldunload(struct thread *td, int fileid, int flags) } } else error = ENOENT; - - if (error == 0) { - sx_downgrade(&kld_sx); - EVENTHANDLER_INVOKE(kld_unload, filename, address, size); - sx_sunlock(&kld_sx); - } else - sx_xunlock(&kld_sx); - free(filename, M_TEMP); + sx_xunlock(&kld_sx); CURVNET_RESTORE(); return (error); |