Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys add more accessor functions for various struct module fi...
details: https://anonhg.NetBSD.org/src/rev/6937f0004711
branches: trunk
changeset: 323026:6937f0004711
user: chs <chs%NetBSD.org@localhost>
date: Mon May 28 21:04:40 2018 +0000
description:
add more accessor functions for various struct module fields.
add a mechanism for registering callbacks to be called upon module load/unload.
diffstat:
sys/kern/kern_module.c | 239 +++++++++++++++++++++++++++++++++++++++++++-----
sys/sys/module.h | 34 ++++--
2 files changed, 234 insertions(+), 39 deletions(-)
diffs (truncated from 497 to 300 lines):
diff -r c35e574a9c92 -r 6937f0004711 sys/kern/kern_module.c
--- a/sys/kern/kern_module.c Mon May 28 21:04:37 2018 +0000
+++ b/sys/kern/kern_module.c Mon May 28 21:04:40 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_module.c,v 1.130 2017/12/14 22:28:59 pgoyette Exp $ */
+/* $NetBSD: kern_module.c,v 1.131 2018/05/28 21:04:40 chs 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.130 2017/12/14 22:28:59 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.131 2018/05/28 21:04:40 chs Exp $");
#define _MODULE_INTERNAL
@@ -65,6 +65,21 @@
struct modlist module_builtins = TAILQ_HEAD_INITIALIZER(module_builtins);
static struct modlist module_bootlist = TAILQ_HEAD_INITIALIZER(module_bootlist);
+struct module_callbacks {
+ TAILQ_ENTRY(module_callbacks) modcb_list;
+ void (*modcb_load)(struct module *);
+ void (*modcb_unload)(struct module *);
+};
+TAILQ_HEAD(modcblist, module_callbacks);
+static struct modcblist modcblist;
+
+static module_t *module_netbsd;
+static const modinfo_t module_netbsd_modinfo = {
+ .mi_version = __NetBSD_Version__,
+ .mi_class = MODULE_CLASS_MISC,
+ .mi_name = "netbsd"
+};
+
static module_t *module_active;
bool module_verbose_on;
#ifdef MODULAR_DEFAULT_AUTOLOAD
@@ -84,11 +99,14 @@
static kauth_listener_t module_listener;
+static specificdata_domain_t module_specificdata_domain;
+
/* Ensure that the kernel's link set isn't empty. */
static modinfo_t module_dummy;
__link_set_add_rodata(modules, module_dummy);
static module_t *module_newmodule(modsrc_t);
+static void module_free(module_t *);
static void module_require_force(module_t *);
static int module_do_load(const char *, bool, int, prop_dictionary_t,
module_t **, modclass_t modclass, bool);
@@ -106,6 +124,9 @@
static void sysctl_module_setup(void);
static int sysctl_module_autotime(SYSCTLFN_PROTO);
+static void module_callback_load(struct module *);
+static void module_callback_unload(struct module *);
+
#define MODULE_CLASS_MATCH(mi, modclass) \
((modclass) == MODULE_CLASS_ANY || (modclass) == (mi)->mi_class)
@@ -116,6 +137,13 @@
mi->mi_name, modclass, mi->mi_class);
}
+struct module *
+module_kernel(void)
+{
+
+ return module_netbsd;
+}
+
/*
* module_error:
*
@@ -152,6 +180,30 @@
}
}
+/*
+ * module_name:
+ *
+ * Utility function: return the module's name.
+ */
+const char *
+module_name(struct module *mod)
+{
+
+ return mod->mod_info->mi_name;
+}
+
+/*
+ * module_source:
+ *
+ * Utility function: return the module's source.
+ */
+modsrc_t
+module_source(struct module *mod)
+{
+
+ return mod->mod_source;
+}
+
static int
module_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
void *arg0, void *arg1, void *arg2, void *arg3)
@@ -179,12 +231,22 @@
mod = kmem_zalloc(sizeof(*mod), KM_SLEEP);
mod->mod_source = source;
- mod->mod_info = NULL;
- mod->mod_flags = 0;
+ specificdata_init(module_specificdata_domain, &mod->mod_sdref);
return mod;
}
/*
+ * Free a module_t
+ */
+static void
+module_free(module_t *mod)
+{
+
+ specificdata_fini(module_specificdata_domain, &mod->mod_sdref);
+ kmem_free(mod, sizeof(*mod));
+}
+
+/*
* Require the -f (force) flag to load a module
*/
static void
@@ -280,7 +342,7 @@
if (rv != 0) {
for (i = 0; i < nmodinfo; i++) {
if (modp[i])
- kmem_free(modp[i], sizeof(*modp[i]));
+ module_free(modp[i]);
}
}
kmem_free(modp, sizeof(*modp) * nmodinfo);
@@ -347,6 +409,7 @@
}
cv_init(&module_thread_cv, "mod_unld");
mutex_init(&module_thread_lock, MUTEX_DEFAULT, IPL_NONE);
+ TAILQ_INIT(&modcblist);
#ifdef MODULAR /* XXX */
module_init_md();
@@ -373,6 +436,11 @@
}
sysctl_module_setup();
+ module_specificdata_domain = specificdata_domain_create();
+
+ module_netbsd = module_newmodule(MODULE_SOURCE_KERNEL);
+ module_netbsd->mod_refcnt = 1;
+ module_netbsd->mod_info = &module_netbsd_modinfo;
}
/*
@@ -685,21 +753,13 @@
* responsibility to ensure that the reference is dropped
* later.
*/
-int
-module_hold(const char *name)
+void
+module_hold(module_t *mod)
{
- module_t *mod;
kernconfig_lock();
- mod = module_lookup(name);
- if (mod == NULL) {
- kernconfig_unlock();
- return ENOENT;
- }
mod->mod_refcnt++;
kernconfig_unlock();
-
- return 0;
}
/*
@@ -708,16 +768,11 @@
* Release a reference acquired with module_hold().
*/
void
-module_rele(const char *name)
+module_rele(module_t *mod)
{
- module_t *mod;
kernconfig_lock();
- mod = module_lookup(name);
- if (mod == NULL) {
- kernconfig_unlock();
- panic("%s: gone", __func__);
- }
+ KASSERT(mod->mod_refcnt > 0);
mod->mod_refcnt--;
kernconfig_unlock();
}
@@ -982,7 +1037,7 @@
module_error("vfs load failed for `%s', "
"error %d", name, error);
#endif
- kmem_free(mod, sizeof(*mod));
+ module_free(mod);
depth--;
return error;
}
@@ -1181,6 +1236,7 @@
}
depth--;
module_print("module `%s' loaded successfully", mi->mi_name);
+ module_callback_load(mod);
return 0;
fail1:
@@ -1193,7 +1249,7 @@
filedict = NULL;
}
TAILQ_REMOVE(pending, mod, mod_chain);
- kmem_free(mod, sizeof(*mod));
+ module_free(mod);
depth--;
return error;
}
@@ -1238,6 +1294,7 @@
prev_active = module_active;
module_active = mod;
+ module_callback_unload(mod);
error = (*mod->mod_info->mi_modcmd)(MODULE_CMD_FINI, NULL);
module_active = prev_active;
if (error != 0) {
@@ -1261,7 +1318,7 @@
TAILQ_INSERT_TAIL(&module_builtins, mod, mod_chain);
module_builtinlist++;
} else {
- kmem_free(mod, sizeof(*mod));
+ module_free(mod);
}
module_gen++;
@@ -1311,7 +1368,7 @@
error = kobj_load_mem(&mod->mod_kobj, name, base, size);
if (error != 0) {
- kmem_free(mod, sizeof(*mod));
+ module_free(mod);
module_error("unable to load `%s' pushed by boot loader, "
"error %d", name, error);
return error;
@@ -1319,7 +1376,7 @@
error = module_fetch_info(mod);
if (error != 0) {
kobj_unload(mod->mod_kobj);
- kmem_free(mod, sizeof(*mod));
+ module_free(mod);
module_error("unable to fetch_info for `%s' pushed by boot "
"loader, error %d", name, error);
return error;
@@ -1565,3 +1622,131 @@
return !error;
}
+
+/*
+ * module_specific_key_create:
+ *
+ * Create a key for subsystem module-specific data.
+ */
+specificdata_key_t
+module_specific_key_create(specificdata_key_t *keyp, specificdata_dtor_t dtor)
+{
+
+ return specificdata_key_create(module_specificdata_domain, keyp, dtor);
+}
+
+/*
+ * module_specific_key_delete:
+ *
+ * Delete a key for subsystem module-specific data.
+ */
+void
+module_specific_key_delete(specificdata_key_t key)
+{
+
+ return specificdata_key_delete(module_specificdata_domain, key);
+}
+
+/*
+ * module_getspecific:
+ *
Home |
Main Index |
Thread Index |
Old Index