Skip to content

Commit 9fb48c7

Browse files
jimcgregkh
authored andcommitted
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 <[email protected]> Signed-off-by: Jim Cromie <[email protected]> Acked-by: Jason Baron <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 3faa286 commit 9fb48c7

File tree

3 files changed

+39
-28
lines changed

3 files changed

+39
-28
lines changed

include/linux/moduleparam.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,8 @@ extern int parse_args(const char *name,
320320
unsigned num,
321321
s16 level_min,
322322
s16 level_max,
323-
int (*unknown)(char *param, char *val));
323+
int (*unknown)(char *param, char *val,
324+
const char *doing));
324325

325326
/* Called by module remove. */
326327
#ifdef CONFIG_SYSFS

init/main.c

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,8 @@ early_param("loglevel", loglevel);
229229
* Unknown boot options get handed to init, unless they look like
230230
* unused parameters (modprobe will find them in /proc/cmdline).
231231
*/
232-
static int __init unknown_bootoption(char *param, char *val)
232+
static int __init unknown_bootoption(char *param, char *val,
233+
const char *unused)
233234
{
234235
/* Change NUL term back to "=", to make "param" the whole string. */
235236
if (val) {
@@ -379,7 +380,7 @@ static noinline void __init_refok rest_init(void)
379380
}
380381

381382
/* 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)
383384
{
384385
const struct obs_kernel_param *p;
385386

@@ -722,17 +723,18 @@ static initcall_t *initcall_levels[] __initdata = {
722723
};
723724

724725
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",
733734
};
734735

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)
736738
{
737739
return 0;
738740
}
@@ -747,7 +749,7 @@ static void __init do_initcall_level(int level)
747749
static_command_line, __start___param,
748750
__stop___param - __start___param,
749751
level, level,
750-
ignore_unknown_bootoption);
752+
&ignore_unknown_bootoption);
751753

752754
for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
753755
do_one_initcall(*fn);
@@ -757,8 +759,13 @@ static void __init do_initcalls(void)
757759
{
758760
int level;
759761

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]));
761767
do_initcall_level(level);
768+
}
762769
}
763770

764771
/*

kernel/params.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,13 @@ bool parameq(const char *a, const char *b)
8585

8686
static int parse_one(char *param,
8787
char *val,
88+
const char *doing,
8889
const struct kernel_param *params,
8990
unsigned num_params,
9091
s16 min_level,
9192
s16 max_level,
92-
int (*handle_unknown)(char *param, char *val))
93+
int (*handle_unknown)(char *param, char *val,
94+
const char *doing))
9395
{
9496
unsigned int i;
9597
int err;
@@ -104,8 +106,8 @@ static int parse_one(char *param,
104106
if (!val && params[i].ops->set != param_set_bool
105107
&& params[i].ops->set != param_set_bint)
106108
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);
109111
mutex_lock(&param_lock);
110112
err = params[i].ops->set(val, &params[i]);
111113
mutex_unlock(&param_lock);
@@ -114,11 +116,11 @@ static int parse_one(char *param,
114116
}
115117

116118
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);
119121
}
120122

121-
pr_debug("Unknown argument `%s'\n", param);
123+
pr_debug("Unknown argument '%s'\n", param);
122124
return -ENOENT;
123125
}
124126

@@ -175,28 +177,29 @@ static char *next_arg(char *args, char **param, char **val)
175177
}
176178

177179
/* Args looks like "foo=bar,bar2 baz=fuz wiz". */
178-
int parse_args(const char *name,
180+
int parse_args(const char *doing,
179181
char *args,
180182
const struct kernel_param *params,
181183
unsigned num,
182184
s16 min_level,
183185
s16 max_level,
184-
int (*unknown)(char *param, char *val))
186+
int (*unknown)(char *param, char *val, const char *doing))
185187
{
186188
char *param, *val;
187189

188-
pr_debug("Parsing ARGS: %s\n", args);
189-
190190
/* Chew leading spaces */
191191
args = skip_spaces(args);
192192

193+
if (args && *args)
194+
pr_debug("doing %s, parsing ARGS: '%s'\n", doing, args);
195+
193196
while (*args) {
194197
int ret;
195198
int irq_was_disabled;
196199

197200
args = next_arg(args, &param, &val);
198201
irq_was_disabled = irqs_disabled();
199-
ret = parse_one(param, val, params, num,
202+
ret = parse_one(param, val, doing, params, num,
200203
min_level, max_level, unknown);
201204
if (irq_was_disabled && !irqs_disabled()) {
202205
printk(KERN_WARNING "parse_args(): option '%s' enabled "
@@ -205,19 +208,19 @@ int parse_args(const char *name,
205208
switch (ret) {
206209
case -ENOENT:
207210
printk(KERN_ERR "%s: Unknown parameter `%s'\n",
208-
name, param);
211+
doing, param);
209212
return ret;
210213
case -ENOSPC:
211214
printk(KERN_ERR
212215
"%s: `%s' too large for parameter `%s'\n",
213-
name, val ?: "", param);
216+
doing, val ?: "", param);
214217
return ret;
215218
case 0:
216219
break;
217220
default:
218221
printk(KERN_ERR
219222
"%s: `%s' invalid for parameter `%s'\n",
220-
name, val ?: "", param);
223+
doing, val ?: "", param);
221224
return ret;
222225
}
223226
}

0 commit comments

Comments
 (0)