PERFORCE change 99866 for review
Chris Jones
cdjones at FreeBSD.org
Fri Jun 23 15:47:54 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=99866
Change 99866 by cdjones at cdjones_ides on 2006/06/23 15:47:27
Integrate misc. unused stuff.
Affected files ...
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_acct.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_clock.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_event.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_exit.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_linker.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_mbuf.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_module.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_mutex.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_switch.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_synch.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_sysctl.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_tc.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/link_elf.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/link_elf_obj.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/sched_4bsd.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/sched_core.c#1 branch
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/sched_ule.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/subr_bus.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/subr_firmware.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/subr_kdb.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/subr_rman.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/sys_pipe.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/sysv_msg.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/sysv_sem.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/sysv_shm.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/uipc_mbuf.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/uipc_socket.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/uipc_socket2.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/uipc_syscalls.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/uipc_usrreq.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/vfs_aio.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/vfs_cache.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/vfs_init.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/vfs_mount.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/vfs_subr.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/vfs_syscalls.c#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/sys/kern/vnode_if.src#2 integrate
.. //depot/projects/soc2006/cdjones_jail/src/usr.sbin/jail/jail.8#2 integrate
Differences ...
==== //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_acct.c#2 (text+ko) ====
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_acct.c,v 1.81 2006/03/28 21:26:59 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_acct.c,v 1.82 2006/06/05 13:02:34 rwatson Exp $");
#include "opt_mac.h"
@@ -171,8 +171,8 @@
* appending and make sure it's a 'normal'.
*/
if (uap->path != NULL) {
- NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_USERSPACE,
- uap->path, td);
+ NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1,
+ UIO_USERSPACE, uap->path, td);
flags = FWRITE | O_APPEND;
error = vn_open(&nd, &flags, 0, -1);
if (error)
==== //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_clock.c#2 (text+ko) ====
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_clock.c,v 1.188 2006/04/17 20:14:51 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_clock.c,v 1.190 2006/06/14 03:14:26 delphij Exp $");
#include "opt_device_polling.h"
#include "opt_hwpmc_hooks.h"
@@ -201,6 +201,7 @@
* Run current process's virtual and profile time, as needed.
*/
mtx_lock_spin_flags(&sched_lock, MTX_QUIET);
+ sched_tick();
if (p->p_flag & P_SA) {
/* XXXKSE What to do? */
} else {
@@ -256,7 +257,7 @@
*/
mtx_lock_spin_flags(&callout_lock, MTX_QUIET);
ticks++;
- if (TAILQ_FIRST(&callwheel[ticks & callwheelmask]) != NULL) {
+ if (!TAILQ_EMPTY(&callwheel[ticks & callwheelmask])) {
need_softclock = 1;
} else if (softticks + 1 == ticks)
++softticks;
==== //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_event.c#2 (text+ko) ====
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_event.c,v 1.99 2006/04/14 14:27:28 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_event.c,v 1.103 2006/06/12 21:46:23 jhb Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -754,15 +754,12 @@
int
kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int waitok)
{
- struct filedesc *fdp;
struct filterops *fops;
struct file *fp;
struct knote *kn, *tkn;
int error, filt, event;
int haskqglobal;
- int fd;
- fdp = NULL;
fp = NULL;
kn = NULL;
error = 0;
@@ -778,22 +775,13 @@
findkn:
if (fops->f_isfd) {
KASSERT(td != NULL, ("td is NULL"));
- fdp = td->td_proc->p_fd;
- FILEDESC_LOCK(fdp);
- /* validate descriptor */
- fd = kev->ident;
- if (fd < 0 || fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[fd]) == NULL) {
- FILEDESC_UNLOCK(fdp);
- error = EBADF;
+ error = fget(td, kev->ident, &fp);
+ if (error)
goto done;
- }
- fhold(fp);
if ((kev->flags & EV_ADD) == EV_ADD && kqueue_expand(kq, fops,
kev->ident, 0) != 0) {
- /* unlock and try again */
- FILEDESC_UNLOCK(fdp);
+ /* try again */
fdrop(fp, td);
fp = NULL;
error = kqueue_expand(kq, fops, kev->ident, waitok);
@@ -811,15 +799,13 @@
* they are the same thing.
*/
if (fp->f_data == kq) {
- FILEDESC_UNLOCK(fdp);
error = EINVAL;
- goto done_noglobal;
+ goto done;
}
KQ_GLOBAL_LOCK(&kq_global, haskqglobal);
}
- FILEDESC_UNLOCK(fdp);
KQ_LOCK(kq);
if (kev->ident < kq->kq_knlistsize) {
SLIST_FOREACH(kn, &kq->kq_knlist[kev->ident], kn_link)
@@ -869,6 +855,7 @@
kn = tkn;
tkn = NULL;
if (kn == NULL) {
+ KQ_UNLOCK(kq);
error = ENOMEM;
goto done;
}
@@ -954,7 +941,6 @@
done:
KQ_GLOBAL_UNLOCK(&kq_global, haskqglobal);
-done_noglobal:
if (fp != NULL)
fdrop(fp, td);
if (tkn != NULL)
@@ -1708,7 +1694,7 @@
void
knlist_cleardel(struct knlist *knl, struct thread *td, int islocked, int killkn)
{
- struct knote *kn;
+ struct knote *kn, *kn2;
struct kqueue *kq;
if (islocked)
@@ -1719,7 +1705,7 @@
knl->kl_lock(knl->kl_lockarg);
}
- SLIST_FOREACH(kn, &knl->kl_list, kn_selnext) {
+ SLIST_FOREACH_SAFE(kn, &knl->kl_list, kn_selnext, kn2) {
kq = kn->kn_kq;
KQ_LOCK(kq);
if ((kn->kn_status & KN_INFLUX)) {
==== //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_exit.c#2 (text+ko) ====
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_exit.c,v 1.288 2006/04/10 14:07:28 csjp Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_exit.c,v 1.289 2006/05/29 21:28:56 tegge Exp $");
#include "opt_compat.h"
#include "opt_ktrace.h"
@@ -113,14 +113,13 @@
struct proc *p, *nq, *q;
struct tty *tp;
struct vnode *ttyvp;
- struct vmspace *vm;
struct vnode *vtmp;
#ifdef KTRACE
struct vnode *tracevp;
struct ucred *tracecred;
#endif
struct plimit *plim;
- int locked, refcnt;
+ int locked;
/*
* Drop Giant if caller has it. Eventually we should warn about
@@ -300,33 +299,7 @@
}
mtx_unlock(&ppeers_lock);
- /* The next two chunks should probably be moved to vmspace_exit. */
- vm = p->p_vmspace;
- /*
- * Release user portion of address space.
- * This releases references to vnodes,
- * which could cause I/O if the file has been unlinked.
- * Need to do this early enough that we can still sleep.
- * Can't free the entire vmspace as the kernel stack
- * may be mapped within that space also.
- *
- * Processes sharing the same vmspace may exit in one order, and
- * get cleaned up by vmspace_exit() in a different order. The
- * last exiting process to reach this point releases as much of
- * the environment as it can, and the last process cleaned up
- * by vmspace_exit() (which decrements exitingcnt) cleans up the
- * remainder.
- */
- atomic_add_int(&vm->vm_exitingcnt, 1);
- do
- refcnt = vm->vm_refcnt;
- while (!atomic_cmpset_int(&vm->vm_refcnt, refcnt, refcnt - 1));
- if (refcnt == 1) {
- shmexit(vm);
- pmap_remove_pages(vmspace_pmap(vm));
- (void) vm_map_remove(&vm->vm_map, vm_map_min(&vm->vm_map),
- vm_map_max(&vm->vm_map));
- }
+ vmspace_exit(td);
sx_xlock(&proctree_lock);
if (SESS_LEADER(p)) {
==== //depot/projects/soc2006/cdjones_jail/src/sys/kern/kern_linker.c#2 (text+ko) ====
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/kern_linker.c,v 1.120 2006/05/27 09:21:41 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/kern_linker.c,v 1.138 2006/06/21 20:42:08 jhb Exp $");
#include "opt_ddb.h"
#include "opt_hwpmc_hooks.h"
@@ -43,11 +43,13 @@
#include <sys/sx.h>
#include <sys/mac.h>
#include <sys/module.h>
+#include <sys/mount.h>
#include <sys/linker.h>
#include <sys/fcntl.h>
#include <sys/libkern.h>
#include <sys/namei.h>
#include <sys/vnode.h>
+#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include "linker_if.h"
@@ -60,12 +62,27 @@
int kld_debug = 0;
#endif
+#define KLD_LOCK() do { sx_xlock(&kld_sx); mtx_lock(&Giant); } while (0)
+#define KLD_UNLOCK() do { mtx_unlock(&Giant); sx_xunlock(&kld_sx); } while (0)
+#define KLD_LOCKED() sx_xlocked(&kld_sx)
+#define KLD_LOCK_ASSERT() do { if (!cold) sx_assert(&kld_sx, SX_XLOCKED); } while (0)
+
/*
* static char *linker_search_path(const char *name, struct mod_depend
* *verinfo);
*/
static const char *linker_basename(const char *path);
+/*
+ * Find a currently loaded file given its filename.
+ */
+static linker_file_t linker_find_file_by_name(const char* _filename);
+
+/*
+ * Find a currently loaded file given its file id.
+ */
+static linker_file_t linker_find_file_by_id(int _fileid);
+
/* Metadata from the static kernel */
SET_DECLARE(modmetadata_set, struct mod_metadata);
@@ -73,7 +90,7 @@
linker_file_t linker_kernel_file;
-static struct mtx kld_mtx; /* kernel linker mutex */
+static struct sx kld_sx; /* kernel linker lock */
static linker_class_list_t classes;
static linker_file_list_t linker_files;
@@ -83,17 +100,15 @@
#define LINKER_GET_NEXT_FILE_ID(a) do { \
linker_file_t lftmp; \
\
+ KLD_LOCK_ASSERT(); \
retry: \
- mtx_lock(&kld_mtx); \
TAILQ_FOREACH(lftmp, &linker_files, link) { \
if (next_file_id == lftmp->id) { \
next_file_id++; \
- mtx_unlock(&kld_mtx); \
goto retry; \
} \
} \
(a) = next_file_id; \
- mtx_unlock(&kld_mtx); /* Hold for safe read of id variable */ \
} while(0)
@@ -108,8 +123,14 @@
typedef struct modlist *modlist_t;
static modlisthead_t found_modules;
-static modlist_t modlist_lookup2(const char *name,
- struct mod_depend *verinfo);
+static int linker_file_add_dependency(linker_file_t file,
+ linker_file_t dep);
+static caddr_t linker_file_lookup_symbol_internal(linker_file_t file,
+ const char* name, int deps);
+static int linker_load_module(const char *kldname,
+ const char *modname, struct linker_file *parent,
+ struct mod_depend *verinfo, struct linker_file **lfpp);
+static modlist_t modlist_lookup2(const char *name, struct mod_depend *verinfo);
static char *
linker_strdup(const char *str)
@@ -125,7 +146,7 @@
linker_init(void *arg)
{
- mtx_init(&kld_mtx, "kernel linker", NULL, MTX_DEF);
+ sx_init(&kld_sx, "kernel linker");
TAILQ_INIT(&classes);
TAILQ_INIT(&linker_files);
}
@@ -171,7 +192,7 @@
/*
* Perform a bubble sort of the system initialization objects by
* their subsystem (primary key) and order (secondary key).
- *
+ *
* Since some things care about execution order, this is the operation
* which ensures continued function.
*/
@@ -215,7 +236,7 @@
/*
* Perform a reverse bubble sort of the system initialization objects
* by their subsystem (primary key) and order (secondary key).
- *
+ *
* Since some things care about execution order, this is the operation
* which ensures continued function.
*/
@@ -256,8 +277,10 @@
if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
return;
+ mtx_lock(&Giant);
for (oidp = start; oidp < stop; oidp++)
sysctl_register_oid(*oidp);
+ mtx_unlock(&Giant);
}
static void
@@ -271,8 +294,10 @@
if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
return;
+ mtx_lock(&Giant);
for (oidp = start; oidp < stop; oidp++)
sysctl_unregister_oid(*oidp);
+ mtx_unlock(&Giant);
}
static int
@@ -286,7 +311,7 @@
" in %s\n", lf->filename));
if (linker_file_lookup_set(lf, "modmetadata_set", &start,
- &stop, 0) != 0) {
+ &stop, NULL) != 0) {
/*
* This fallback should be unnecessary, but if we get booted
* from boot2 instead of loader and we are missing our
@@ -330,22 +355,23 @@
{
linker_class_t lc;
linker_file_t lf;
- int foundfile, error = 0;
+ int foundfile, error;
/* Refuse to load modules if securelevel raised */
if (securelevel > 0)
return (EPERM);
+ KLD_LOCK_ASSERT();
lf = linker_find_file_by_name(filename);
if (lf) {
KLD_DPF(FILE, ("linker_load_file: file %s is already loaded,"
" incrementing refs\n", filename));
*result = lf;
lf->refs++;
- goto out;
+ return (0);
}
- lf = NULL;
foundfile = 0;
+ error = 0;
/*
* We do not need to protect (lock) classes here because there is
@@ -366,14 +392,13 @@
error = linker_file_register_modules(lf);
if (error == EEXIST) {
linker_file_unload(lf, LINKER_UNLOAD_FORCE);
- goto out;
+ return (error);
}
linker_file_register_sysctls(lf);
linker_file_sysinit(lf);
lf->flags |= LINKER_FILE_LINKED;
*result = lf;
- error = 0;
- goto out;
+ return (0);
}
}
/*
@@ -393,7 +418,6 @@
error = ENOEXEC;
} else
error = ENOENT; /* Nothing found */
-out:
return (error);
}
@@ -402,67 +426,107 @@
linker_file_t *result)
{
modlist_t mod;
+ int error;
+ KLD_LOCK();
if ((mod = modlist_lookup2(modname, verinfo)) != NULL) {
*result = mod->container;
(*result)->refs++;
+ KLD_UNLOCK();
return (0);
}
- return (linker_load_module(NULL, modname, NULL, verinfo, result));
+ error = linker_load_module(NULL, modname, NULL, verinfo, result);
+ KLD_UNLOCK();
+ return (error);
+}
+
+int
+linker_release_module(const char *modname, struct mod_depend *verinfo,
+ linker_file_t lf)
+{
+ modlist_t mod;
+ int error;
+
+ KLD_LOCK();
+ if (lf == NULL) {
+ KASSERT(modname != NULL,
+ ("linker_release_module: no file or name"));
+ mod = modlist_lookup2(modname, verinfo);
+ if (mod == NULL) {
+ KLD_UNLOCK();
+ return (ESRCH);
+ }
+ lf = mod->container;
+ } else
+ KASSERT(modname == NULL && verinfo == NULL,
+ ("linker_release_module: both file and name"));
+ error = linker_file_unload(lf, LINKER_UNLOAD_NORMAL);
+ KLD_UNLOCK();
+ return (error);
}
-linker_file_t
+static linker_file_t
linker_find_file_by_name(const char *filename)
{
- linker_file_t lf = 0;
+ linker_file_t lf;
char *koname;
koname = malloc(strlen(filename) + 4, M_LINKER, M_WAITOK);
- if (koname == NULL)
- goto out;
sprintf(koname, "%s.ko", filename);
- mtx_lock(&kld_mtx);
+ KLD_LOCK_ASSERT();
TAILQ_FOREACH(lf, &linker_files, link) {
if (strcmp(lf->filename, koname) == 0)
break;
if (strcmp(lf->filename, filename) == 0)
break;
}
- mtx_unlock(&kld_mtx);
-out:
- if (koname)
- free(koname, M_LINKER);
+ free(koname, M_LINKER);
return (lf);
}
-linker_file_t
+static linker_file_t
linker_find_file_by_id(int fileid)
{
- linker_file_t lf = 0;
-
- mtx_lock(&kld_mtx);
+ linker_file_t lf;
+
+ KLD_LOCK_ASSERT();
TAILQ_FOREACH(lf, &linker_files, link)
if (lf->id == fileid)
break;
- mtx_unlock(&kld_mtx);
return (lf);
}
+int
+linker_file_foreach(linker_predicate_t *predicate, void *context)
+{
+ linker_file_t lf;
+ int retval = 0;
+
+ KLD_LOCK();
+ TAILQ_FOREACH(lf, &linker_files, link) {
+ retval = predicate(lf, context);
+ if (retval != 0)
+ break;
+ }
+ KLD_UNLOCK();
+ return (retval);
+}
+
linker_file_t
linker_make_file(const char *pathname, linker_class_t lc)
{
linker_file_t lf;
const char *filename;
- lf = NULL;
+ KLD_LOCK_ASSERT();
filename = linker_basename(pathname);
KLD_DPF(FILE, ("linker_make_file: new file, filename=%s\n", filename));
lf = (linker_file_t)kobj_create((kobj_class_t)lc, M_LINKER, M_WAITOK);
if (lf == NULL)
- goto out;
+ return (NULL);
lf->refs = 1;
lf->userrefs = 0;
lf->flags = 0;
@@ -472,10 +536,7 @@
lf->deps = NULL;
STAILQ_INIT(&lf->common);
TAILQ_INIT(&lf->modules);
- mtx_lock(&kld_mtx);
TAILQ_INSERT_TAIL(&linker_files, lf, link);
- mtx_unlock(&kld_mtx);
-out:
return (lf);
}
@@ -487,8 +548,6 @@
struct common_symbol *cp;
int error, i;
- error = 0;
-
/* Refuse to unload modules if securelevel raised. */
if (securelevel > 0)
return (EPERM);
@@ -498,55 +557,55 @@
return (error);
#endif
+ KLD_LOCK_ASSERT();
KLD_DPF(FILE, ("linker_file_unload: lf->refs=%d\n", file->refs));
- if (file->refs == 1) {
- KLD_DPF(FILE, ("linker_file_unload: file is unloading,"
- " informing modules\n"));
+
+ /* Easy case of just dropping a reference. */
+ if (file->refs > 1) {
+ file->refs--;
+ return (0);
+ }
+
+ KLD_DPF(FILE, ("linker_file_unload: file is unloading,"
+ " informing modules\n"));
+
+ /*
+ * Inform any modules associated with this file.
+ */
+ MOD_XLOCK;
+ for (mod = TAILQ_FIRST(&file->modules); mod; mod = next) {
+ next = module_getfnext(mod);
+ MOD_XUNLOCK;
/*
- * Inform any modules associated with this file.
+ * Give the module a chance to veto the unload.
*/
+ if ((error = module_unload(mod, flags)) != 0) {
+ KLD_DPF(FILE, ("linker_file_unload: module %p"
+ " vetoes unload\n", mod));
+ return (error);
+ }
MOD_XLOCK;
- for (mod = TAILQ_FIRST(&file->modules); mod; mod = next) {
- next = module_getfnext(mod);
- MOD_XUNLOCK;
+ module_release(mod);
+ }
+ MOD_XUNLOCK;
- /*
- * Give the module a chance to veto the unload.
- */
- if ((error = module_unload(mod, flags)) != 0) {
- KLD_DPF(FILE, ("linker_file_unload: module %p"
- " vetoes unload\n", mod));
- goto out;
- } else
- MOD_XLOCK;
- module_release(mod);
- }
- MOD_XUNLOCK;
- }
- file->refs--;
- if (file->refs > 0) {
- goto out;
- }
- for (ml = TAILQ_FIRST(&found_modules); ml; ml = nextml) {
- nextml = TAILQ_NEXT(ml, link);
+ TAILQ_FOREACH_SAFE(ml, &found_modules, link, nextml) {
if (ml->container == file) {
TAILQ_REMOVE(&found_modules, ml, link);
free(ml, M_LINKER);
}
}
- /*
- * Don't try to run SYSUNINITs if we are unloaded due to a
+ /*
+ * Don't try to run SYSUNINITs if we are unloaded due to a
* link error.
*/
if (file->flags & LINKER_FILE_LINKED) {
linker_file_sysuninit(file);
linker_file_unregister_sysctls(file);
}
- mtx_lock(&kld_mtx);
TAILQ_REMOVE(&linker_files, file, link);
- mtx_unlock(&kld_mtx);
if (file->deps) {
for (i = 0; i < file->ndeps; i++)
@@ -566,15 +625,15 @@
file->filename = NULL;
}
kobj_delete((kobj_t) file, M_LINKER);
-out:
- return (error);
+ return (0);
}
-int
+static int
linker_file_add_dependency(linker_file_t file, linker_file_t dep)
{
linker_file_t *newdeps;
+ KLD_LOCK_ASSERT();
newdeps = malloc((file->ndeps + 1) * sizeof(linker_file_t *),
M_LINKER, M_WAITOK | M_ZERO);
if (newdeps == NULL)
@@ -593,25 +652,51 @@
/*
* Locate a linker set and its contents. This is a helper function to avoid
- * linker_if.h exposure elsewhere. Note: firstp and lastp are really void ***
+ * linker_if.h exposure elsewhere. Note: firstp and lastp are really void **.
+ * This function is used in this file so we can avoid having lots of (void **)
+ * casts.
*/
int
linker_file_lookup_set(linker_file_t file, const char *name,
void *firstp, void *lastp, int *countp)
{
+ int error, locked;
- return (LINKER_LOOKUP_SET(file, name, firstp, lastp, countp));
+ locked = KLD_LOCKED();
+ if (!locked)
+ KLD_LOCK();
+ error = LINKER_LOOKUP_SET(file, name, firstp, lastp, countp);
+ if (!locked)
+ KLD_UNLOCK();
+ return (error);
}
caddr_t
linker_file_lookup_symbol(linker_file_t file, const char *name, int deps)
{
+ caddr_t sym;
+ int locked;
+
+ locked = KLD_LOCKED();
+ if (!locked)
+ KLD_LOCK();
+ sym = linker_file_lookup_symbol_internal(file, name, deps);
+ if (!locked)
+ KLD_UNLOCK();
+ return (sym);
+}
+
+static caddr_t
+linker_file_lookup_symbol_internal(linker_file_t file, const char *name,
+ int deps)
+{
c_linker_sym_t sym;
linker_symval_t symval;
caddr_t address;
size_t common_size = 0;
int i;
+ KLD_LOCK_ASSERT();
KLD_DPF(SYM, ("linker_file_lookup_symbol: file=%p, name=%s, deps=%d\n",
file, name, deps));
@@ -632,8 +717,8 @@
}
if (deps) {
for (i = 0; i < file->ndeps; i++) {
- address = linker_file_lookup_symbol(file->deps[i],
- name, 0);
+ address = linker_file_lookup_symbol_internal(
+ file->deps[i], name, 0);
if (address) {
KLD_DPF(SYM, ("linker_file_lookup_symbol:"
" deps value=%p\n", address));
@@ -663,10 +748,6 @@
cp = malloc(sizeof(struct common_symbol)
+ common_size + strlen(name) + 1, M_LINKER,
M_WAITOK | M_ZERO);
- if (cp == NULL) {
- KLD_DPF(SYM, ("linker_file_lookup_symbol: nomem\n"));
- return (0);
- }
cp->address = (caddr_t)(cp + 1);
cp->name = cp->address + common_size;
strcpy(cp->name, name);
@@ -685,7 +766,7 @@
/*
* DDB Helpers. DDB has to look across multiple files with their own symbol
* tables and string tables.
- *
+ *
* Note that we do not obey list locking protocols here. We really don't need
* DDB to hang because somebody's got the lock held. We'll take the chance
* that the files list is inconsistant instead.
@@ -754,64 +835,74 @@
* 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;
-
- td->td_retval[0] = -1;
-
- mtx_lock(&Giant);
+ int error;
if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
- goto out;
+ return (error);
if ((error = suser(td)) != 0)
- goto out;
-
- pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
- if ((error = copyinstr(uap->file, pathname, MAXPATHLEN, NULL)) != 0)
- goto out;
+ return (error);
/*
- * 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(kldname, modname, NULL, NULL, &lf);
if (error)
- goto out;
-
+ goto unlock;
#ifdef HWPMC_HOOKS
pkm.pm_file = lf->filename;
pkm.pm_address = (uintptr_t) lf->address;
PMC_CALL_HOOK(td, PMC_FN_KLD_LOAD, (void *) &pkm);
#endif
lf->userrefs++;
- td->td_retval[0] = lf->id;
-out:
- if (pathname)
- free(pathname, M_TEMP);
- mtx_unlock(&Giant);
+ if (fileid != NULL)
+ *fileid = lf->id;
+unlock:
+ KLD_UNLOCK();
+ return (error);
+}
+
+int
+kldload(struct thread *td, struct kldload_args *uap)
+{
+ char *pathname = NULL;
+ int error, fileid;
+
+ 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, &fileid);
+ if (error == 0)
+ td->td_retval[0] = fileid;
+ }
+ free(pathname, M_TEMP);
return (error);
}
/*
* MPSAFE
*/
-static int
+int
kern_kldunload(struct thread *td, int fileid, int flags)
{
#ifdef HWPMC_HOOKS
@@ -820,14 +911,13 @@
linker_file_t lf;
int error = 0;
- mtx_lock(&Giant);
-
if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
- goto out;
+ return (error);
if ((error = suser(td)) != 0)
- goto out;
+ return (error);
+ KLD_LOCK();
lf = linker_find_file_by_id(fileid);
if (lf) {
KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs));
@@ -838,17 +928,17 @@
printf("kldunload: attempt to unload file that was"
" loaded by the kernel\n");
error = EBUSY;
- goto out;
- }
- lf->userrefs--;
+ } else {
#ifdef HWPMC_HOOKS
- /* Save data needed by hwpmc(4) before unloading the kld. */
- pkm.pm_address = (uintptr_t) lf->address;
- pkm.pm_size = lf->size;
+ /* Save data needed by hwpmc(4) before unloading. */
+ pkm.pm_address = (uintptr_t) lf->address;
+ pkm.pm_size = lf->size;
#endif
- error = linker_file_unload(lf, flags);
- if (error)
- lf->userrefs++;
+ lf->userrefs--;
+ error = linker_file_unload(lf, flags);
+ if (error)
+ lf->userrefs++;
+ }
} else
error = ENOENT;
@@ -856,8 +946,7 @@
if (error == 0)
PMC_CALL_HOOK(td, PMC_FN_KLD_UNLOAD, (void *) &pkm);
#endif
-out:
- mtx_unlock(&Giant);
+ KLD_UNLOCK();
return (error);
}
@@ -893,7 +982,7 @@
char *pathname;
const char *filename;
linker_file_t lf;
- int error = 0;
+ int error;
#ifdef MAC
error = mac_check_kld_stat(td->td_ucred);
@@ -901,7 +990,6 @@
return (error);
#endif
- mtx_lock(&Giant);
td->td_retval[0] = -1;
pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
@@ -909,15 +997,15 @@
goto out;
filename = linker_basename(pathname);
+ KLD_LOCK();
lf = linker_find_file_by_name(filename);
if (lf)
td->td_retval[0] = lf->id;
else
error = ENOENT;
+ KLD_UNLOCK();
out:
- if (pathname)
- free(pathname, M_TEMP);
- mtx_unlock(&Giant);
+ free(pathname, M_TEMP);
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list