Ensure that circular dependencies do not panic the machine by doubly
locking the same file. Remove the special self-dependant case previously introduced, as the general case handles it properly.
This commit is contained in:
parent
9df302c742
commit
8a7c44d074
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kern_module.c,v 1.6 2008/01/18 16:41:46 rumble Exp $ */
|
||||
/* $NetBSD: kern_module.c,v 1.7 2008/01/19 00:57:35 rumble Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
@ -42,7 +42,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.6 2008/01/18 16:41:46 rumble Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.7 2008/01/19 00:57:35 rumble Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -388,6 +388,7 @@ module_do_load(const char *filename, bool isdep, bool force, module_t **modp)
|
||||
int error;
|
||||
size_t len;
|
||||
u_int i;
|
||||
bool closed = false;
|
||||
|
||||
KASSERT(mutex_owned(&module_lock));
|
||||
|
||||
@ -429,8 +430,9 @@ module_do_load(const char *filename, bool isdep, bool force, module_t **modp)
|
||||
return error;
|
||||
}
|
||||
error = kobj_load(mod->mod_kobj);
|
||||
if (error != 0)
|
||||
if (error != 0) {
|
||||
module_error("unable to load kernel object");
|
||||
}
|
||||
mod->mod_source = MODULE_SOURCE_FILESYS;
|
||||
}
|
||||
TAILQ_INSERT_TAIL(&pending, mod, mod_chain);
|
||||
@ -505,6 +507,14 @@ module_do_load(const char *filename, bool isdep, bool force, module_t **modp)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close the kobj before handling dependencies since we're done
|
||||
* with it and don't want to open an already locked file if a
|
||||
* circular dependency exists.
|
||||
*/
|
||||
kobj_close(mod->mod_kobj);
|
||||
closed = true;
|
||||
|
||||
/*
|
||||
* Now try to load any requisite modules.
|
||||
*/
|
||||
@ -555,7 +565,8 @@ module_do_load(const char *filename, bool isdep, bool force, module_t **modp)
|
||||
* list and add references to its requisite modules.
|
||||
*/
|
||||
module_count++;
|
||||
kobj_close(mod->mod_kobj);
|
||||
if (!closed)
|
||||
kobj_close(mod->mod_kobj);
|
||||
TAILQ_REMOVE(&pending, mod, mod_chain);
|
||||
TAILQ_INSERT_TAIL(&module_list, mod, mod_chain);
|
||||
for (i = 0; i < mod->mod_nrequired; i++) {
|
||||
@ -567,8 +578,10 @@ module_do_load(const char *filename, bool isdep, bool force, module_t **modp)
|
||||
}
|
||||
depth--;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
kobj_close(mod->mod_kobj);
|
||||
if (!closed)
|
||||
kobj_close(mod->mod_kobj);
|
||||
TAILQ_REMOVE(&pending, mod, mod_chain);
|
||||
kobj_unload(mod->mod_kobj);
|
||||
kmem_free(mod, sizeof(*mod));
|
||||
|
Loading…
x
Reference in New Issue
Block a user