Some modules may want to avoid autounload because their use is transient.

Their FINI routine may legitimately succeed even though the module is likely
to be used soon again, for example: exec_script. Add a MODULE_CMD_AUTOUNLOAD
to query whether a module wants to avoid autounload.
This commit is contained in:
ad 2008-11-18 11:56:09 +00:00
parent f94a8f9142
commit 2bae5b390e
2 changed files with 20 additions and 7 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_module.c,v 1.27 2008/11/18 11:39:41 ad Exp $ */
/* $NetBSD: kern_module.c,v 1.28 2008/11/18 11:56:09 ad 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.27 2008/11/18 11:39:41 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.28 2008/11/18 11:56:09 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -841,6 +841,8 @@ static void
module_thread(void *cookie)
{
module_t *mod, *next;
modinfo_t *mi;
int error;
for (;;) {
mutex_enter(&module_lock);
@ -856,7 +858,17 @@ module_thread(void *cookie)
} else {
mod->mod_autotime = 0;
}
(void)module_do_unload(mod->mod_info->mi_name);
/*
* If this module wants to avoid autounload then
* skip it. Some modules can ping-pong in and out
* because their use is transient but often.
* Example: exec_script.
*/
mi = mod->mod_info;
error = (*mi->mi_modcmd)(MODULE_CMD_AUTOUNLOAD, NULL);
if (error == 0 || error == ENOTTY) {
(void)module_do_unload(mi->mi_name);
}
}
mutex_exit(&module_lock);

View File

@ -1,4 +1,4 @@
/* $NetBSD: module.h,v 1.11 2008/11/14 23:06:45 ad Exp $ */
/* $NetBSD: module.h,v 1.12 2008/11/18 11:56:09 ad Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -56,9 +56,10 @@ typedef enum modsrc {
/* Commands passed to module control routine. */
typedef enum modcmd {
MODULE_CMD_INIT,
MODULE_CMD_FINI,
MODULE_CMD_STAT
MODULE_CMD_INIT, /* mandatory */
MODULE_CMD_FINI, /* mandatory */
MODULE_CMD_STAT, /* optional */
MODULE_CMD_AUTOUNLOAD, /* optional */
} modcmd_t;
#ifdef _KERNEL