params: don't ignore the rest of cmdline if parse_one() fails

parse_args() just aborts after it hits an error, so other args
at the same initcall level are simply ignored. This can lead to
other hard-to-understand problems, for example my testing machine
panics during the boot if I pass "locktorture.verbose=true".

Change parse_args() to save the err code for return and continue.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Oleg Nesterov 2015-08-26 09:42:34 +09:30 committed by Rusty Russell
parent 5cfb203a30
commit 74b22c465c

View file

@ -223,7 +223,7 @@ char *parse_args(const char *doing,
int (*unknown)(char *param, char *val, int (*unknown)(char *param, char *val,
const char *doing, void *arg)) const char *doing, void *arg))
{ {
char *param, *val; char *param, *val, *err = NULL;
/* Chew leading spaces */ /* Chew leading spaces */
args = skip_spaces(args); args = skip_spaces(args);
@ -238,7 +238,7 @@ char *parse_args(const char *doing,
args = next_arg(args, &param, &val); args = next_arg(args, &param, &val);
/* Stop at -- */ /* Stop at -- */
if (!val && strcmp(param, "--") == 0) if (!val && strcmp(param, "--") == 0)
return args; return err ?: args;
irq_was_disabled = irqs_disabled(); irq_was_disabled = irqs_disabled();
ret = parse_one(param, val, doing, params, num, ret = parse_one(param, val, doing, params, num,
min_level, max_level, arg, unknown); min_level, max_level, arg, unknown);
@ -247,24 +247,25 @@ char *parse_args(const char *doing,
doing, param); doing, param);
switch (ret) { switch (ret) {
case 0:
continue;
case -ENOENT: case -ENOENT:
pr_err("%s: Unknown parameter `%s'\n", doing, param); pr_err("%s: Unknown parameter `%s'\n", doing, param);
return ERR_PTR(ret); break;
case -ENOSPC: case -ENOSPC:
pr_err("%s: `%s' too large for parameter `%s'\n", pr_err("%s: `%s' too large for parameter `%s'\n",
doing, val ?: "", param); doing, val ?: "", param);
return ERR_PTR(ret);
case 0:
break; break;
default: default:
pr_err("%s: `%s' invalid for parameter `%s'\n", pr_err("%s: `%s' invalid for parameter `%s'\n",
doing, val ?: "", param); doing, val ?: "", param);
return ERR_PTR(ret); break;
} }
err = ERR_PTR(ret);
} }
/* All parsed OK. */ return err;
return NULL;
} }
/* Lazy bastard, eh? */ /* Lazy bastard, eh? */