Add support for load-time parameters for modules, which are passed through

a dictionary.  As discussed in tech-kern@.
This commit is contained in:
jmmv 2008-03-02 11:18:43 +00:00
parent 9edaf4a46f
commit 3fd8e29a11
3 changed files with 85 additions and 27 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_module.c,v 1.8 2008/01/19 18:20:39 rumble Exp $ */
/* $NetBSD: kern_module.c,v 1.9 2008/03/02 11:18:43 jmmv Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.8 2008/01/19 18:20:39 rumble Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.9 2008/03/02 11:18:43 jmmv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -73,7 +73,8 @@ static modinfo_t module_dummy;
__link_set_add_rodata(modules, module_dummy);
static module_t *module_lookup(const char *);
static int module_do_load(const char *, bool, bool, module_t **);
static int module_do_load(const char *, bool, int, prop_dictionary_t,
module_t **);
static int module_do_unload(const char *);
static void module_error(const char *, ...);
static int module_do_builtin(const char *, module_t **);
@ -142,7 +143,8 @@ module_init_class(modclass_t class)
* list as we call module_do_load();
*/
while ((mod = TAILQ_FIRST(&module_bootlist)) != NULL) {
module_do_load(mod->mod_info->mi_name, false, false, NULL);
module_do_load(mod->mod_info->mi_name, false, 0,
NULL, NULL);
}
mutex_exit(&module_lock);
}
@ -162,16 +164,15 @@ module_jettison(void)
/*
* module_load:
*
* Load a single module from the file system. If force is set,
* bypass the version check.
* Load a single module from the file system.
*/
int
module_load(const char *filename, bool force)
module_load(const char *filename, int flags, prop_dictionary_t props)
{
int error;
mutex_enter(&module_lock);
error = module_do_load(filename, false, force, NULL);
error = module_do_load(filename, false, flags, props, NULL);
mutex_exit(&module_lock);
return error;
@ -374,7 +375,8 @@ module_do_builtin(const char *name, module_t **modp)
* pushed by the boot loader.
*/
static int
module_do_load(const char *filename, bool isdep, bool force, module_t **modp)
module_do_load(const char *filename, bool isdep, int flags,
prop_dictionary_t props, module_t **modp)
{
static TAILQ_HEAD(,module) pending = TAILQ_HEAD_INITIALIZER(pending);
static int depth;
@ -545,7 +547,7 @@ module_do_load(const char *filename, bool isdep, bool force, module_t **modp)
module_error("self-dependency detected");
goto fail;
}
error = module_do_load(buf, true, force,
error = module_do_load(buf, true, flags, NULL,
&mod->mod_required[mod->mod_nrequired++]);
if (error != 0 && error != EEXIST)
goto fail;
@ -555,7 +557,7 @@ module_do_load(const char *filename, bool isdep, bool force, module_t **modp)
/*
* We loaded all needed modules successfully: initialize.
*/
error = (*mi->mi_modcmd)(MODULE_CMD_INIT, NULL);
error = (*mi->mi_modcmd)(MODULE_CMD_INIT, props);
if (error != 0) {
module_error("modctl function returned error %d", error);
goto fail;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sys_module.c,v 1.3 2008/01/17 22:30:54 rumble Exp $ */
/* $NetBSD: sys_module.c,v 1.4 2008/03/02 11:18:43 jmmv Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sys_module.c,v 1.3 2008/01/17 22:30:54 rumble Exp $");
__KERNEL_RCSID(0, "$NetBSD: sys_module.c,v 1.4 2008/03/02 11:18:43 jmmv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -47,11 +47,65 @@ __KERNEL_RCSID(0, "$NetBSD: sys_module.c,v 1.3 2008/01/17 22:30:54 rumble Exp $"
#include <sys/kauth.h>
#include <sys/kobj.h>
#include <sys/kmem.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/kauth.h>
#include <sys/syscall.h>
#include <sys/syscallargs.h>
static
int
handle_modctl_load(void *arg)
{
modctl_load_t *ml = (modctl_load_t *)arg;
char *path;
char *props;
int error;
prop_dictionary_t dict;
size_t propslen;
if ((ml->ml_props != NULL && ml->ml_propslen == 0) ||
(ml->ml_props == NULL && ml->ml_propslen > 0)) {
error = EINVAL;
goto out1;
}
path = PNBUF_GET();
error = copyinstr(ml->ml_filename, path, MAXPATHLEN, NULL);
if (error != 0)
goto out2;
propslen = ml->ml_propslen + 1;
props = (char *)malloc(propslen, M_TEMP, M_WAITOK|M_CANFAIL);
if (props == NULL) {
error = ENOMEM;
goto out2;
}
error = copyinstr(ml->ml_props, props, propslen, NULL);
if (error != 0)
goto out3;
dict = prop_dictionary_internalize(props);
if (dict == NULL) {
error = EINVAL;
goto out3;
}
error = module_load(path, ml->ml_flags, dict);
prop_object_release(dict);
out3:
free(props, M_TEMP);
out2:
PNBUF_PUT(path);
out1:
return error;
}
int
sys_modctl(struct lwp *l, const struct sys_modctl_args *uap,
register_t *retval)
@ -70,13 +124,11 @@ sys_modctl(struct lwp *l, const struct sys_modctl_args *uap,
struct iovec iov;
int error;
void *arg;
char *path;
arg = SCARG(uap, arg);
switch (SCARG(uap, cmd)) {
case MODCTL_LOAD:
case MODCTL_FORCELOAD:
case MODCTL_UNLOAD:
/* Authorize. */
error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MODULE,
@ -90,15 +142,8 @@ sys_modctl(struct lwp *l, const struct sys_modctl_args *uap,
}
switch (SCARG(uap, cmd)) {
case MODCTL_FORCELOAD:
case MODCTL_LOAD:
path = PNBUF_GET();
error = copyinstr(arg, path, MAXPATHLEN, NULL);
if (error == 0) {
error = module_load(path,
SCARG(uap, cmd) == MODCTL_FORCELOAD);
}
PNBUF_PUT(path);
error = handle_modctl_load(arg);
break;
case MODCTL_UNLOAD:

View File

@ -1,4 +1,4 @@
/* $NetBSD: module.h,v 1.1 2008/01/16 12:34:54 ad Exp $ */
/* $NetBSD: module.h,v 1.2 2008/03/02 11:18:43 jmmv Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -92,6 +92,8 @@ typedef struct module {
#include <sys/mutex.h>
#include <prop/proplib.h>
/*
* Per-module linkage. Loadable modules have a `link_set_modules' section
* containing only one entry, pointing to the module's modinfo_t record.
@ -121,7 +123,7 @@ void module_init_class(modclass_t);
int module_prime(void *, size_t);
void module_jettison(void);
int module_load(const char *, bool);
int module_load(const char *, int, prop_dictionary_t);
int module_unload(const char *);
int module_hold(const char *);
void module_rele(const char *);
@ -132,9 +134,18 @@ void module_rele(const char *);
#endif /* _KERNEL */
typedef struct modctl_load {
const char *ml_filename;
#define MODCTL_LOAD_FORCE 1
int ml_flags;
const char *ml_props;
size_t ml_propslen;
} modctl_load_t;
typedef enum modctl {
MODCTL_LOAD, /* char *filename */
MODCTL_FORCELOAD, /* char *filename */
MODCTL_LOAD, /* modctl_load_t *ml */
MODCTL_UNLOAD, /* char *name */
MODCTL_STAT /* struct iovec *buffer */
} modctl_t;