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