Date: Fri, 23 Jun 2006 15:47:53 GMT From: Chris Jones <cdjones@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 99866 for review Message-ID: <200606231547.k5NFlrg3019432@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=99866 Change 99866 by cdjones@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) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606231547.k5NFlrg3019432>