Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys 1. Add an allocator for 'struct module *' and use it ins...
details: https://anonhg.NetBSD.org/src/rev/6eb4bb4de1d0
branches: trunk
changeset: 755874:6eb4bb4de1d0
user: pgoyette <pgoyette%NetBSD.org@localhost>
date: Sat Jun 26 07:23:57 2010 +0000
description:
1. Add an allocator for 'struct module *' and use it instead of local
allocations.
2. Add a new member mod_flags to the 'struct module *' and define
MODFLG_MUST_FORCE. If this flag is set and the entry is on the list
of builtins, it means that the module has been explicitly unloaded
and any re-loads will require the MODCTL_LOAD_FORCE flag. Provide a
module_require_force() method to set this flag; once set, it should
never be unset.
3. Rename original module_init2() to module_start_unload_thread() to be
more descriptive of what it does.
4. Add a new module_builtin_require_force() routine that sets the
MODFLG_MUST_FORCE flag for any module that has not yet successfully
been initialized. Call it after module_init_class(MODULE_CLASS_ANY)
to disable remaining built-in modules.
This makes built-in versions of the xxxVERBOSE modules work once more,
resolving breakage reported by jruoho@ and njoly@.
Discussed on tech-kern, and comments and suggestions implemented. No
additional discussion for last week. Tested only on amd64 systems, but
there's nothing here that should be port- or architecture-specific (no
more specific than existing module implementation) so others should not
break.
diffstat:
sys/kern/init_main.c | 10 +++--
sys/kern/kern_module.c | 90 ++++++++++++++++++++++++++++++++++++++-----------
sys/sys/module.h | 8 +++-
3 files changed, 82 insertions(+), 26 deletions(-)
diffs (296 lines):
diff -r 1401b34de959 -r 6eb4bb4de1d0 sys/kern/init_main.c
--- a/sys/kern/init_main.c Sat Jun 26 06:43:13 2010 +0000
+++ b/sys/kern/init_main.c Sat Jun 26 07:23:57 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: init_main.c,v 1.421 2010/06/25 15:10:42 tsutsui Exp $ */
+/* $NetBSD: init_main.c,v 1.422 2010/06/26 07:23:57 pgoyette Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.421 2010/06/25 15:10:42 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.422 2010/06/26 07:23:57 pgoyette Exp $");
#include "opt_ddb.h"
#include "opt_ipsec.h"
@@ -431,7 +431,7 @@
loginit();
/* Second part of module system initialization. */
- module_init2();
+ module_start_unload_thread();
/* Initialize the file systems. */
#ifdef NVNODE_IMPLICIT
@@ -595,9 +595,11 @@
/*
* Load any remaining builtin modules, and hand back temporary
- * storage to the VM system.
+ * storage to the VM system. Then require force when loading any
+ * remaining un-init'ed built-in modules to avoid later surprises.
*/
module_init_class(MODULE_CLASS_ANY);
+ module_builtin_require_force();
/*
* Finalize configuration now that all real devices have been
diff -r 1401b34de959 -r 6eb4bb4de1d0 sys/kern/kern_module.c
--- a/sys/kern/kern_module.c Sat Jun 26 06:43:13 2010 +0000
+++ b/sys/kern/kern_module.c Sat Jun 26 07:23:57 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_module.c,v 1.69 2010/05/26 23:53:21 pooka Exp $ */
+/* $NetBSD: kern_module.c,v 1.70 2010/06/26 07:23:57 pgoyette Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.69 2010/05/26 23:53:21 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.70 2010/06/26 07:23:57 pgoyette Exp $");
#define _MODULE_INTERNAL
@@ -87,9 +87,11 @@
static modinfo_t module_dummy;
__link_set_add_rodata(modules, module_dummy);
+static module_t *module_newmodule(modsrc_t);
+static void module_require_force(module_t *);
static int module_do_load(const char *, bool, int, prop_dictionary_t,
module_t **, modclass_t class, bool);
-static int module_do_unload(const char *);
+static int module_do_unload(const char *, bool);
static int module_do_builtin(const char *, module_t **);
static int module_fetch_info(module_t *);
static void module_thread(void *);
@@ -155,6 +157,32 @@
}
/*
+ * Allocate a new module_t
+ */
+static module_t *
+module_newmodule(modsrc_t source)
+{
+ module_t *mod;
+
+ mod = kmem_zalloc(sizeof(*mod), KM_SLEEP);
+ if (mod != NULL) {
+ mod->mod_source = source;
+ mod->mod_info = NULL;
+ mod->mod_flags = 0;
+ }
+ return mod;
+}
+
+/*
+ * Require the -f (force) flag to load a module
+ */
+static void
+module_require_force(struct module *mod)
+{
+ mod->mod_flags |= MODFLG_MUST_FORCE;
+}
+
+/*
* Add modules to the builtin list. This can done at boottime or
* at runtime if the module is linked into the kernel with an
* external linker. All or none of the input will be handled.
@@ -192,9 +220,8 @@
mipskip++;
continue;
}
- modp[i] = kmem_zalloc(sizeof(*modp[i]), KM_SLEEP);
+ modp[i] = module_newmodule(MODULE_SOURCE_KERNEL);
modp[i]->mod_info = mip[i+mipskip];
- modp[i]->mod_source = MODULE_SOURCE_KERNEL;
}
mutex_enter(&module_lock);
@@ -265,7 +292,7 @@
return rv;
mutex_enter(&module_lock);
- rv = module_do_unload(mi->mi_name);
+ rv = module_do_unload(mi->mi_name, true);
if (rv) {
goto out;
}
@@ -335,12 +362,12 @@
}
/*
- * module_init2:
+ * module_start_unload_thread:
*
* Start the auto unload kthread.
*/
void
-module_init2(void)
+module_start_unload_thread(void)
{
int error;
@@ -350,6 +377,24 @@
panic("module_init: %d", error);
}
+/*
+ * module_builtin_require_force
+ *
+ * Require MODCTL_MUST_FORCE to load any built-in modules that have
+ * not yet been initialized
+ */
+void
+module_builtin_require_force(void)
+{
+ module_t *mod;
+
+ mutex_enter(&module_lock);
+ TAILQ_FOREACH(mod, &module_builtins, mod_chain) {
+ module_require_force(mod);
+ }
+ mutex_exit(&module_lock);
+}
+
static struct sysctllog *module_sysctllog;
static void
@@ -412,10 +457,14 @@
/*
* If initializing a builtin module fails, don't try
* to load it again. But keep it around and queue it
- * on the disabled list after we're done with module
- * init.
+ * on the builtins list after we're done with module
+ * init. Don't set it to MODFLG_MUST_FORCE in case a
+ * future attempt to initialize can be successful.
+ * (If the module has previously been set to
+ * MODFLG_MUST_FORCE, don't try to override that!)
*/
- if (module_do_builtin(mi->mi_name, NULL) != 0) {
+ if (mod->mod_flags & MODFLG_MUST_FORCE ||
+ module_do_builtin(mi->mi_name, NULL) != 0) {
TAILQ_REMOVE(&module_builtins, mod, mod_chain);
TAILQ_INSERT_TAIL(&bi_fail, mod, mod_chain);
}
@@ -438,7 +487,7 @@
}
} while (mod != NULL);
- /* failed builtin modules remain disabled */
+ /* return failed builtin modules to builtin list */
while ((mod = TAILQ_FIRST(&bi_fail)) != NULL) {
TAILQ_REMOVE(&bi_fail, mod, mod_chain);
TAILQ_INSERT_TAIL(&module_builtins, mod, mod_chain);
@@ -544,7 +593,7 @@
}
mutex_enter(&module_lock);
- error = module_do_unload(name);
+ error = module_do_unload(name, true);
mutex_exit(&module_lock);
return error;
@@ -794,7 +843,8 @@
}
}
if (mod) {
- if ((flags & MODCTL_LOAD_FORCE) == 0) {
+ if ((mod->mod_flags & MODFLG_MUST_FORCE) &&
+ (flags & MODCTL_LOAD_FORCE) == 0) {
if (!autoload) {
module_error("use -f to reinstate "
"builtin module \"%s\"", name);
@@ -839,7 +889,7 @@
return 0;
}
}
- mod = kmem_zalloc(sizeof(*mod), KM_SLEEP);
+ mod = module_newmodule(MODULE_SOURCE_FILESYS);
if (mod == NULL) {
module_error("out of memory for `%s'", name);
depth--;
@@ -853,7 +903,6 @@
depth--;
return error;
}
- mod->mod_source = MODULE_SOURCE_FILESYS;
TAILQ_INSERT_TAIL(&pending, mod, mod_chain);
error = module_fetch_info(mod);
@@ -1048,7 +1097,7 @@
* Helper routine: do the dirty work of unloading a module.
*/
static int
-module_do_unload(const char *name)
+module_do_unload(const char *name, bool load_requires_force)
{
module_t *mod;
int error;
@@ -1086,6 +1135,8 @@
}
if (mod->mod_source == MODULE_SOURCE_KERNEL) {
mod->mod_nrequired = 0; /* will be re-parsed */
+ if (load_requires_force)
+ module_require_force(mod);
TAILQ_INSERT_TAIL(&module_builtins, mod, mod_chain);
module_builtinlist++;
} else {
@@ -1108,11 +1159,10 @@
module_t *mod;
int error;
- mod = kmem_zalloc(sizeof(*mod), KM_SLEEP);
+ mod = module_newmodule(MODULE_SOURCE_BOOT);
if (mod == NULL) {
return ENOMEM;
}
- mod->mod_source = MODULE_SOURCE_BOOT;
error = kobj_load_mem(&mod->mod_kobj, base, size);
if (error != 0) {
@@ -1218,7 +1268,7 @@
mi = mod->mod_info;
error = (*mi->mi_modcmd)(MODULE_CMD_AUTOUNLOAD, NULL);
if (error == 0 || error == ENOTTY) {
- (void)module_do_unload(mi->mi_name);
+ (void)module_do_unload(mi->mi_name, false);
}
}
mutex_exit(&module_lock);
diff -r 1401b34de959 -r 6eb4bb4de1d0 sys/sys/module.h
--- a/sys/sys/module.h Sat Jun 26 06:43:13 2010 +0000
+++ b/sys/sys/module.h Sat Jun 26 07:23:57 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: module.h,v 1.23 2010/05/24 03:50:25 pgoyette Exp $ */
+/* $NetBSD: module.h,v 1.24 2010/06/26 07:23:57 pgoyette Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -90,6 +90,9 @@
time_t mod_autotime;
void *mod_ctf;
u_int mod_fbtentries; /* DTrace FBT entrie count */
+ int mod_flags;
+#define MODFLG_MUST_FORCE 0x01
+
} module_t;
/*
@@ -120,7 +123,8 @@
extern u_int module_gen;
void module_init(void);
-void module_init2(void);
+void module_start_unload_thread(void);
+void module_builtin_require_force(void);
void module_init_md(void);
void module_init_class(modclass_t);
int module_prime(void *, size_t);
Home |
Main Index |
Thread Index |
Old Index