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