diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/compat/freebsd32/freebsd32_proto.h | 7 | ||||
-rw-r--r-- | sys/compat/freebsd32/freebsd32_syscall.h | 5 | ||||
-rw-r--r-- | sys/compat/freebsd32/freebsd32_syscalls.c | 3 | ||||
-rw-r--r-- | sys/compat/freebsd32/freebsd32_sysent.c | 3 | ||||
-rw-r--r-- | sys/dev/digi/digi.c | 4 | ||||
-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 | ||||
-rw-r--r-- | sys/sys/linker.h | 9 | ||||
-rw-r--r-- | sys/sys/module.h | 5 | ||||
-rw-r--r-- | sys/sys/syscall.h | 5 | ||||
-rw-r--r-- | sys/sys/syscall.mk | 5 | ||||
-rw-r--r-- | sys/sys/sysproto.h | 7 |
17 files changed, 91 insertions, 33 deletions
diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h index 79fc978..acebc69 100644 --- a/sys/compat/freebsd32/freebsd32_proto.h +++ b/sys/compat/freebsd32/freebsd32_proto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.38 2004/07/02 00:35:52 marcel Exp + * created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.39 2004/07/13 19:35:11 phk Exp */ #ifndef _FREEBSD32_SYSPROTO_H_ @@ -205,6 +205,10 @@ struct freebsd32_sigaction_args { struct freebsd32_sigreturn_args { char sigcntxp_l_[PADL_(const struct freebsd32_ucontext *)]; const struct freebsd32_ucontext * sigcntxp; char sigcntxp_r_[PADR_(const struct freebsd32_ucontext *)]; }; +struct kldunloadf_args { + char fileid_l_[PADL_(int)]; int fileid; char fileid_r_[PADR_(int)]; + char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)]; +}; int freebsd32_wait4(struct thread *, struct freebsd32_wait4_args *); int freebsd32_sigaltstack(struct thread *, struct freebsd32_sigaltstack_args *); int freebsd32_execve(struct thread *, struct freebsd32_execve_args *); @@ -235,6 +239,7 @@ int freebsd32_kevent(struct thread *, struct freebsd32_kevent_args *); int freebsd32_sendfile(struct thread *, struct freebsd32_sendfile_args *); int freebsd32_sigaction(struct thread *, struct freebsd32_sigaction_args *); int freebsd32_sigreturn(struct thread *, struct freebsd32_sigreturn_args *); +int kldunloadf(struct thread *, struct kldunloadf_args *); #ifdef COMPAT_43 diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h index 524e783..72fe352 100644 --- a/sys/compat/freebsd32/freebsd32_syscall.h +++ b/sys/compat/freebsd32/freebsd32_syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.38 2004/07/02 00:35:52 marcel Exp + * created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.39 2004/07/13 19:35:11 phk Exp */ #define FREEBSD32_SYS_syscall 0 @@ -301,4 +301,5 @@ #define FREEBSD32_SYS_jail_attach 436 #define FREEBSD32_SYS_thr_suspend 442 #define FREEBSD32_SYS_thr_wake 443 -#define FREEBSD32_SYS_MAXSYSCALL 444 +#define FREEBSD32_SYS_kldunloadf 444 +#define FREEBSD32_SYS_MAXSYSCALL 445 diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c index 6d73c55..291f8c4 100644 --- a/sys/compat/freebsd32/freebsd32_syscalls.c +++ b/sys/compat/freebsd32/freebsd32_syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.38 2004/07/02 00:35:52 marcel Exp + * created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.39 2004/07/13 19:35:11 phk Exp */ const char *freebsd32_syscallnames[] = { @@ -451,4 +451,5 @@ const char *freebsd32_syscallnames[] = { "#441", /* 441 = ksem_timedwait */ "thr_suspend", /* 442 = thr_suspend */ "thr_wake", /* 443 = thr_wake */ + "kldunloadf", /* 444 = kldunloadf */ }; diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c index dc4fd10..26144c6 100644 --- a/sys/compat/freebsd32/freebsd32_sysent.c +++ b/sys/compat/freebsd32/freebsd32_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.38 2004/07/02 00:35:52 marcel Exp + * created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.39 2004/07/13 19:35:11 phk Exp */ #include "opt_compat.h" @@ -469,4 +469,5 @@ struct sysent freebsd32_sysent[] = { { 0, (sy_call_t *)nosys }, /* 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/dev/digi/digi.c b/sys/dev/digi/digi.c index 68081d5..b08cd58 100644 --- a/sys/dev/digi/digi.c +++ b/sys/dev/digi/digi.c @@ -1042,7 +1042,7 @@ digi_loadmoduledata(struct digi_softc *sc) if (digi_mod->dm_version != DIGI_MOD_VERSION) { printf("digi_%s.ko: Invalid version %d (need %d)\n", sc->module, digi_mod->dm_version, DIGI_MOD_VERSION); - linker_file_unload(lf); + linker_file_unload(lf, LINKER_UNLOAD_FORCE); return (EINVAL); } @@ -1064,7 +1064,7 @@ digi_loadmoduledata(struct digi_softc *sc) bcopy(digi_mod->dm_link.data, sc->link.data, sc->link.size); } - linker_file_unload(lf); + linker_file_unload(lf, LINKER_UNLOAD_FORCE); return (0); } diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 9d0ecad..1185cf8 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 4ad549e..d2a2329 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 3832922..158612e 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 0f00d90..5679cbf 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 9049880..e5fa30e 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 202c7d1..9a2f795 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 d697499..cf7b7c1 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); } diff --git a/sys/sys/linker.h b/sys/sys/linker.h index 1815c47..923febe 100644 --- a/sys/sys/linker.h +++ b/sys/sys/linker.h @@ -135,7 +135,7 @@ linker_file_t linker_make_file(const char* _filename, linker_class_t _cls); /* * Unload a file, freeing up memory. */ -int linker_file_unload(linker_file_t _file); +int linker_file_unload(linker_file_t _file, int flags); /* * Add a dependency to a file. @@ -275,6 +275,12 @@ struct kld_sym_lookup { }; #define KLDSYM_LOOKUP 1 +/* + * Flags for kldunloadf() and linker_file_unload() + */ +#define LINKER_UNLOAD_NORMAL 0 +#define LINKER_UNLOAD_FORCE 1 + #ifndef _KERNEL #include <sys/cdefs.h> @@ -282,6 +288,7 @@ struct kld_sym_lookup { __BEGIN_DECLS int kldload(const char* _file); int kldunload(int _fileid); +int kldunloadf(int _fileid, int flags); int kldfind(const char* _file); int kldnext(int _fileid); int kldstat(int _fileid, struct kld_file_stat* _stat); diff --git a/sys/sys/module.h b/sys/sys/module.h index 39f138d..5beb9bb 100644 --- a/sys/sys/module.h +++ b/sys/sys/module.h @@ -42,7 +42,8 @@ typedef enum modeventtype { MOD_LOAD, MOD_UNLOAD, - MOD_SHUTDOWN + MOD_SHUTDOWN, + MOD_QUIESCE } modeventtype_t; typedef struct module *module_t; @@ -142,7 +143,7 @@ module_t module_lookupbyname(const char *); module_t module_lookupbyid(int); void module_reference(module_t); void module_release(module_t); -int module_unload(module_t); +int module_unload(module_t, int flags); int module_getid(module_t); module_t module_getfnext(module_t); void module_setspecific(module_t, modspecific_t *); diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 562de13..8767ff1 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -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 */ #define SYS_syscall 0 @@ -356,4 +356,5 @@ #define SYS_ksem_timedwait 441 #define SYS_thr_suspend 442 #define SYS_thr_wake 443 -#define SYS_MAXSYSCALL 444 +#define SYS_kldunloadf 444 +#define SYS_MAXSYSCALL 445 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index 2eac19a..9354f5a 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,7 +1,7 @@ # FreeBSD system call names. # 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 MIASM = \ syscall.o \ exit.o \ @@ -297,4 +297,5 @@ MIASM = \ kse_switchin.o \ ksem_timedwait.o \ thr_suspend.o \ - thr_wake.o + thr_wake.o \ + kldunloadf.o diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index a8e3a6b..ff28363 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -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 */ #ifndef _SYS_SYSPROTO_H_ @@ -1302,6 +1302,10 @@ struct thr_suspend_args { struct thr_wake_args { char id_l_[PADL_(long)]; long id; char id_r_[PADR_(long)]; }; +struct kldunloadf_args { + char fileid_l_[PADL_(int)]; int fileid; char fileid_r_[PADR_(int)]; + char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)]; +}; int nosys(struct thread *, struct nosys_args *); void sys_exit(struct thread *, struct sys_exit_args *); int fork(struct thread *, struct fork_args *); @@ -1596,6 +1600,7 @@ int kse_switchin(struct thread *, struct kse_switchin_args *); int ksem_timedwait(struct thread *, struct ksem_timedwait_args *); int thr_suspend(struct thread *, struct thr_suspend_args *); int thr_wake(struct thread *, struct thr_wake_args *); +int kldunloadf(struct thread *, struct kldunloadf_args *); #ifdef COMPAT_43 |