diff options
| author | Poul-Henning Kamp <phk@FreeBSD.org> | 2004-07-13 19:36:59 +0000 |
|---|---|---|
| committer | Poul-Henning Kamp <phk@FreeBSD.org> | 2004-07-13 19:36:59 +0000 |
| commit | 65a311fcb2f44fce7eb05160d3198cefed5c27f9 (patch) | |
| tree | d2eb15e6477b3d5e7e1f7c49c1e2eed3b85ec318 /sys/kern | |
| parent | 1a946b9fef9f4b4cd10611232e8844d4c2d33e69 (diff) | |
Notes
Diffstat (limited to 'sys/kern')
| -rw-r--r-- | sys/kern/init_sysent.c | 3 | ||||
| -rw-r--r-- | sys/kern/kern_linker.c | 49 | ||||
| -rw-r--r-- | sys/kern/kern_module.c | 8 | ||||
| -rw-r--r-- | sys/kern/link_elf.c | 4 | ||||
| -rw-r--r-- | sys/kern/link_elf_obj.c | 2 | ||||
| -rw-r--r-- | sys/kern/syscalls.c | 3 | ||||
| -rw-r--r-- | sys/kern/vfs_mount.c | 2 |
7 files changed, 53 insertions, 18 deletions
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 9d0ecade6a44..1185cf817f81 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.174 2004/07/02 00:35:52 marcel Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.176 2004/07/13 19:35:10 phk Exp */ #include "opt_compat.h" @@ -472,4 +472,5 @@ struct sysent sysent[] = { { SYF_MPSAFE | AS(ksem_timedwait_args), (sy_call_t *)lkmressys }, /* 441 = ksem_timedwait */ { SYF_MPSAFE | AS(thr_suspend_args), (sy_call_t *)thr_suspend }, /* 442 = thr_suspend */ { SYF_MPSAFE | AS(thr_wake_args), (sy_call_t *)thr_wake }, /* 443 = thr_wake */ + { SYF_MPSAFE | AS(kldunloadf_args), (sy_call_t *)kldunloadf }, /* 444 = kldunloadf */ }; diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 4ad549eec183..d2a2329a4880 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -466,7 +466,7 @@ out: } int -linker_file_unload(linker_file_t file) +linker_file_unload(linker_file_t file, int flags) { module_t mod, next; modlist_t ml, nextml; @@ -500,7 +500,7 @@ linker_file_unload(linker_file_t file) /* * Give the module a chance to veto the unload. */ - if ((error = module_unload(mod)) != 0) { + if ((error = module_unload(mod, flags)) != 0) { KLD_DPF(FILE, ("linker_file_unload: module %p" " vetoes unload\n", mod)); goto out; @@ -536,7 +536,7 @@ linker_file_unload(linker_file_t file) if (file->deps) { for (i = 0; i < file->ndeps; i++) - linker_file_unload(file->deps[i]); + linker_file_unload(file->deps[i], flags); free(file->deps, M_LINKER); file->deps = NULL; } @@ -789,8 +789,8 @@ out: /* * MPSAFE */ -int -kldunload(struct thread *td, struct kldunload_args *uap) +static int +kern_kldunload(struct thread *td, int fileid, int flags) { linker_file_t lf; int error = 0; @@ -803,17 +803,20 @@ kldunload(struct thread *td, struct kldunload_args *uap) if ((error = suser(td)) != 0) goto out; - lf = linker_find_file_by_id(uap->fileid); + lf = linker_find_file_by_id(fileid); if (lf) { KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs)); if (lf->userrefs == 0) { + /* + * XXX: maybe LINKER_UNLOAD_FORCE should override ? + */ printf("kldunload: attempt to unload file that was" " loaded by the kernel\n"); error = EBUSY; goto out; } lf->userrefs--; - error = linker_file_unload(lf); + error = linker_file_unload(lf, flags); if (error) lf->userrefs++; } else @@ -827,6 +830,29 @@ out: * MPSAFE */ int +kldunload(struct thread *td, struct kldunload_args *uap) +{ + + return (kern_kldunload(td, uap->fileid, LINKER_UNLOAD_NORMAL)); +} + +/* + * MPSAFE + */ +int +kldunloadf(struct thread *td, struct kldunloadf_args *uap) +{ + + if (uap->flags != LINKER_UNLOAD_NORMAL && + uap->flags != LINKER_UNLOAD_FORCE) + return (EINVAL); + return (kern_kldunload(td, uap->fileid, uap->flags)); +} + +/* + * MPSAFE + */ +int kldfind(struct thread *td, struct kldfind_args *uap) { char *pathname; @@ -1250,7 +1276,8 @@ restart: nver) != NULL) { printf("module %s already" " present!\n", modname); - linker_file_unload(lf); + linker_file_unload(lf, + LINKER_UNLOAD_FORCE); TAILQ_REMOVE(&loaded_files, lf, loaded); /* we changed tailq next ptr */ @@ -1276,7 +1303,7 @@ restart: */ TAILQ_FOREACH(lf, &loaded_files, loaded) { printf("KLD file %s is missing dependencies\n", lf->filename); - linker_file_unload(lf); + linker_file_unload(lf, LINKER_UNLOAD_FORCE); TAILQ_REMOVE(&loaded_files, lf, loaded); } @@ -1317,7 +1344,7 @@ restart: if (error) { printf("KLD file %s - could not finalize loading\n", lf->filename); - linker_file_unload(lf); + linker_file_unload(lf, LINKER_UNLOAD_FORCE); continue; } linker_file_register_modules(lf); @@ -1676,7 +1703,7 @@ linker_load_module(const char *kldname, const char *modname, break; if (modname && verinfo && modlist_lookup2(modname, verinfo) == NULL) { - linker_file_unload(lfdep); + linker_file_unload(lfdep, LINKER_UNLOAD_FORCE); error = ENOENT; break; } diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c index 3832922f5961..158612e822c1 100644 --- a/sys/kern/kern_module.c +++ b/sys/kern/kern_module.c @@ -215,9 +215,15 @@ module_lookupbyid(int modid) } int -module_unload(module_t mod) +module_unload(module_t mod, int flags) { + int error; + error = MOD_EVENT(mod, MOD_QUIESCE); + if (error == EOPNOTSUPP) + error = 0; + if (flags == LINKER_UNLOAD_NORMAL && error != 0) + return (error); return (MOD_EVENT(mod, MOD_UNLOAD)); } diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index 0f00d904a978..5679cbf2f3fa 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -492,7 +492,7 @@ link_elf_link_preload(linker_class_t cls, error = parse_dynamic(ef); if (error) { - linker_file_unload(lf); + linker_file_unload(lf, LINKER_UNLOAD_FORCE); return error; } link_elf_reloc_local(lf); @@ -846,7 +846,7 @@ nosyms: out: if (error && lf) - linker_file_unload(lf); + linker_file_unload(lf, LINKER_UNLOAD_FORCE); if (shdr) free(shdr, M_LINKER); if (firstpage) diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c index 9049880fe8fb..e5fa30e98045 100644 --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -588,7 +588,7 @@ link_elf_load_file(linker_class_t cls, const char *filename, out: if (error && lf) - linker_file_unload(lf); + linker_file_unload(lf, LINKER_UNLOAD_FORCE); if (hdr) free(hdr, M_LINKER); VOP_UNLOCK(nd.ni_vp, 0, td); diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 202c7d136c77..9a2f79556b91 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.174 2004/07/02 00:35:52 marcel Exp + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.176 2004/07/13 19:35:10 phk Exp */ const char *syscallnames[] = { @@ -451,4 +451,5 @@ const char *syscallnames[] = { "ksem_timedwait", /* 441 = ksem_timedwait */ "thr_suspend", /* 442 = thr_suspend */ "thr_wake", /* 443 = thr_wake */ + "kldunloadf", /* 444 = kldunloadf */ }; diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index d697499a80a7..cf7b7c127257 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -799,7 +799,7 @@ vfs_domount( break; if (vfsp == NULL) { lf->userrefs--; - linker_file_unload(lf); + linker_file_unload(lf, LINKER_UNLOAD_FORCE); vput(vp); return (ENODEV); } |
