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;
 	}

Reply via email to