Add support for load-time parameters for modules, which are passed through
a dictionary. As discussed in tech-kern@.
This commit is contained in:
parent
9edaf4a46f
commit
3fd8e29a11
@ -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.
|
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||||
@ -42,7 +42,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
@ -73,7 +73,8 @@ static modinfo_t module_dummy;
|
|||||||
__link_set_add_rodata(modules, module_dummy);
|
__link_set_add_rodata(modules, module_dummy);
|
||||||
|
|
||||||
static module_t *module_lookup(const char *);
|
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 int module_do_unload(const char *);
|
||||||
static void module_error(const char *, ...);
|
static void module_error(const char *, ...);
|
||||||
static int module_do_builtin(const char *, module_t **);
|
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();
|
* list as we call module_do_load();
|
||||||
*/
|
*/
|
||||||
while ((mod = TAILQ_FIRST(&module_bootlist)) != NULL) {
|
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);
|
mutex_exit(&module_lock);
|
||||||
}
|
}
|
||||||
@ -162,16 +164,15 @@ module_jettison(void)
|
|||||||
/*
|
/*
|
||||||
* module_load:
|
* module_load:
|
||||||
*
|
*
|
||||||
* Load a single module from the file system. If force is set,
|
* Load a single module from the file system.
|
||||||
* bypass the version check.
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
module_load(const char *filename, bool force)
|
module_load(const char *filename, int flags, prop_dictionary_t props)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
mutex_enter(&module_lock);
|
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);
|
mutex_exit(&module_lock);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
@ -374,7 +375,8 @@ module_do_builtin(const char *name, module_t **modp)
|
|||||||
* pushed by the boot loader.
|
* pushed by the boot loader.
|
||||||
*/
|
*/
|
||||||
static int
|
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 TAILQ_HEAD(,module) pending = TAILQ_HEAD_INITIALIZER(pending);
|
||||||
static int depth;
|
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");
|
module_error("self-dependency detected");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
error = module_do_load(buf, true, force,
|
error = module_do_load(buf, true, flags, NULL,
|
||||||
&mod->mod_required[mod->mod_nrequired++]);
|
&mod->mod_required[mod->mod_nrequired++]);
|
||||||
if (error != 0 && error != EEXIST)
|
if (error != 0 && error != EEXIST)
|
||||||
goto fail;
|
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.
|
* 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) {
|
if (error != 0) {
|
||||||
module_error("modctl function returned error %d", error);
|
module_error("modctl function returned error %d", error);
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -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.
|
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||||
@ -38,7 +38,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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/param.h>
|
||||||
#include <sys/systm.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/kauth.h>
|
||||||
#include <sys/kobj.h>
|
#include <sys/kobj.h>
|
||||||
#include <sys/kmem.h>
|
#include <sys/kmem.h>
|
||||||
|
#include <sys/malloc.h>
|
||||||
#include <sys/module.h>
|
#include <sys/module.h>
|
||||||
#include <sys/kauth.h>
|
#include <sys/kauth.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/syscallargs.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
|
int
|
||||||
sys_modctl(struct lwp *l, const struct sys_modctl_args *uap,
|
sys_modctl(struct lwp *l, const struct sys_modctl_args *uap,
|
||||||
register_t *retval)
|
register_t *retval)
|
||||||
@ -70,13 +124,11 @@ sys_modctl(struct lwp *l, const struct sys_modctl_args *uap,
|
|||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
int error;
|
int error;
|
||||||
void *arg;
|
void *arg;
|
||||||
char *path;
|
|
||||||
|
|
||||||
arg = SCARG(uap, arg);
|
arg = SCARG(uap, arg);
|
||||||
|
|
||||||
switch (SCARG(uap, cmd)) {
|
switch (SCARG(uap, cmd)) {
|
||||||
case MODCTL_LOAD:
|
case MODCTL_LOAD:
|
||||||
case MODCTL_FORCELOAD:
|
|
||||||
case MODCTL_UNLOAD:
|
case MODCTL_UNLOAD:
|
||||||
/* Authorize. */
|
/* Authorize. */
|
||||||
error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MODULE,
|
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)) {
|
switch (SCARG(uap, cmd)) {
|
||||||
case MODCTL_FORCELOAD:
|
|
||||||
case MODCTL_LOAD:
|
case MODCTL_LOAD:
|
||||||
path = PNBUF_GET();
|
error = handle_modctl_load(arg);
|
||||||
error = copyinstr(arg, path, MAXPATHLEN, NULL);
|
|
||||||
if (error == 0) {
|
|
||||||
error = module_load(path,
|
|
||||||
SCARG(uap, cmd) == MODCTL_FORCELOAD);
|
|
||||||
}
|
|
||||||
PNBUF_PUT(path);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MODCTL_UNLOAD:
|
case MODCTL_UNLOAD:
|
||||||
|
@ -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.
|
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||||
@ -92,6 +92,8 @@ typedef struct module {
|
|||||||
|
|
||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
|
|
||||||
|
#include <prop/proplib.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Per-module linkage. Loadable modules have a `link_set_modules' section
|
* Per-module linkage. Loadable modules have a `link_set_modules' section
|
||||||
* containing only one entry, pointing to the module's modinfo_t record.
|
* 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);
|
int module_prime(void *, size_t);
|
||||||
void module_jettison(void);
|
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_unload(const char *);
|
||||||
int module_hold(const char *);
|
int module_hold(const char *);
|
||||||
void module_rele(const char *);
|
void module_rele(const char *);
|
||||||
@ -132,9 +134,18 @@ void module_rele(const char *);
|
|||||||
|
|
||||||
#endif /* _KERNEL */
|
#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 {
|
typedef enum modctl {
|
||||||
MODCTL_LOAD, /* char *filename */
|
MODCTL_LOAD, /* modctl_load_t *ml */
|
||||||
MODCTL_FORCELOAD, /* char *filename */
|
|
||||||
MODCTL_UNLOAD, /* char *name */
|
MODCTL_UNLOAD, /* char *name */
|
||||||
MODCTL_STAT /* struct iovec *buffer */
|
MODCTL_STAT /* struct iovec *buffer */
|
||||||
} modctl_t;
|
} modctl_t;
|
||||||
|
Loading…
Reference in New Issue
Block a user