PERFORCE change 97817 for review

John Baldwin jhb at FreeBSD.org
Thu May 25 13:12:08 PDT 2006


http://perforce.freebsd.org/chv.cgi?CH=97817

Change 97817 by jhb at 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,


More information about the p4-projects mailing list