From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757273Ab2DFRMB (ORCPT ); Fri, 6 Apr 2012 13:12:01 -0400 Received: from 206.83.70.73.ptr.us.xo.net ([206.83.70.73]:52149 "EHLO king.tilera.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757081Ab2DFRLz (ORCPT ); Fri, 6 Apr 2012 13:11:55 -0400 Message-Id: <201204061711.q36HBpAh015060@lab-41.internal.tilera.com> From: Chris Metcalf Date: Fri, 6 Apr 2012 12:53:50 -0400 Subject: [PATCH] init: fix bug where environment vars can't be passed via boot args To: Pawel Moll , Ingo Molnar , Peter Zijlstra , Andrew Morton , Rusty Russell , Stanislaw Gruszka , linux-kernel@vger.kernel.org X-OriginalArrivalTime: 06 Apr 2012 17:11:54.0788 (UTC) FILETIME=[5DBA6640:01CD1418] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit 026cee0086f had the side-effect of dropping the '=' from the unknown boot arguments that are passed to init as environment variables. This is because parse_args() puts a NUL in the string where the '=' was when it passes the "param" and "val" pointers to the parsing subfunctions. Previously, unknown_bootoption() was the last parse_args() subfunction to run, and it carefully put back the '=' character. Now ignore_unknown_bootoption() is the last one to run, and it wasn't doing the necessary repair, so the envp params ended up with the embedded NUL and were no longer seen as valid environment variables by init. Signed-off-by: Chris Metcalf --- init/main.c | 25 +++++++++++++------------ 1 files changed, 13 insertions(+), 12 deletions(-) diff --git a/init/main.c b/init/main.c index 9d454f0..44b2433 100644 --- a/init/main.c +++ b/init/main.c @@ -225,13 +225,9 @@ static int __init loglevel(char *str) early_param("loglevel", loglevel); -/* - * Unknown boot options get handed to init, unless they look like - * unused parameters (modprobe will find them in /proc/cmdline). - */ -static int __init unknown_bootoption(char *param, char *val) +/* Change NUL term back to "=", to make "param" the whole string. */ +static int __init repair_env_string(char *param, char *val) { - /* Change NUL term back to "=", to make "param" the whole string. */ if (val) { /* param=val or param="val"? */ if (val == param+strlen(param)+1) @@ -243,6 +239,16 @@ static int __init unknown_bootoption(char *param, char *val) } else BUG(); } + return 0; +} + +/* + * Unknown boot options get handed to init, unless they look like + * unused parameters (modprobe will find them in /proc/cmdline). + */ +static int __init unknown_bootoption(char *param, char *val) +{ + repair_env_string(param, val); /* Handle obsolete-style parameters */ if (obsolete_checksetup(param)) @@ -732,11 +738,6 @@ static char *initcall_level_names[] __initdata = { "late parameters", }; -static int __init ignore_unknown_bootoption(char *param, char *val) -{ - return 0; -} - static void __init do_initcall_level(int level) { extern const struct kernel_param __start___param[], __stop___param[]; @@ -747,7 +748,7 @@ static void __init do_initcall_level(int level) static_command_line, __start___param, __stop___param - __start___param, level, level, - ignore_unknown_bootoption); + repair_env_string); for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) do_one_initcall(*fn); -- 1.6.5.2