diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2014-04-27 22:04:33 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2014-04-27 22:18:34 -0400 |
commit | 51e158c12aca3c9ac63988611a97c05109b14dc9 (patch) | |
tree | 579ef4259a17200a77ec111c6a6ca082d43a368d /kernel/params.c | |
parent | 2ee41e62ba5b952e9d9fcba6f7079a0c608bb849 (diff) |
param: hand arguments after -- straight to init
The kernel passes any args it doesn't need through to init, except it
assumes anything containing '.' belongs to the kernel (for a module).
This change means all users can clearly distinguish which arguments
are for init.
For example, the kernel uses debug ("dee-bug") to mean log everything to
the console, where systemd uses the debug from the Scandinavian "day-boog"
meaning "fail to boot". If a future versions uses argv[] instead of
reading /proc/cmdline, this confusion will be avoided.
eg: test 'FOO="this is --foo"' -- 'systemd.debug="true true true"'
Gives:
argv[0] = '/debug-init'
argv[1] = 'test'
argv[2] = 'systemd.debug=true true true'
envp[0] = 'HOME=/'
envp[1] = 'TERM=linux'
envp[2] = 'FOO=this is --foo'
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel/params.c')
-rw-r--r-- | kernel/params.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/kernel/params.c b/kernel/params.c index b00142e7f3ba..1e52ca233fd9 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -177,13 +177,13 @@ static char *next_arg(char *args, char **param, char **val) | |||
177 | } | 177 | } |
178 | 178 | ||
179 | /* Args looks like "foo=bar,bar2 baz=fuz wiz". */ | 179 | /* Args looks like "foo=bar,bar2 baz=fuz wiz". */ |
180 | int parse_args(const char *doing, | 180 | char *parse_args(const char *doing, |
181 | char *args, | 181 | char *args, |
182 | const struct kernel_param *params, | 182 | const struct kernel_param *params, |
183 | unsigned num, | 183 | unsigned num, |
184 | s16 min_level, | 184 | s16 min_level, |
185 | s16 max_level, | 185 | s16 max_level, |
186 | int (*unknown)(char *param, char *val, const char *doing)) | 186 | int (*unknown)(char *param, char *val, const char *doing)) |
187 | { | 187 | { |
188 | char *param, *val; | 188 | char *param, *val; |
189 | 189 | ||
@@ -198,6 +198,9 @@ int parse_args(const char *doing, | |||
198 | int irq_was_disabled; | 198 | int irq_was_disabled; |
199 | 199 | ||
200 | args = next_arg(args, ¶m, &val); | 200 | args = next_arg(args, ¶m, &val); |
201 | /* Stop at -- */ | ||
202 | if (!val && strcmp(param, "--") == 0) | ||
203 | return args; | ||
201 | irq_was_disabled = irqs_disabled(); | 204 | irq_was_disabled = irqs_disabled(); |
202 | ret = parse_one(param, val, doing, params, num, | 205 | ret = parse_one(param, val, doing, params, num, |
203 | min_level, max_level, unknown); | 206 | min_level, max_level, unknown); |
@@ -208,22 +211,22 @@ int parse_args(const char *doing, | |||
208 | switch (ret) { | 211 | switch (ret) { |
209 | case -ENOENT: | 212 | case -ENOENT: |
210 | pr_err("%s: Unknown parameter `%s'\n", doing, param); | 213 | pr_err("%s: Unknown parameter `%s'\n", doing, param); |
211 | return ret; | 214 | return ERR_PTR(ret); |
212 | case -ENOSPC: | 215 | case -ENOSPC: |
213 | pr_err("%s: `%s' too large for parameter `%s'\n", | 216 | pr_err("%s: `%s' too large for parameter `%s'\n", |
214 | doing, val ?: "", param); | 217 | doing, val ?: "", param); |
215 | return ret; | 218 | return ERR_PTR(ret); |
216 | case 0: | 219 | case 0: |
217 | break; | 220 | break; |
218 | default: | 221 | default: |
219 | pr_err("%s: `%s' invalid for parameter `%s'\n", | 222 | pr_err("%s: `%s' invalid for parameter `%s'\n", |
220 | doing, val ?: "", param); | 223 | doing, val ?: "", param); |
221 | return ret; | 224 | return ERR_PTR(ret); |
222 | } | 225 | } |
223 | } | 226 | } |
224 | 227 | ||
225 | /* All parsed OK. */ | 228 | /* All parsed OK. */ |
226 | return 0; | 229 | return NULL; |
227 | } | 230 | } |
228 | 231 | ||
229 | /* Lazy bastard, eh? */ | 232 | /* Lazy bastard, eh? */ |