Zbigniew Jędrzejewski-Szmek ea1976
From e47a9f972749544d28cffede77de13e9d8af4d2b Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek ea1976
From: Michal Schmidt <mschmidt@redhat.com>
Zbigniew Jędrzejewski-Szmek ea1976
Date: Thu, 6 Nov 2014 22:24:13 +0100
Zbigniew Jędrzejewski-Szmek ea1976
Subject: [PATCH] shutdown: fix arguments to /run/initramfs/shutdown
Zbigniew Jędrzejewski-Szmek ea1976
Zbigniew Jędrzejewski-Szmek ea1976
Our initrd interface specifies that the verb is in argv[1].
Zbigniew Jędrzejewski-Szmek ea1976
This is where systemd passes it to systemd-shutdown, but getopt
Zbigniew Jędrzejewski-Szmek ea1976
permutes argv[]. This confuses dracut's shutdown script:
Zbigniew Jędrzejewski-Szmek ea1976
  Shutdown called with argument '--log-level'. Rebooting!
Zbigniew Jędrzejewski-Szmek ea1976
Zbigniew Jędrzejewski-Szmek ea1976
getopt can be convinced to not permute argv[] by having '-' as the first
Zbigniew Jędrzejewski-Szmek ea1976
character of optstring. Let's use it. This requires changing the way
Zbigniew Jędrzejewski-Szmek ea1976
non-option arguments (in our case, the verb) are processed.
Zbigniew Jędrzejewski-Szmek ea1976
Zbigniew Jędrzejewski-Szmek ea1976
This fixes a bug where the system would reboot instead of powering off.
Zbigniew Jędrzejewski-Szmek ea1976
Zbigniew Jędrzejewski-Szmek ea1976
(cherry picked from commit 4b5d8d0f22ae61ceb45a25391354ba53b43ee992)
Zbigniew Jędrzejewski-Szmek ea1976
---
Zbigniew Jędrzejewski-Szmek ea1976
 src/core/shutdown.c | 17 +++++++++++------
Zbigniew Jędrzejewski-Szmek ea1976
 1 file changed, 11 insertions(+), 6 deletions(-)
Zbigniew Jędrzejewski-Szmek ea1976
Zbigniew Jędrzejewski-Szmek ea1976
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
Zbigniew Jędrzejewski-Szmek ea1976
index 20cf526ba2..03cfddc543 100644
Zbigniew Jędrzejewski-Szmek ea1976
--- a/src/core/shutdown.c
Zbigniew Jędrzejewski-Szmek ea1976
+++ b/src/core/shutdown.c
Zbigniew Jędrzejewski-Szmek ea1976
@@ -75,7 +75,9 @@ static int parse_argv(int argc, char *argv[]) {
Zbigniew Jędrzejewski-Szmek ea1976
         assert(argc >= 1);
Zbigniew Jędrzejewski-Szmek ea1976
         assert(argv);
Zbigniew Jędrzejewski-Szmek ea1976
 
Zbigniew Jędrzejewski-Szmek ea1976
-        while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
Zbigniew Jędrzejewski-Szmek ea1976
+        /* "-" prevents getopt from permuting argv[] and moving the verb away
Zbigniew Jędrzejewski-Szmek ea1976
+         * from argv[1]. Our interface to initrd promises it'll be there. */
Zbigniew Jędrzejewski-Szmek ea1976
+        while ((c = getopt_long(argc, argv, "-", options, NULL)) >= 0)
Zbigniew Jędrzejewski-Szmek ea1976
                 switch (c) {
Zbigniew Jędrzejewski-Szmek ea1976
 
Zbigniew Jędrzejewski-Szmek ea1976
                 case ARG_LOG_LEVEL:
Zbigniew Jędrzejewski-Szmek ea1976
@@ -113,6 +115,13 @@ static int parse_argv(int argc, char *argv[]) {
Zbigniew Jędrzejewski-Szmek ea1976
 
Zbigniew Jędrzejewski-Szmek ea1976
                         break;
Zbigniew Jędrzejewski-Szmek ea1976
 
Zbigniew Jędrzejewski-Szmek ea1976
+                case '\001':
Zbigniew Jędrzejewski-Szmek ea1976
+                        if (!arg_verb)
Zbigniew Jędrzejewski-Szmek ea1976
+                                arg_verb = optarg;
Zbigniew Jędrzejewski-Szmek ea1976
+                        else
Zbigniew Jędrzejewski-Szmek ea1976
+                                log_error("Excess arguments, ignoring");
Zbigniew Jędrzejewski-Szmek ea1976
+                        break;
Zbigniew Jędrzejewski-Szmek ea1976
+
Zbigniew Jędrzejewski-Szmek ea1976
                 case '?':
Zbigniew Jędrzejewski-Szmek ea1976
                         return -EINVAL;
Zbigniew Jędrzejewski-Szmek ea1976
 
Zbigniew Jędrzejewski-Szmek ea1976
@@ -120,15 +129,11 @@ static int parse_argv(int argc, char *argv[]) {
Zbigniew Jędrzejewski-Szmek ea1976
                         assert_not_reached("Unhandled option code.");
Zbigniew Jędrzejewski-Szmek ea1976
                 }
Zbigniew Jędrzejewski-Szmek ea1976
 
Zbigniew Jędrzejewski-Szmek ea1976
-        if (optind >= argc) {
Zbigniew Jędrzejewski-Szmek ea1976
+        if (!arg_verb) {
Zbigniew Jędrzejewski-Szmek ea1976
                 log_error("Verb argument missing.");
Zbigniew Jędrzejewski-Szmek ea1976
                 return -EINVAL;
Zbigniew Jędrzejewski-Szmek ea1976
         }
Zbigniew Jędrzejewski-Szmek ea1976
 
Zbigniew Jędrzejewski-Szmek ea1976
-        arg_verb = argv[optind];
Zbigniew Jędrzejewski-Szmek ea1976
-
Zbigniew Jędrzejewski-Szmek ea1976
-        if (optind + 1 < argc)
Zbigniew Jędrzejewski-Szmek ea1976
-                log_error("Excess arguments, ignoring");
Zbigniew Jędrzejewski-Szmek ea1976
         return 0;
Zbigniew Jędrzejewski-Szmek ea1976
 }
Zbigniew Jędrzejewski-Szmek ea1976