Module Name: src Committed By: pgoyette Date: Tue Sep 6 13:31:09 UTC 2022
Modified Files: src/sys/kern: kern_module.c Log Message: Resequence the sysctl_setup and evcnt stuff so that they always occur _before_ the module's MODULE_CMD_INIT call. Also update the unload code to invoke the sysctl_setup and evcnt stuff _after_ the module's MODULE_CMD_FINI call. This makes the behaviour and order consistent whether the module is built-in or loaded at run-time. As reported by riastradh@ To generate a diff of this commit: cvs rdiff -u -r1.158 -r1.159 src/sys/kern/kern_module.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_module.c diff -u src/sys/kern/kern_module.c:1.158 src/sys/kern/kern_module.c:1.159 --- src/sys/kern/kern_module.c:1.158 Fri Aug 12 15:17:10 2022 +++ src/sys/kern/kern_module.c Tue Sep 6 13:31:09 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_module.c,v 1.158 2022/08/12 15:17:10 riastradh Exp $ */ +/* $NetBSD: kern_module.c,v 1.159 2022/09/06 13:31:09 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.158 2022/08/12 15:17:10 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.159 2022/09/06 13:31:09 pgoyette Exp $"); #define _MODULE_INTERNAL @@ -1371,6 +1371,17 @@ module_do_load(const char *name, bool is prev_active = module_active; module_active = mod; + + /* + * Note that we handle sysctl and evcnt setup _before_ we + * initialize the module itself. This maintains a consistent + * order between built-in and run-time-loaded modules. If + * initialization then fails, we'll need to undo these, too. + */ + module_load_sysctl(mod); /* Set-up module's sysctl if any */ + module_load_evcnt(mod); /* Attach any static evcnt needed */ + + error = (*mi->mi_modcmd)(MODULE_CMD_INIT, filedict ? filedict : props); module_active = prev_active; if (filedict) { @@ -1380,7 +1391,7 @@ module_do_load(const char *name, bool is if (error != 0) { module_error("modcmd(CMD_INIT) failed for `%s', error %d", mi->mi_name, error); - goto fail; + goto fail3; } /* @@ -1395,9 +1406,6 @@ module_do_load(const char *name, bool is goto fail1; } - module_load_sysctl(mod); /* Set-up module's sysctl if any */ - module_load_evcnt(mod); /* Attach any static evcnt needed */ - /* * Good, the module loaded successfully. Put it onto the * list and add references to its requisite modules. @@ -1423,6 +1431,16 @@ module_do_load(const char *name, bool is fail1: (*mi->mi_modcmd)(MODULE_CMD_FINI, NULL); + fail3: + /* + * If there were any registered SYSCTL_SETUP funcs, make sure + * we release the sysctl entries + */ + if (mod->mod_sysctllog) { + sysctl_teardown(&mod->mod_sysctllog); + } + /* Also detach any static evcnt's */ + module_unload_evcnt(mod); fail: kobj_unload(mod->mod_kobj); fail2: @@ -1478,20 +1496,22 @@ module_do_unload(const char *name, bool module_active = mod; module_callback_unload(mod); + /* let the module clean up after itself */ + error = (*mod->mod_info->mi_modcmd)(MODULE_CMD_FINI, NULL); + /* * If there were any registered SYSCTL_SETUP funcs, make sure - * we release the sysctl entries + * we release the sysctl entries. Same for static evcnt. */ - if (mod->mod_sysctllog) { - sysctl_teardown(&mod->mod_sysctllog); + if (error == 0) { + if (mod->mod_sysctllog) { + sysctl_teardown(&mod->mod_sysctllog); + } + module_unload_evcnt(mod); } - module_unload_evcnt(mod); - error = (*mod->mod_info->mi_modcmd)(MODULE_CMD_FINI, NULL); module_active = prev_active; if (error != 0) { - module_load_sysctl(mod); /* re-enable sysctl stuff */ - module_load_evcnt(mod); /* and reenable evcnts */ - module_print("cannot unload module `%s' error=%d", name, + module_print("could not unload module `%s' error=%d", name, error); return error; }