Commit 9fb48c744ba6a4bf58b666f4e6fdac3008ea1bd4
Committed by
Greg Kroah-Hartman
1 parent
3faa286055
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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>
Showing 3 changed files with 39 additions and 28 deletions Side-by-side Diff
include/linux/moduleparam.h
init/main.c
... | ... | @@ -229,7 +229,8 @@ |
229 | 229 | * Unknown boot options get handed to init, unless they look like |
230 | 230 | * unused parameters (modprobe will find them in /proc/cmdline). |
231 | 231 | */ |
232 | -static int __init unknown_bootoption(char *param, char *val) | |
232 | +static int __init unknown_bootoption(char *param, char *val, | |
233 | + const char *unused) | |
233 | 234 | { |
234 | 235 | /* Change NUL term back to "=", to make "param" the whole string. */ |
235 | 236 | if (val) { |
... | ... | @@ -379,7 +380,7 @@ |
379 | 380 | } |
380 | 381 | |
381 | 382 | /* Check for early params. */ |
382 | -static int __init do_early_param(char *param, char *val) | |
383 | +static int __init do_early_param(char *param, char *val, const char *unused) | |
383 | 384 | { |
384 | 385 | const struct obs_kernel_param *p; |
385 | 386 | |
386 | 387 | |
... | ... | @@ -722,17 +723,18 @@ |
722 | 723 | }; |
723 | 724 | |
724 | 725 | static char *initcall_level_names[] __initdata = { |
725 | - "early parameters", | |
726 | - "core parameters", | |
727 | - "postcore parameters", | |
728 | - "arch parameters", | |
729 | - "subsys parameters", | |
730 | - "fs parameters", | |
731 | - "device parameters", | |
732 | - "late parameters", | |
726 | + "early", | |
727 | + "core", | |
728 | + "postcore", | |
729 | + "arch", | |
730 | + "subsys", | |
731 | + "fs", | |
732 | + "device", | |
733 | + "late", | |
733 | 734 | }; |
734 | 735 | |
735 | -static int __init ignore_unknown_bootoption(char *param, char *val) | |
736 | +static int __init ignore_unknown_bootoption(char *param, char *val, | |
737 | + const char *doing) | |
736 | 738 | { |
737 | 739 | return 0; |
738 | 740 | } |
... | ... | @@ -747,7 +749,7 @@ |
747 | 749 | static_command_line, __start___param, |
748 | 750 | __stop___param - __start___param, |
749 | 751 | level, level, |
750 | - ignore_unknown_bootoption); | |
752 | + &ignore_unknown_bootoption); | |
751 | 753 | |
752 | 754 | for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) |
753 | 755 | do_one_initcall(*fn); |
754 | 756 | |
... | ... | @@ -757,8 +759,13 @@ |
757 | 759 | { |
758 | 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 | 767 | do_initcall_level(level); |
768 | + } | |
762 | 769 | } |
763 | 770 | |
764 | 771 | /* |
kernel/params.c
... | ... | @@ -85,11 +85,13 @@ |
85 | 85 | |
86 | 86 | static int parse_one(char *param, |
87 | 87 | char *val, |
88 | + const char *doing, | |
88 | 89 | const struct kernel_param *params, |
89 | 90 | unsigned num_params, |
90 | 91 | s16 min_level, |
91 | 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 | 96 | unsigned int i; |
95 | 97 | int err; |
... | ... | @@ -104,8 +106,8 @@ |
104 | 106 | if (!val && params[i].ops->set != param_set_bool |
105 | 107 | && params[i].ops->set != param_set_bint) |
106 | 108 | return -EINVAL; |
107 | - pr_debug("They are equal! Calling %p\n", | |
108 | - params[i].ops->set); | |
109 | + pr_debug("handling %s with %p\n", param, | |
110 | + params[i].ops->set); | |
109 | 111 | mutex_lock(¶m_lock); |
110 | 112 | err = params[i].ops->set(val, ¶ms[i]); |
111 | 113 | mutex_unlock(¶m_lock); |
112 | 114 | |
... | ... | @@ -114,11 +116,11 @@ |
114 | 116 | } |
115 | 117 | |
116 | 118 | if (handle_unknown) { |
117 | - pr_debug("Unknown argument: calling %p\n", handle_unknown); | |
118 | - return handle_unknown(param, val); | |
119 | + pr_debug("doing %s: %s='%s'\n", doing, 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 | 124 | return -ENOENT; |
123 | 125 | } |
124 | 126 | |
125 | 127 | |
126 | 128 | |
127 | 129 | |
128 | 130 | |
... | ... | @@ -175,28 +177,29 @@ |
175 | 177 | } |
176 | 178 | |
177 | 179 | /* Args looks like "foo=bar,bar2 baz=fuz wiz". */ |
178 | -int parse_args(const char *name, | |
180 | +int parse_args(const char *doing, | |
179 | 181 | char *args, |
180 | 182 | const struct kernel_param *params, |
181 | 183 | unsigned num, |
182 | 184 | s16 min_level, |
183 | 185 | s16 max_level, |
184 | - int (*unknown)(char *param, char *val)) | |
186 | + int (*unknown)(char *param, char *val, const char *doing)) | |
185 | 187 | { |
186 | 188 | char *param, *val; |
187 | 189 | |
188 | - pr_debug("Parsing ARGS: %s\n", args); | |
189 | - | |
190 | 190 | /* Chew leading spaces */ |
191 | 191 | args = skip_spaces(args); |
192 | 192 | |
193 | + if (args && *args) | |
194 | + pr_debug("doing %s, parsing ARGS: '%s'\n", doing, args); | |
195 | + | |
193 | 196 | while (*args) { |
194 | 197 | int ret; |
195 | 198 | int irq_was_disabled; |
196 | 199 | |
197 | 200 | args = next_arg(args, ¶m, &val); |
198 | 201 | irq_was_disabled = irqs_disabled(); |
199 | - ret = parse_one(param, val, params, num, | |
202 | + ret = parse_one(param, val, doing, params, num, | |
200 | 203 | min_level, max_level, unknown); |
201 | 204 | if (irq_was_disabled && !irqs_disabled()) { |
202 | 205 | printk(KERN_WARNING "parse_args(): option '%s' enabled " |
203 | 206 | |
204 | 207 | |
... | ... | @@ -205,19 +208,19 @@ |
205 | 208 | switch (ret) { |
206 | 209 | case -ENOENT: |
207 | 210 | printk(KERN_ERR "%s: Unknown parameter `%s'\n", |
208 | - name, param); | |
211 | + doing, param); | |
209 | 212 | return ret; |
210 | 213 | case -ENOSPC: |
211 | 214 | printk(KERN_ERR |
212 | 215 | "%s: `%s' too large for parameter `%s'\n", |
213 | - name, val ?: "", param); | |
216 | + doing, val ?: "", param); | |
214 | 217 | return ret; |
215 | 218 | case 0: |
216 | 219 | break; |
217 | 220 | default: |
218 | 221 | printk(KERN_ERR |
219 | 222 | "%s: `%s' invalid for parameter `%s'\n", |
220 | - name, val ?: "", param); | |
223 | + doing, val ?: "", param); | |
221 | 224 | return ret; |
222 | 225 | } |
223 | 226 | } |