aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Cromie <jim.cromie@gmail.com>2012-04-27 16:30:34 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-30 14:05:27 -0400
commit9fb48c744ba6a4bf58b666f4e6fdac3008ea1bd4 (patch)
treef145e07824a3a9bae9f8da3e5c39ea5073bd872e
parent3faa286055c02291dc9b6d838601dcb105a64a14 (diff)
params: add 3rd arg to option handler callback signature
Add a 3rd arg, named "doing", to unknown-options callbacks invoked from parse_args(). The arg is passed as: "Booting kernel" from start_kernel(), initcall_level_names[i] from do_initcall_level(), mod->name from load_module(), via parse_args(), parse_one() parse_args() already has the "name" parameter, which is renamed to "doing" to better reflect current uses 1,2 above. parse_args() passes it to an altered parse_one(), which now passes it down into the unknown option handler callbacks. The mod->name will be needed to handle dyndbg for loadable modules, since params passed by modprobe are not qualified (they do not have a "$modname." prefix), and by the time the unknown-param callback is called, the module name is not otherwise available. Minor tweaks: Add param-name to parse_one's pr_debug(), current message doesnt identify the param being handled, add it. Add a pr_info to print current level and level_name of the initcall, and number of registered initcalls at that level. This adds 7 lines to dmesg output, like: initlevel:6=device, 172 registered initcalls Drop "parameters" from initcall_level_names[], its unhelpful in the pr_info() added above. This array is passed into parse_args() by do_initcall_level(). CC: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Jim Cromie <jim.cromie@gmail.com> Acked-by: Jason Baron <jbaron@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--include/linux/moduleparam.h3
-rw-r--r--init/main.c33
-rw-r--r--kernel/params.c31
3 files changed, 39 insertions, 28 deletions
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index ea36486378d8..1b14d25162cb 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -320,7 +320,8 @@ extern int parse_args(const char *name,
320 unsigned num, 320 unsigned num,
321 s16 level_min, 321 s16 level_min,
322 s16 level_max, 322 s16 level_max,
323 int (*unknown)(char *param, char *val)); 323 int (*unknown)(char *param, char *val,
324 const char *doing));
324 325
325/* Called by module remove. */ 326/* Called by module remove. */
326#ifdef CONFIG_SYSFS 327#ifdef CONFIG_SYSFS
diff --git a/init/main.c b/init/main.c
index 9d454f09f3b1..11bc6f7ed866 100644
--- a/init/main.c
+++ b/init/main.c
@@ -229,7 +229,8 @@ early_param("loglevel", loglevel);
229 * Unknown boot options get handed to init, unless they look like 229 * Unknown boot options get handed to init, unless they look like
230 * unused parameters (modprobe will find them in /proc/cmdline). 230 * unused parameters (modprobe will find them in /proc/cmdline).
231 */ 231 */
232static int __init unknown_bootoption(char *param, char *val) 232static int __init unknown_bootoption(char *param, char *val,
233 const char *unused)
233{ 234{
234 /* Change NUL term back to "=", to make "param" the whole string. */ 235 /* Change NUL term back to "=", to make "param" the whole string. */
235 if (val) { 236 if (val) {
@@ -379,7 +380,7 @@ static noinline void __init_refok rest_init(void)
379} 380}
380 381
381/* Check for early params. */ 382/* Check for early params. */
382static int __init do_early_param(char *param, char *val) 383static int __init do_early_param(char *param, char *val, const char *unused)
383{ 384{
384 const struct obs_kernel_param *p; 385 const struct obs_kernel_param *p;
385 386
@@ -722,17 +723,18 @@ static initcall_t *initcall_levels[] __initdata = {
722}; 723};
723 724
724static char *initcall_level_names[] __initdata = { 725static char *initcall_level_names[] __initdata = {
725 "early parameters", 726 "early",
726 "core parameters", 727 "core",
727 "postcore parameters", 728 "postcore",
728 "arch parameters", 729 "arch",
729 "subsys parameters", 730 "subsys",
730 "fs parameters", 731 "fs",
731 "device parameters", 732 "device",
732 "late parameters", 733 "late",
733}; 734};
734 735
735static int __init ignore_unknown_bootoption(char *param, char *val) 736static int __init ignore_unknown_bootoption(char *param, char *val,
737 const char *doing)
736{ 738{
737 return 0; 739 return 0;
738} 740}
@@ -747,7 +749,7 @@ static void __init do_initcall_level(int level)
747 static_command_line, __start___param, 749 static_command_line, __start___param,
748 __stop___param - __start___param, 750 __stop___param - __start___param,
749 level, level, 751 level, level,
750 ignore_unknown_bootoption); 752 &ignore_unknown_bootoption);
751 753
752 for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) 754 for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
753 do_one_initcall(*fn); 755 do_one_initcall(*fn);
@@ -757,8 +759,13 @@ static void __init do_initcalls(void)
757{ 759{
758 int level; 760 int level;
759 761
760 for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) 762 for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) {
763 pr_info("initlevel:%d=%s, %d registered initcalls\n",
764 level, initcall_level_names[level],
765 (int) (initcall_levels[level+1]
766 - initcall_levels[level]));
761 do_initcall_level(level); 767 do_initcall_level(level);
768 }
762} 769}
763 770
764/* 771/*
diff --git a/kernel/params.c b/kernel/params.c
index f37d82631347..b60e2c74b961 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -85,11 +85,13 @@ bool parameq(const char *a, const char *b)
85 85
86static int parse_one(char *param, 86static int parse_one(char *param,
87 char *val, 87 char *val,
88 const char *doing,
88 const struct kernel_param *params, 89 const struct kernel_param *params,
89 unsigned num_params, 90 unsigned num_params,
90 s16 min_level, 91 s16 min_level,
91 s16 max_level, 92 s16 max_level,
92 int (*handle_unknown)(char *param, char *val)) 93 int (*handle_unknown)(char *param, char *val,
94 const char *doing))
93{ 95{
94 unsigned int i; 96 unsigned int i;
95 int err; 97 int err;
@@ -104,8 +106,8 @@ static int parse_one(char *param,
104 if (!val && params[i].ops->set != param_set_bool 106 if (!val && params[i].ops->set != param_set_bool
105 && params[i].ops->set != param_set_bint) 107 && params[i].ops->set != param_set_bint)
106 return -EINVAL; 108 return -EINVAL;
107 pr_debug("They are equal! Calling %p\n", 109 pr_debug("handling %s with %p\n", param,
108 params[i].ops->set); 110 params[i].ops->set);
109 mutex_lock(&param_lock); 111 mutex_lock(&param_lock);
110 err = params[i].ops->set(val, &params[i]); 112 err = params[i].ops->set(val, &params[i]);
111 mutex_unlock(&param_lock); 113 mutex_unlock(&param_lock);
@@ -114,11 +116,11 @@ static int parse_one(char *param,
114 } 116 }
115 117
116 if (handle_unknown) { 118 if (handle_unknown) {
117 pr_debug("Unknown argument: calling %p\n", handle_unknown); 119 pr_debug("doing %s: %s='%s'\n", doing, param, val);
118 return handle_unknown(param, val); 120 return handle_unknown(param, val, doing);
119 } 121 }
120 122
121 pr_debug("Unknown argument `%s'\n", param); 123 pr_debug("Unknown argument '%s'\n", param);
122 return -ENOENT; 124 return -ENOENT;
123} 125}
124 126
@@ -175,28 +177,29 @@ static char *next_arg(char *args, char **param, char **val)
175} 177}
176 178
177/* Args looks like "foo=bar,bar2 baz=fuz wiz". */ 179/* Args looks like "foo=bar,bar2 baz=fuz wiz". */
178int parse_args(const char *name, 180int parse_args(const char *doing,
179 char *args, 181 char *args,
180 const struct kernel_param *params, 182 const struct kernel_param *params,
181 unsigned num, 183 unsigned num,
182 s16 min_level, 184 s16 min_level,
183 s16 max_level, 185 s16 max_level,
184 int (*unknown)(char *param, char *val)) 186 int (*unknown)(char *param, char *val, const char *doing))
185{ 187{
186 char *param, *val; 188 char *param, *val;
187 189
188 pr_debug("Parsing ARGS: %s\n", args);
189
190 /* Chew leading spaces */ 190 /* Chew leading spaces */
191 args = skip_spaces(args); 191 args = skip_spaces(args);
192 192
193 if (args && *args)
194 pr_debug("doing %s, parsing ARGS: '%s'\n", doing, args);
195
193 while (*args) { 196 while (*args) {
194 int ret; 197 int ret;
195 int irq_was_disabled; 198 int irq_was_disabled;
196 199
197 args = next_arg(args, &param, &val); 200 args = next_arg(args, &param, &val);
198 irq_was_disabled = irqs_disabled(); 201 irq_was_disabled = irqs_disabled();
199 ret = parse_one(param, val, params, num, 202 ret = parse_one(param, val, doing, params, num,
200 min_level, max_level, unknown); 203 min_level, max_level, unknown);
201 if (irq_was_disabled && !irqs_disabled()) { 204 if (irq_was_disabled && !irqs_disabled()) {
202 printk(KERN_WARNING "parse_args(): option '%s' enabled " 205 printk(KERN_WARNING "parse_args(): option '%s' enabled "
@@ -205,19 +208,19 @@ int parse_args(const char *name,
205 switch (ret) { 208 switch (ret) {
206 case -ENOENT: 209 case -ENOENT:
207 printk(KERN_ERR "%s: Unknown parameter `%s'\n", 210 printk(KERN_ERR "%s: Unknown parameter `%s'\n",
208 name, param); 211 doing, param);
209 return ret; 212 return ret;
210 case -ENOSPC: 213 case -ENOSPC:
211 printk(KERN_ERR 214 printk(KERN_ERR
212 "%s: `%s' too large for parameter `%s'\n", 215 "%s: `%s' too large for parameter `%s'\n",
213 name, val ?: "", param); 216 doing, val ?: "", param);
214 return ret; 217 return ret;
215 case 0: 218 case 0:
216 break; 219 break;
217 default: 220 default:
218 printk(KERN_ERR 221 printk(KERN_ERR
219 "%s: `%s' invalid for parameter `%s'\n", 222 "%s: `%s' invalid for parameter `%s'\n",
220 name, val ?: "", param); 223 doing, val ?: "", param);
221 return ret; 224 return ret;
222 } 225 }
223 } 226 }