aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2015-08-25 20:12:34 -0400
committerRusty Russell <rusty@rustcorp.com.au>2015-08-25 21:06:19 -0400
commit74b22c465cd2b6ff4b8cec3997512ec807e6e495 (patch)
treebcc0db7d79b2b2c17f6f1cf3743a8eebbebdd7a9
parent5cfb203a304deaaa8c7c5368722b214d24583137 (diff)
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>
-rw-r--r--kernel/params.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/kernel/params.c b/kernel/params.c
index b6554aa71094..ed1e0a1cffa7 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -223,7 +223,7 @@ char *parse_args(const char *doing,
223 int (*unknown)(char *param, char *val, 223 int (*unknown)(char *param, char *val,
224 const char *doing, void *arg)) 224 const char *doing, void *arg))
225{ 225{
226 char *param, *val; 226 char *param, *val, *err = NULL;
227 227
228 /* Chew leading spaces */ 228 /* Chew leading spaces */
229 args = skip_spaces(args); 229 args = skip_spaces(args);
@@ -238,7 +238,7 @@ char *parse_args(const char *doing,
238 args = next_arg(args, &param, &val); 238 args = next_arg(args, &param, &val);
239 /* Stop at -- */ 239 /* Stop at -- */
240 if (!val && strcmp(param, "--") == 0) 240 if (!val && strcmp(param, "--") == 0)
241 return args; 241 return err ?: args;
242 irq_was_disabled = irqs_disabled(); 242 irq_was_disabled = irqs_disabled();
243 ret = parse_one(param, val, doing, params, num, 243 ret = parse_one(param, val, doing, params, num,
244 min_level, max_level, arg, unknown); 244 min_level, max_level, arg, unknown);
@@ -247,24 +247,25 @@ char *parse_args(const char *doing,
247 doing, param); 247 doing, param);
248 248
249 switch (ret) { 249 switch (ret) {
250 case 0:
251 continue;
250 case -ENOENT: 252 case -ENOENT:
251 pr_err("%s: Unknown parameter `%s'\n", doing, param); 253 pr_err("%s: Unknown parameter `%s'\n", doing, param);
252 return ERR_PTR(ret); 254 break;
253 case -ENOSPC: 255 case -ENOSPC:
254 pr_err("%s: `%s' too large for parameter `%s'\n", 256 pr_err("%s: `%s' too large for parameter `%s'\n",
255 doing, val ?: "", param); 257 doing, val ?: "", param);
256 return ERR_PTR(ret);
257 case 0:
258 break; 258 break;
259 default: 259 default:
260 pr_err("%s: `%s' invalid for parameter `%s'\n", 260 pr_err("%s: `%s' invalid for parameter `%s'\n",
261 doing, val ?: "", param); 261 doing, val ?: "", param);
262 return ERR_PTR(ret); 262 break;
263 } 263 }
264
265 err = ERR_PTR(ret);
264 } 266 }
265 267
266 /* All parsed OK. */ 268 return err;
267 return NULL;
268} 269}
269 270
270/* Lazy bastard, eh? */ 271/* Lazy bastard, eh? */