Date: Thu, 19 Dec 2013 03:48:36 +0000 (UTC) From: Mark Johnston <markj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r259587 - head/sys/kern Message-ID: <201312190348.rBJ3magP020349@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: markj Date: Thu Dec 19 03:48:36 2013 New Revision: 259587 URL: http://svnweb.freebsd.org/changeset/base/259587 Log: Invoke the kld_* event handlers from linker_load_file() and linker_unload_file() rather than kern_kldload() and kern_kldunload(). This ensures that the handlers are invoked for files that are loaded/unloaded automatically as dependencies. Previously, they were only invoked for files loaded by a user. As a side effect, the kld_load and kld_unload handlers are now invoked with the kernel linker lock exclusively held. Reported by: avg Reviewed by: jhb MFC after: 2 weeks Modified: head/sys/kern/kern_linker.c Modified: head/sys/kern/kern_linker.c ============================================================================== --- head/sys/kern/kern_linker.c Thu Dec 19 03:21:53 2013 (r259586) +++ head/sys/kern/kern_linker.c Thu Dec 19 03:48:36 2013 (r259587) @@ -434,6 +434,7 @@ linker_load_file(const char *filename, l 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, i 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, i } 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 ch 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 fi 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 fi " 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 fi } } 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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201312190348.rBJ3magP020349>