Annotation of /trunk/systemd/patches/systemd-217-shutdown-fix-arguments-to-run-initramfs-shutdown.patch
Parent Directory | Revision Log
Revision 2524 -
(hide annotations)
(download)
Mon Nov 17 13:56:31 2014 UTC (9 years, 10 months ago) by niro
File size: 2374 byte(s)
Mon Nov 17 13:56:31 2014 UTC (9 years, 10 months ago) by niro
File size: 2374 byte(s)
-upstream fixes
1 | niro | 2524 | From 4b5d8d0f22ae61ceb45a25391354ba53b43ee992 Mon Sep 17 00:00:00 2001 |
2 | From: Michal Schmidt <mschmidt@redhat.com> | ||
3 | Date: Thu, 6 Nov 2014 22:24:13 +0100 | ||
4 | Subject: [PATCH] shutdown: fix arguments to /run/initramfs/shutdown | ||
5 | |||
6 | Our initrd interface specifies that the verb is in argv[1]. | ||
7 | This is where systemd passes it to systemd-shutdown, but getopt | ||
8 | permutes argv[]. This confuses dracut's shutdown script: | ||
9 | Shutdown called with argument '--log-level'. Rebooting! | ||
10 | |||
11 | getopt can be convinced to not permute argv[] by having '-' as the first | ||
12 | character of optstring. Let's use it. This requires changing the way | ||
13 | non-option arguments (in our case, the verb) are processed. | ||
14 | |||
15 | This fixes a bug where the system would reboot instead of powering off. | ||
16 | --- | ||
17 | src/core/shutdown.c | 17 +++++++++++------ | ||
18 | 1 file changed, 11 insertions(+), 6 deletions(-) | ||
19 | |||
20 | diff --git a/src/core/shutdown.c b/src/core/shutdown.c | ||
21 | index dd11ae3..48ed7fa 100644 | ||
22 | --- a/src/core/shutdown.c | ||
23 | +++ b/src/core/shutdown.c | ||
24 | @@ -75,7 +75,9 @@ static int parse_argv(int argc, char *argv[]) { | ||
25 | assert(argc >= 1); | ||
26 | assert(argv); | ||
27 | |||
28 | - while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) | ||
29 | + /* "-" prevents getopt from permuting argv[] and moving the verb away | ||
30 | + * from argv[1]. Our interface to initrd promises it'll be there. */ | ||
31 | + while ((c = getopt_long(argc, argv, "-", options, NULL)) >= 0) | ||
32 | switch (c) { | ||
33 | |||
34 | case ARG_LOG_LEVEL: | ||
35 | @@ -113,6 +115,13 @@ static int parse_argv(int argc, char *argv[]) { | ||
36 | |||
37 | break; | ||
38 | |||
39 | + case '\001': | ||
40 | + if (!arg_verb) | ||
41 | + arg_verb = optarg; | ||
42 | + else | ||
43 | + log_error("Excess arguments, ignoring"); | ||
44 | + break; | ||
45 | + | ||
46 | case '?': | ||
47 | return -EINVAL; | ||
48 | |||
49 | @@ -120,15 +129,11 @@ static int parse_argv(int argc, char *argv[]) { | ||
50 | assert_not_reached("Unhandled option code."); | ||
51 | } | ||
52 | |||
53 | - if (optind >= argc) { | ||
54 | + if (!arg_verb) { | ||
55 | log_error("Verb argument missing."); | ||
56 | return -EINVAL; | ||
57 | } | ||
58 | |||
59 | - arg_verb = argv[optind]; | ||
60 | - | ||
61 | - if (optind + 1 < argc) | ||
62 | - log_error("Excess arguments, ignoring"); | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | -- | ||
67 | 2.1.3 | ||
68 |