Date: Thu, 25 May 2006 20:10:59 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 97817 for review Message-ID: <200605252010.k4PKAxqk030690@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=97817 Change 97817 by jhb@jhb_mutex on 2006/05/25 20:10:47 Closer so sanity in the kernel linker: - Split kldload() into kern_kldload() and a simple kldload() wrapper. - Expose kern_kldunload() to the outside world. - Convert VFS, ieee80211, and ng_socket to using kern_kldload() and kern_kldunload() instead of screwing around with linker internals. - Now that linker_load_module() is no longer used, retire it as a public interface and rename linker_load_module_internal() back to linker_load_module(). Affected files ... .. //depot/projects/smpng/sys/kern/kern_linker.c#57 edit .. //depot/projects/smpng/sys/kern/vfs_init.c#22 edit .. //depot/projects/smpng/sys/net80211/ieee80211_freebsd.c#8 edit .. //depot/projects/smpng/sys/netgraph/ng_socket.c#37 edit .. //depot/projects/smpng/sys/sys/linker.h#21 edit .. //depot/projects/smpng/sys/sys/syscallsubr.h#27 edit Differences ... ==== //depot/projects/smpng/sys/kern/kern_linker.c#57 (text+ko) ==== @@ -49,6 +49,7 @@ #include <sys/libkern.h> #include <sys/namei.h> #include <sys/vnode.h> +#include <sys/syscallsubr.h> #include <sys/sysctl.h> #include "linker_if.h" @@ -127,7 +128,7 @@ static caddr_t linker_file_lookup_symbol_internal(linker_file_t file, const char* name, int deps); static int linker_file_unload_internal(linker_file_t _file, int flags); -static int linker_load_module_internal(const char *kldname, +static int linker_load_module(const char *kldname, const char *modname, struct linker_file *parent, struct mod_depend *verinfo, struct linker_file **lfpp); static int linker_lookup_set(linker_file_t file, const char *name, @@ -437,7 +438,7 @@ return (0); } - error = linker_load_module_internal(NULL, modname, NULL, verinfo, + error = linker_load_module(NULL, modname, NULL, verinfo, result); if (!locked) KLD_UNLOCK(); @@ -834,43 +835,36 @@ * MPSAFE */ int -kldload(struct thread *td, struct kldload_args *uap) +kern_kldload(struct thread *td, const char *file, int *fileid) { #ifdef HWPMC_HOOKS struct pmckern_map_in pkm; #endif - char *kldname, *modname; - char *pathname = NULL; + const char *kldname, *modname; linker_file_t lf; - int error = 0; + int error; - td->td_retval[0] = -1; - if ((error = securelevel_gt(td->td_ucred, 0)) != 0) return (error); if ((error = suser(td)) != 0) return (error); - pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); - if ((error = copyinstr(uap->file, pathname, MAXPATHLEN, NULL)) != 0) - goto out; - /* - * If path do not contain qualified name or any dot in it - * (kldname.ko, or kldname.ver.ko) treat it as interface + * If file does not contain a qualified name or any dot in it + * (kldname.ko, or kldname.ver.ko) treat it as an interface * name. */ - if (index(pathname, '/') || index(pathname, '.')) { - kldname = pathname; + if (index(file, '/') || index(file, '.')) { + kldname = file; modname = NULL; } else { kldname = NULL; - modname = pathname; + modname = file; } KLD_LOCK(); - error = linker_load_module_internal(kldname, modname, NULL, NULL, &lf); + error = linker_load_module(kldname, modname, NULL, NULL, &lf); if (error) goto unlock; #ifdef HWPMC_HOOKS @@ -879,10 +873,26 @@ PMC_CALL_HOOK(td, PMC_FN_KLD_LOAD, (void *) &pkm); #endif lf->userrefs++; - td->td_retval[0] = lf->id; + if (fileid != NULL) + *fileid = lf->id; unlock: KLD_UNLOCK(); -out: + return (error); +} + +int +kldload(struct thread *td, struct kldload_args *uap) +{ + char *pathname = NULL; + int error; + + td->td_retval[0] = -1; + + pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); + error = copyinstr(uap->file, pathname, MAXPATHLEN, NULL); + if (error == 0) + error = kern_kldload(td, pathname, &td->td_retval[0]); + free(pathname, M_TEMP); return (error); } @@ -890,7 +900,7 @@ /* * MPSAFE */ -static int +int kern_kldunload(struct thread *td, int fileid, int flags) { #ifdef HWPMC_HOOKS @@ -1809,28 +1819,11 @@ * Find a file which contains given module and load it, if "parent" is not * NULL, register a reference to it. */ -int +static int linker_load_module(const char *kldname, const char *modname, struct linker_file *parent, struct mod_depend *verinfo, struct linker_file **lfpp) { - int error, locked; - - locked = KLD_LOCKED(); - if (!locked) - KLD_LOCK(); - error = linker_load_module_internal(kldname, modname, parent, - verinfo, lfpp); - if (!locked) - KLD_UNLOCK(); - return (error); -} - -static int -linker_load_module_internal(const char *kldname, const char *modname, - struct linker_file *parent, struct mod_depend *verinfo, - struct linker_file **lfpp) -{ linker_file_t lfdep; const char *filename; char *pathname; @@ -1960,7 +1953,7 @@ break; continue; } - error = linker_load_module_internal(NULL, modname, lf, verinfo, + error = linker_load_module(NULL, modname, lf, verinfo, NULL); if (error) { printf("KLD %s: depends on %s - not available\n", ==== //depot/projects/smpng/sys/kern/vfs_init.c#22 (text+ko) ==== @@ -43,6 +43,7 @@ #include <sys/linker.h> #include <sys/mount.h> #include <sys/proc.h> +#include <sys/syscallsubr.h> #include <sys/sysctl.h> #include <sys/vnode.h> #include <sys/malloc.h> @@ -108,7 +109,7 @@ vfs_byname_kld(const char *fstype, struct thread *td, int *error) { struct vfsconf *vfsp; - linker_file_t lf; + int fileid; vfsp = vfs_byname(fstype); if (vfsp != NULL) @@ -121,17 +122,14 @@ *error = securelevel_gt(td->td_ucred, 0); if (*error) return (NULL); - *error = linker_load_module(NULL, fstype, NULL, NULL, &lf); - if (lf == NULL) - *error = ENODEV; + *error = kern_kldload(td, fstype, &fileid); if (*error) return (NULL); - lf->userrefs++; + /* Look up again to see if the VFS was loaded. */ vfsp = vfs_byname(fstype); if (vfsp == NULL) { - lf->userrefs--; - linker_file_unload(lf, LINKER_UNLOAD_FORCE); + (void)kern_kldunload(td, fileid, LINKER_UNLOAD_FORCE); *error = ENODEV; return (NULL); } ==== //depot/projects/smpng/sys/net80211/ieee80211_freebsd.c#8 (text+ko) ==== @@ -310,14 +310,9 @@ void ieee80211_load_module(const char *modname) { + #ifdef notyet - struct thread *td = curthread; - - if (suser(td) == 0 && securelevel_gt(td->td_ucred, 0) == 0) { - mtx_lock(&Giant); - (void) linker_load_module(modname, NULL, NULL, NULL, NULL); - mtx_unlock(&Giant); - } + (void)kern_kldload(curthread, modname, NULL); #else printf("%s: load the %s module by hand for now.\n", __func__, modname); #endif ==== //depot/projects/smpng/sys/netgraph/ng_socket.c#37 (text+ko) ==== @@ -65,6 +65,7 @@ #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/sx.h> +#include <sys/syscallsubr.h> #include <sys/sysctl.h> #include <sys/systm.h> #ifdef NOTYET @@ -274,24 +275,22 @@ if ((type = ng_findtype(mkp->type)) == NULL) { char filename[NG_TYPESIZ + 3]; - linker_file_t lf; + int fileid; /* Not found, try to load it as a loadable module. */ snprintf(filename, sizeof(filename), "ng_%s", mkp->type); - mtx_lock(&Giant); - error = linker_load_module(NULL, filename, NULL, NULL, - &lf); - mtx_unlock(&Giant); + error = kern_kldload(curthread, filename, &fileid); if (error != 0) { FREE(msg, M_NETGRAPH_MSG); goto release; } - lf->userrefs++; /* See if type has been loaded successfully. */ if ((type = ng_findtype(mkp->type)) == NULL) { FREE(msg, M_NETGRAPH_MSG); + (void)kern_kldunload(curthread, fileid, + LINKER_UNLOAD_NORMAL); error = ENXIO; goto release; } ==== //depot/projects/smpng/sys/sys/linker.h#21 (text+ko) ==== @@ -105,13 +105,6 @@ extern linker_file_t linker_kernel_file; /* - * Load a kernel module. - */ -int linker_load_module(const char *_kldname, const char *_modname, - struct linker_file *_parent, struct mod_depend *_verinfo, - struct linker_file **_lfpp); - -/* * Obtain a reference to a module, loading it if required. */ int linker_reference_module(const char* _modname, struct mod_depend *_verinfo, ==== //depot/projects/smpng/sys/sys/syscallsubr.h#27 (text+ko) ==== @@ -86,6 +86,8 @@ void *optval, enum uio_seg valseg, socklen_t *valsize); int kern_kevent(struct thread *td, int fd, int nchanges, int nevents, struct kevent_copyops *k_ops, const struct timespec *timeout); +int kern_kldload(struct thread *td, const char *file, int *fileid); +int kern_kldunload(struct thread *td, int fileid, int flags); int kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid, int gid); int kern_link(struct thread *td, char *path, char *link,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200605252010.k4PKAxqk030690>