summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/compat/freebsd32/freebsd32_proto.h7
-rw-r--r--sys/compat/freebsd32/freebsd32_syscall.h5
-rw-r--r--sys/compat/freebsd32/freebsd32_syscalls.c3
-rw-r--r--sys/compat/freebsd32/freebsd32_sysent.c3
-rw-r--r--sys/dev/digi/digi.c4
-rw-r--r--sys/kern/init_sysent.c3
-rw-r--r--sys/kern/kern_linker.c49
-rw-r--r--sys/kern/kern_module.c8
-rw-r--r--sys/kern/link_elf.c4
-rw-r--r--sys/kern/link_elf_obj.c2
-rw-r--r--sys/kern/syscalls.c3
-rw-r--r--sys/kern/vfs_mount.c2
-rw-r--r--sys/sys/linker.h9
-rw-r--r--sys/sys/module.h5
-rw-r--r--sys/sys/syscall.h5
-rw-r--r--sys/sys/syscall.mk5
-rw-r--r--sys/sys/sysproto.h7
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
OpenPOWER on IntegriCloud