Module Name: src Committed By: pooka Date: Wed Nov 18 17:40:45 UTC 2009
Modified Files: src/sys/conf: files src/sys/kern: kern_module.c src/sys/sys: module.h Added Files: src/sys/kern: kern_module_vfs.c Log Message: * make it possible to include kern_module in a kernel without vfs support, i.e. move vfs functionality to a separate module (kern_module_vfs.c) * make module proplist size an MI constant (now 8k) instead of PAGE_SIZE * change some error values to something else than the karmic EINVAL To generate a diff of this commit: cvs rdiff -u -r1.963 -r1.964 src/sys/conf/files cvs rdiff -u -r1.53 -r1.54 src/sys/kern/kern_module.c cvs rdiff -u -r0 -r1.1 src/sys/kern/kern_module_vfs.c cvs rdiff -u -r1.17 -r1.18 src/sys/sys/module.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/conf/files diff -u src/sys/conf/files:1.963 src/sys/conf/files:1.964 --- src/sys/conf/files:1.963 Thu Nov 12 18:37:10 2009 +++ src/sys/conf/files Wed Nov 18 17:40:45 2009 @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.963 2009/11/12 18:37:10 snj Exp $ +# $NetBSD: files,v 1.964 2009/11/18 17:40:45 pooka Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 version 20090313 @@ -1438,6 +1438,7 @@ file kern/kern_malloc_stdtype.c file kern/kern_malloc_debug.c malloc_debug file kern/kern_module.c +file kern/kern_module_vfs.c file kern/kern_mutex.c file kern/kern_mutex_obj.c file kern/kern_fileassoc.c fileassoc Index: src/sys/kern/kern_module.c diff -u src/sys/kern/kern_module.c:1.53 src/sys/kern/kern_module.c:1.54 --- src/sys/kern/kern_module.c:1.53 Thu Nov 5 14:09:14 2009 +++ src/sys/kern/kern_module.c Wed Nov 18 17:40:45 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_module.c,v 1.53 2009/11/05 14:09:14 pooka Exp $ */ +/* $NetBSD: kern_module.c,v 1.54 2009/11/18 17:40:45 pooka Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -34,7 +34,9 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.53 2009/11/05 14:09:14 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.54 2009/11/18 17:40:45 pooka Exp $"); + +#define _MODULE_INTERNAL #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -44,7 +46,6 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/fcntl.h> #include <sys/proc.h> #include <sys/kauth.h> #include <sys/kobj.h> @@ -53,21 +54,18 @@ #include <sys/kauth.h> #include <sys/kthread.h> #include <sys/sysctl.h> -#include <sys/namei.h> #include <sys/lock.h> -#include <sys/vnode.h> -#include <sys/stat.h> #include <uvm/uvm_extern.h> #include <machine/stdarg.h> struct vm_map *module_map; +char module_base[MODULE_BASE_SIZE]; struct modlist module_list = TAILQ_HEAD_INITIALIZER(module_list); struct modlist module_bootlist = TAILQ_HEAD_INITIALIZER(module_bootlist); static module_t *module_active; -static char module_base[64]; static int module_verbose_on; static int module_autoload_on = 1; u_int module_count; @@ -87,23 +85,28 @@ static int module_do_load(const char *, bool, int, prop_dictionary_t, module_t **, modclass_t class, bool); static int module_do_unload(const char *); -static void module_error(const char *, ...) - __attribute__((__format__(__printf__,1,2))); -static void module_print(const char *, ...) - __attribute__((__format__(__printf__,1,2))); static int module_do_builtin(const char *, module_t **); static int module_fetch_info(module_t *); static void module_thread(void *); -static int module_load_plist_file(const char *, const bool, void **, - size_t *); + static bool module_merge_dicts(prop_dictionary_t, const prop_dictionary_t); +int module_eopnotsupp(void); + +int +module_eopnotsupp(void) +{ + + return EOPNOTSUPP; +} +__weak_alias(module_load_vfs,module_eopnotsupp); + /* * module_error: * * Utility function: log an error. */ -static void +void module_error(const char *fmt, ...) { va_list ap; @@ -120,7 +123,7 @@ * * Utility function: log verbose output. */ -static void +void module_print(const char *fmt, ...) { va_list ap; @@ -601,19 +604,15 @@ modinfo_t *mi; module_t *mod, *mod2; prop_dictionary_t filedict; - void *plist; - char buf[MAXMODNAME], *path; + char buf[MAXMODNAME]; const char *s, *p; int error; - size_t len, plistlen; - bool nochroot; + size_t len; KASSERT(mutex_owned(&module_lock)); filedict = NULL; - path = NULL; error = 0; - nochroot = false; /* * Avoid recursing too far. @@ -664,33 +663,16 @@ depth--; return ENOMEM; } - path = PNBUF_GET(); - if (!autoload) { - nochroot = false; - snprintf(path, MAXPATHLEN, "%s", name); - error = kobj_load_file(&mod->mod_kobj, path, nochroot); - } - if (autoload || (error == ENOENT)) { - nochroot = true; - snprintf(path, MAXPATHLEN, "%s/%s/%s.kmod", - module_base, name, name); - error = kobj_load_file(&mod->mod_kobj, path, nochroot); - } + + error = module_load_vfs(name, flags, autoload, mod, &filedict); if (error != 0) { kmem_free(mod, sizeof(*mod)); depth--; - PNBUF_PUT(path); - if (autoload) { - module_print("Cannot load kernel object `%s'" - " error=%d", name, error); - } else { - module_error("Cannot load kernel object `%s'" - " error=%d", name, error); - } return error; } - TAILQ_INSERT_TAIL(&pending, mod, mod_chain); mod->mod_source = MODULE_SOURCE_FILESYS; + TAILQ_INSERT_TAIL(&pending, mod, mod_chain); + error = module_fetch_info(mod); if (error != 0) { module_error("cannot fetch module info for `%s'", @@ -820,47 +802,27 @@ goto fail2; } - /* - * Load and process <module>.prop if it exists. - */ - if (((flags & MODCTL_NO_PROP) == 0) && - (mod->mod_source == MODULE_SOURCE_FILESYS)) { - error = module_load_plist_file(path, nochroot, &plist, - &plistlen); - if (error != 0) { - module_print("plist load returned error %d for `%s'", - error, path); - } else { - filedict = prop_dictionary_internalize(plist); - if (filedict == NULL) { - error = EINVAL; - } else if (!module_merge_dicts(filedict, props)) { - error = EINVAL; - prop_object_release(filedict); - filedict = NULL; - } - } - if (plist != NULL) { - kmem_free(plist, PAGE_SIZE); - } - if ((error != 0) && (error != ENOENT)) { + if (filedict) { + if (!module_merge_dicts(filedict, props)) { + module_error("module properties failed"); + error = EINVAL; goto fail; } } - KASSERT(module_active == NULL); module_active = mod; - error = (*mi->mi_modcmd)(MODULE_CMD_INIT, (filedict != NULL) ? - filedict : props); /* props will have been merged with filedict */ + error = (*mi->mi_modcmd)(MODULE_CMD_INIT, filedict ? filedict : props); module_active = NULL; - if (filedict != NULL) { + if (filedict) { prop_object_release(filedict); + filedict = NULL; } if (error != 0) { module_error("modcmd function returned error %d for `%s'", error, mi->mi_name); goto fail; } + if (mi->mi_class == MODULE_CLASS_SECMODEL) secmodel_register(); @@ -882,18 +844,18 @@ module_thread_kick(); } depth--; - if (path != NULL) - PNBUF_PUT(path); return 0; fail: kobj_unload(mod->mod_kobj); fail2: + if (filedict != NULL) { + prop_object_release(filedict); + filedict = NULL; + } TAILQ_REMOVE(&pending, mod, mod_chain); kmem_free(mod, sizeof(*mod)); depth--; - if (path != NULL) - PNBUF_PUT(path); return error; } @@ -1163,86 +1125,6 @@ } #endif /* DDB */ -/* - * module_load_plist_file: - * - * Load a plist located in the file system into memory. - */ -static int -module_load_plist_file(const char *modpath, const bool nochroot, - void **basep, size_t *length) -{ - struct nameidata nd; - struct stat sb; - void *base; - char *proppath; - size_t resid; - int error, pathlen; - - base = NULL; - *length = 0; - - proppath = PNBUF_GET(); - strcpy(proppath, modpath); - pathlen = strlen(proppath); - if ((pathlen >= 5) && (strcmp(&proppath[pathlen - 5], ".kmod") == 0)) { - strcpy(&proppath[pathlen - 5], ".prop"); - } else if (pathlen < MAXPATHLEN - 5) { - strcat(proppath, ".prop"); - } else { - error = ENOENT; - goto out1; - } - - NDINIT(&nd, LOOKUP, FOLLOW | (nochroot ? NOCHROOT : 0), - UIO_SYSSPACE, proppath); - - error = namei(&nd); - if (error != 0) { - goto out1; - } - - error = vn_stat(nd.ni_vp, &sb); - if (sb.st_size >= (PAGE_SIZE - 1)) { /* leave space for term \0 */ - error = EINVAL; - } - if (error != 0) { - goto out1; - } - - error = vn_open(&nd, FREAD, 0); - if (error != 0) { - goto out1; - } - - base = kmem_alloc(PAGE_SIZE, KM_SLEEP); - if (base == NULL) { - error = ENOMEM; - goto out; - } - - error = vn_rdwr(UIO_READ, nd.ni_vp, base, sb.st_size, 0, - UIO_SYSSPACE, IO_NODELOCKED, curlwp->l_cred, &resid, curlwp); - *((uint8_t *)base + sb.st_size) = '\0'; - if (error == 0 && resid != 0) { - error = EINVAL; - } - if (error != 0) { - kmem_free(base, PAGE_SIZE); - base = NULL; - } - *length = sb.st_size; - -out: - VOP_UNLOCK(nd.ni_vp, 0); - vn_close(nd.ni_vp, FREAD, kauth_cred_get()); - -out1: - PNBUF_PUT(proppath); - *basep = base; - return error; -} - static bool module_merge_dicts(prop_dictionary_t existing_dict, const prop_dictionary_t new_dict) Index: src/sys/sys/module.h diff -u src/sys/sys/module.h:1.17 src/sys/sys/module.h:1.18 --- src/sys/sys/module.h:1.17 Thu Nov 5 14:09:14 2009 +++ src/sys/sys/module.h Wed Nov 18 17:40:45 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: module.h,v 1.17 2009/11/05 14:09:14 pooka Exp $ */ +/* $NetBSD: module.h,v 1.18 2009/11/18 17:40:45 pooka Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -135,6 +135,19 @@ void module_whatis(uintptr_t, void (*)(const char *, ...)); void module_print_list(void (*)(const char *, ...)); + +#ifdef _MODULE_INTERNAL +int module_load_vfs(const char *, int, bool, module_t *, + prop_dictionary_t *); +void module_error(const char *, ...) + __attribute__((__format__(__printf__,1,2))); +void module_print(const char *, ...) + __attribute__((__format__(__printf__,1,2))); + +#define MODULE_BASE_SIZE 64 +extern char module_base[MODULE_BASE_SIZE]; +#endif /* _MODULE_INTERNAL */ + #else /* _KERNEL */ #include <stdint.h> Added files: Index: src/sys/kern/kern_module_vfs.c diff -u /dev/null src/sys/kern/kern_module_vfs.c:1.1 --- /dev/null Wed Nov 18 17:40:45 2009 +++ src/sys/kern/kern_module_vfs.c Wed Nov 18 17:40:45 2009 @@ -0,0 +1,201 @@ +/* $NetBSD: kern_module_vfs.c,v 1.1 2009/11/18 17:40:45 pooka Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software developed for The NetBSD Foundation + * by Andrew Doran. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Kernel module file system interaction. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: kern_module_vfs.c,v 1.1 2009/11/18 17:40:45 pooka Exp $"); + +#define _MODULE_INTERNAL +#include <sys/param.h> +#include <sys/fcntl.h> +#include <sys/kmem.h> +#include <sys/kobj.h> +#include <sys/module.h> +#include <sys/namei.h> +#include <sys/pool.h> +#include <sys/stat.h> +#include <sys/vnode.h> + +#include <prop/proplib.h> + +static int module_load_plist_file(const char *, const bool, + prop_dictionary_t *); + +int +module_load_vfs(const char *name, int flags, bool autoload, + module_t *mod, prop_dictionary_t *filedictp) +{ + char *path; + bool nochroot; + int error; + + nochroot = false; + error = 0; + path = NULL; + if (filedictp) + *filedictp = NULL; + path = PNBUF_GET(); + + if (!autoload) { + nochroot = false; + snprintf(path, MAXPATHLEN, "%s", name); + error = kobj_load_file(&mod->mod_kobj, path, nochroot); + } + if (autoload || (error == ENOENT)) { + nochroot = true; + snprintf(path, MAXPATHLEN, "%s/%s/%s.kmod", + module_base, name, name); + error = kobj_load_file(&mod->mod_kobj, path, nochroot); + } + if (error != 0) { + PNBUF_PUT(path); + if (autoload) { + module_print("Cannot load kernel object `%s'" + " error=%d", name, error); + } else { + module_error("Cannot load kernel object `%s'" + " error=%d", name, error); + } + return error; + } + + /* + * Load and process <module>.prop if it exists. + */ + if ((flags & MODCTL_NO_PROP) == 0 && filedictp) { + error = module_load_plist_file(path, nochroot, filedictp); + if (error != 0) { + module_print("plist load returned error %d for `%s'", + error, path); + if (error != ENOENT) + goto fail; + } + } + + PNBUF_PUT(path); + return 0; + + fail: + kobj_unload(mod->mod_kobj); + PNBUF_PUT(path); + return error; +} + +/* + * module_load_plist_file: + * + * Load a plist located in the file system into memory. + */ +static int +module_load_plist_file(const char *modpath, const bool nochroot, + prop_dictionary_t *filedictp) +{ + struct nameidata nd; + struct stat sb; + void *base; + char *proppath; + const size_t plistsize = 8192; + size_t resid; + int error, pathlen; + + KASSERT(filedictp != NULL); + base = NULL; + + proppath = PNBUF_GET(); + strcpy(proppath, modpath); + pathlen = strlen(proppath); + if ((pathlen >= 5) && (strcmp(&proppath[pathlen - 5], ".kmod") == 0)) { + strcpy(&proppath[pathlen - 5], ".prop"); + } else if (pathlen < MAXPATHLEN - 5) { + strcat(proppath, ".prop"); + } else { + error = ENOENT; + goto out1; + } + + NDINIT(&nd, LOOKUP, FOLLOW | (nochroot ? NOCHROOT : 0), + UIO_SYSSPACE, proppath); + + error = namei(&nd); + if (error != 0) { + goto out1; + } + + error = vn_stat(nd.ni_vp, &sb); + if (sb.st_size >= (plistsize - 1)) { /* leave space for term \0 */ + error = EFBIG; + } + if (error != 0) { + goto out1; + } + + error = vn_open(&nd, FREAD, 0); + if (error != 0) { + goto out1; + } + + base = kmem_alloc(plistsize, KM_SLEEP); + if (base == NULL) { + error = ENOMEM; + goto out; + } + + error = vn_rdwr(UIO_READ, nd.ni_vp, base, sb.st_size, 0, + UIO_SYSSPACE, IO_NODELOCKED, curlwp->l_cred, &resid, curlwp); + *((uint8_t *)base + sb.st_size) = '\0'; + if (error == 0 && resid != 0) { + error = EFBIG; + } + if (error != 0) { + kmem_free(base, plistsize); + base = NULL; + goto out; + } + + *filedictp = prop_dictionary_internalize(base); + if (*filedictp == NULL) { + error = EINVAL; + } + kmem_free(base, plistsize); + base = NULL; + KASSERT(error == 0); + +out: + VOP_UNLOCK(nd.ni_vp, 0); + vn_close(nd.ni_vp, FREAD, kauth_cred_get()); + +out1: + PNBUF_PUT(proppath); + return error; +}