diff --git a/sbin/kldunload/kldunload.c b/sbin/kldunload/kldunload.c index 8a3ea61..50e215c 100644 --- a/sbin/kldunload/kldunload.c +++ b/sbin/kldunload/kldunload.c @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -53,7 +54,7 @@ int main(int argc, char** argv) { struct kld_file_stat stat; - int c, fileid, force, opt; + int c, error, fileid, force, opt; char *filename; filename = NULL; @@ -109,7 +110,14 @@ main(int argc, char** argv) else force = LINKER_UNLOAD_NORMAL; - if (kldunloadf(fileid, force) < 0) + error = kldunloadf(fileid, force); + + if (error < 0 && errno == EDOOFUS) { + warnx("module scheduled for removal when refcount drops " + "to zero"); + errno = EBUSY; + } + if (error < 0) err(EXIT_FAILURE, "can't unload file"); } diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 43ccd74..82128d0 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$"); #include #endif +#define KLD_DEBUG #ifdef KLD_DEBUG int kld_debug = 0; SYSCTL_INT(_debug, OID_AUTO, kld_debug, CTLFLAG_RW, @@ -592,7 +593,7 @@ linker_file_unload(linker_file_t file, int flags) /* Easy case of just dropping a reference. */ if (file->refs > 1) { file->refs--; - return (0); + return (EDOOFUS); } KLD_DPF(FILE, ("linker_file_unload: file is unloading," @@ -1095,7 +1096,7 @@ kern_kldunload(struct thread *td, int fileid, int flags) #endif lf->userrefs--; error = linker_file_unload(lf, flags); - if (error) + if (error && error != EDOOFUS) lf->userrefs++; } } else