module_register_init fails, but driver is still loaded?
John Baldwin
jhb at freebsd.org
Tue Aug 23 11:56:28 UTC 2011
On Thursday, August 04, 2011 12:23:15 pm Garrett Cooper wrote:
> Hi hackers,
> I noticed that if anything fails while initializing a driver, the
> driver stays attached to the kernel as a module instead of being
> kicked when all references to the driver go to 0. Is this desired
> behavior (it doesn't seem like it, but I can see potential pros and
> cons of kicking the driver out of the kernel immediately when a
> failure state occurs)? I've seen this on 7.2 ~ 9-CURRENT. Example
> sourcecode and invocation attached below.
This is sort of a feature actually. Consider the hard cases avg@ mentioned
such as a kld that contains multiple modules. What one could possibly do is
notice that all modules failed MOD_LOAD and do an unload in that case. This
untested patch tries to do that:
Index: kern_linker.c
===================================================================
--- kern_linker.c (revision 225077)
+++ kern_linker.c (working copy)
@@ -378,7 +378,7 @@ linker_load_file(const char *filename, linker_file
{
linker_class_t lc;
linker_file_t lf;
- int foundfile, error;
+ int foundfile, error, modules;
/* Refuse to load modules if securelevel raised */
if (prison0.pr_securelevel > 0)
@@ -417,11 +417,22 @@ linker_load_file(const char *filename, linker_file
linker_file_unload(lf, LINKER_UNLOAD_FORCE);
return (error);
}
+ modules = !TAILQ_EMPTY(&lf->modules);
KLD_UNLOCK();
linker_file_register_sysctls(lf);
linker_file_sysinit(lf);
KLD_LOCK();
lf->flags |= LINKER_FILE_LINKED;
+
+ /*
+ * If all of the modules in this file failed
+ * to load, unload the file and return an
+ * error of ENOEXEC.
+ */
+ if (modules && TAILQ_EMPTY(&lf->modules)) {
+ linker_file_unload(lf, LINKER_UNLOAD_FORCE);
+ return (ENOEXEC);
+ }
*result = lf;
return (0);
}
@@ -625,7 +636,7 @@ linker_file_unload(linker_file_t file, int flags)
/*
* Inform any modules associated with this file that they are
- * being be unloaded.
+ * being unloaded.
*/
MOD_XLOCK;
for (mod = TAILQ_FIRST(&file->modules); mod; mod = next) {
--
John Baldwin
More information about the freebsd-hackers
mailing list