Tue Jun 9 19:09:03 2009 UTC ()
Add code to merge the modload "command line" with <module>.prop.


(jnemeth)
diff -r1.46 -r1.47 src/sys/kern/kern_module.c

cvs diff -r1.46 -r1.47 src/sys/kern/kern_module.c (expand / switch to unified diff)

--- src/sys/kern/kern_module.c 2009/06/07 09:47:31 1.46
+++ src/sys/kern/kern_module.c 2009/06/09 19:09:03 1.47
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: kern_module.c,v 1.46 2009/06/07 09:47:31 jnemeth Exp $ */ 1/* $NetBSD: kern_module.c,v 1.47 2009/06/09 19:09:03 jnemeth Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software developed for The NetBSD Foundation 7 * This code is derived from software developed for The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Kernel module support. 33 * Kernel module support.
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.46 2009/06/07 09:47:31 jnemeth Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.47 2009/06/09 19:09:03 jnemeth Exp $");
38 38
39#ifdef _KERNEL_OPT 39#ifdef _KERNEL_OPT
40#include "opt_ddb.h" 40#include "opt_ddb.h"
41#include "opt_modular.h" 41#include "opt_modular.h"
42#endif 42#endif
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/systm.h> 45#include <sys/systm.h>
46#include <sys/kernel.h> 46#include <sys/kernel.h>
47#include <sys/fcntl.h> 47#include <sys/fcntl.h>
48#include <sys/proc.h> 48#include <sys/proc.h>
49#include <sys/kauth.h> 49#include <sys/kauth.h>
50#include <sys/kobj.h> 50#include <sys/kobj.h>
@@ -85,26 +85,27 @@ __link_set_add_rodata(modules, module_du @@ -85,26 +85,27 @@ __link_set_add_rodata(modules, module_du
85static module_t *module_lookup(const char *); 85static module_t *module_lookup(const char *);
86static int module_do_load(const char *, bool, int, prop_dictionary_t, 86static int module_do_load(const char *, bool, int, prop_dictionary_t,
87 module_t **, modclass_t class, bool); 87 module_t **, modclass_t class, bool);
88static int module_do_unload(const char *); 88static int module_do_unload(const char *);
89static void module_error(const char *, ...) 89static void module_error(const char *, ...)
90 __attribute__((__format__(__printf__,1,2))); 90 __attribute__((__format__(__printf__,1,2)));
91static void module_print(const char *, ...) 91static void module_print(const char *, ...)
92 __attribute__((__format__(__printf__,1,2))); 92 __attribute__((__format__(__printf__,1,2)));
93static int module_do_builtin(const char *, module_t **); 93static int module_do_builtin(const char *, module_t **);
94static int module_fetch_info(module_t *); 94static int module_fetch_info(module_t *);
95static void module_thread(void *); 95static void module_thread(void *);
96static int module_load_plist_file(const char *, const bool, void **, 96static int module_load_plist_file(const char *, const bool, void **,
97 size_t *); 97 size_t *);
 98static bool module_merge_dicts(prop_dictionary_t, const prop_dictionary_t);
98 99
99/* 100/*
100 * module_error: 101 * module_error:
101 * 102 *
102 * Utility function: log an error. 103 * Utility function: log an error.
103 */ 104 */
104static void 105static void
105module_error(const char *fmt, ...) 106module_error(const char *fmt, ...)
106{ 107{
107 va_list ap; 108 va_list ap;
108 109
109 va_start(ap, fmt); 110 va_start(ap, fmt);
110 printf("WARNING: module error: "); 111 printf("WARNING: module error: ");
@@ -787,40 +788,44 @@ module_do_load(const char *name, bool is @@ -787,40 +788,44 @@ module_do_load(const char *name, bool is
787 /* 788 /*
788 * Load and process <module>.prop if it exists. 789 * Load and process <module>.prop if it exists.
789 */ 790 */
790 if (mod->mod_source == MODULE_SOURCE_FILESYS) { 791 if (mod->mod_source == MODULE_SOURCE_FILESYS) {
791 error = module_load_plist_file(path, nochroot, &plist, 792 error = module_load_plist_file(path, nochroot, &plist,
792 &plistlen); 793 &plistlen);
793 if (error != 0) { 794 if (error != 0) {
794 module_print("plist load returned error %d for `%s'", 795 module_print("plist load returned error %d for `%s'",
795 error, path); 796 error, path);
796 } else { 797 } else {
797 filedict = prop_dictionary_internalize(plist); 798 filedict = prop_dictionary_internalize(plist);
798 if (filedict == NULL) { 799 if (filedict == NULL) {
799 error = EINVAL; 800 error = EINVAL;
 801 } else if (!module_merge_dicts(filedict, props)) {
 802 error = EINVAL;
 803 prop_object_release(filedict);
 804 filedict = NULL;
800 } 805 }
801 } 806 }
802 if (plist != NULL) { 807 if (plist != NULL) {
803 kmem_free(plist, PAGE_SIZE); 808 kmem_free(plist, PAGE_SIZE);
804 } 809 }
805 if ((error != 0) && (error != ENOENT)) { 810 if ((error != 0) && (error != ENOENT)) {
806 goto fail; 811 goto fail;
807 } 812 }
808 } 813 }
809 814
810 KASSERT(module_active == NULL); 815 KASSERT(module_active == NULL);
811 module_active = mod; 816 module_active = mod;
812 error = (*mi->mi_modcmd)(MODULE_CMD_INIT, (filedict != NULL) ? 817 error = (*mi->mi_modcmd)(MODULE_CMD_INIT, (filedict != NULL) ?
813 filedict : props); 818 filedict : props); /* props will have been merged with filedict */
814 module_active = NULL; 819 module_active = NULL;
815 if (filedict != NULL) { 820 if (filedict != NULL) {
816 prop_object_release(filedict); 821 prop_object_release(filedict);
817 } 822 }
818 if (error != 0) { 823 if (error != 0) {
819 module_error("modcmd function returned error %d for `%s'", 824 module_error("modcmd function returned error %d for `%s'",
820 error, mi->mi_name); 825 error, mi->mi_name);
821 goto fail; 826 goto fail;
822 } 827 }
823 828
824 /* 829 /*
825 * Good, the module loaded successfully. Put it onto the 830 * Good, the module loaded successfully. Put it onto the
826 * list and add references to its requisite modules. 831 * list and add references to its requisite modules.
@@ -1187,13 +1192,47 @@ module_load_plist_file(const char *modpa @@ -1187,13 +1192,47 @@ module_load_plist_file(const char *modpa
1187 base = NULL; 1192 base = NULL;
1188 } 1193 }
1189 *length = sb.st_size; 1194 *length = sb.st_size;
1190 1195
1191out: 1196out:
1192 VOP_UNLOCK(nd.ni_vp, 0); 1197 VOP_UNLOCK(nd.ni_vp, 0);
1193 vn_close(nd.ni_vp, FREAD, kauth_cred_get()); 1198 vn_close(nd.ni_vp, FREAD, kauth_cred_get());
1194 1199
1195out1: 1200out1:
1196 PNBUF_PUT(proppath); 1201 PNBUF_PUT(proppath);
1197 *basep = base; 1202 *basep = base;
1198 return error; 1203 return error;
1199} 1204}
 1205
 1206static bool
 1207module_merge_dicts(prop_dictionary_t existing_dict,
 1208 const prop_dictionary_t new_dict)
 1209{
 1210 prop_dictionary_keysym_t props_keysym;
 1211 prop_object_iterator_t props_iter;
 1212 prop_object_t props_obj;
 1213 const char *props_key;
 1214 bool error;
 1215
 1216 error = false;
 1217 props_iter = prop_dictionary_iterator(new_dict);
 1218 if (props_iter == NULL) {
 1219 return false;
 1220 }
 1221
 1222 while ((props_obj = prop_object_iterator_next(props_iter)) != NULL) {
 1223 props_keysym = (prop_dictionary_keysym_t)props_obj;
 1224 props_key = prop_dictionary_keysym_cstring_nocopy(props_keysym);
 1225 props_obj = prop_dictionary_get_keysym(new_dict, props_keysym);
 1226 if ((props_obj == NULL) || !prop_dictionary_set(existing_dict,
 1227 props_key, props_obj)) {
 1228 error = true;
 1229 goto out;
 1230 }
 1231 }
 1232 error = false;
 1233
 1234out:
 1235 prop_object_iterator_release(props_iter);
 1236
 1237 return !error;
 1238}