Zbigniew Jędrzejewski-Szmek 5d6eed
From 0e2e7e8269dacd5845150170d3d47c2d677474ab Mon Sep 17 00:00:00 2001
Adam Williamson 4c60d7
From: Franck Bui <fbui@suse.com>
Adam Williamson 4c60d7
Date: Thu, 24 Nov 2016 18:52:04 +0100
Adam Williamson 4c60d7
Subject: [PATCH] core: make sure initrd-switch-root command survives PID1's
Adam Williamson 4c60d7
 killing spree (#4730)
Adam Williamson 4c60d7
Adam Williamson 4c60d7
This is a different way to implement the fix proposed by commit
Adam Williamson 4c60d7
a4021390fef27f4136497328f suggested by Lennart Poettering.
Adam Williamson 4c60d7
Adam Williamson 4c60d7
In this patch we instruct PID1 to not kill "systemctl switch-root" command
Adam Williamson 4c60d7
started by initrd-switch-root service using the "argv[0][0]='@'" trick.
Adam Williamson 4c60d7
Adam Williamson 4c60d7
See: https://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons/ for
Adam Williamson 4c60d7
more details.
Adam Williamson 4c60d7
Adam Williamson 4c60d7
We had to backup argv[0] because argv is modified by dispatch_verb().
Zbigniew Jędrzejewski-Szmek 03e93e
(cherry picked from commit acc28e2e3037d689d6481e4664925cf31d4d087b)
Adam Williamson 4c60d7
---
Adam Williamson 4c60d7
 src/systemctl/systemctl.c           | 10 ++++++++++
Zbigniew Jędrzejewski-Szmek 03e93e
 units/initrd-switch-root.service.in |  8 +-------
Zbigniew Jędrzejewski-Szmek 03e93e
 2 files changed, 11 insertions(+), 7 deletions(-)
Adam Williamson 4c60d7
Adam Williamson 4c60d7
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
Zbigniew Jędrzejewski-Szmek 03e93e
index dd3b931cd6..a2b667481d 100644
Adam Williamson 4c60d7
--- a/src/systemctl/systemctl.c
Adam Williamson 4c60d7
+++ b/src/systemctl/systemctl.c
Adam Williamson 4c60d7
@@ -142,6 +142,7 @@ static const char *arg_kill_who = NULL;
Adam Williamson 4c60d7
 static int arg_signal = SIGTERM;
Adam Williamson 4c60d7
 static char *arg_root = NULL;
Adam Williamson 4c60d7
 static usec_t arg_when = 0;
Adam Williamson 4c60d7
+static char *argv_cmdline = NULL;
Adam Williamson 4c60d7
 static enum action {
Adam Williamson 4c60d7
         _ACTION_INVALID,
Adam Williamson 4c60d7
         ACTION_SYSTEMCTL,
Zbigniew Jędrzejewski-Szmek 03e93e
@@ -5584,6 +5585,13 @@ static int switch_root(int argc, char *argv[], void *userdata) {
Adam Williamson 4c60d7
                         init = NULL;
Adam Williamson 4c60d7
         }
Adam Williamson 4c60d7
 
Adam Williamson 4c60d7
+        /* Instruct PID1 to exclude us from its killing spree applied during
Adam Williamson 4c60d7
+         * the transition from the initrd to the main system otherwise we would
Adam Williamson 4c60d7
+         * exit with a failure status even though the switch to the new root
Adam Williamson 4c60d7
+         * has succeed. */
Adam Williamson 4c60d7
+        if (in_initrd())
Adam Williamson 4c60d7
+                argv_cmdline[0] = '@';
Adam Williamson 4c60d7
+
Adam Williamson 4c60d7
         r = acquire_bus(BUS_MANAGER, &bus;;
Adam Williamson 4c60d7
         if (r < 0)
Adam Williamson 4c60d7
                 return r;
Zbigniew Jędrzejewski-Szmek 03e93e
@@ -8324,6 +8332,8 @@ static int logind_cancel_shutdown(void) {
Adam Williamson 4c60d7
 int main(int argc, char*argv[]) {
Adam Williamson 4c60d7
         int r;
Adam Williamson 4c60d7
 
Adam Williamson 4c60d7
+        argv_cmdline = argv[0];
Adam Williamson 4c60d7
+
Adam Williamson 4c60d7
         setlocale(LC_ALL, "");
Adam Williamson 4c60d7
         log_parse_environment();
Adam Williamson 4c60d7
         log_open();
Zbigniew Jędrzejewski-Szmek 03e93e
diff --git a/units/initrd-switch-root.service.in b/units/initrd-switch-root.service.in
Zbigniew Jędrzejewski-Szmek 03e93e
index b89f2348c7..82893dafb1 100644
Zbigniew Jędrzejewski-Szmek 03e93e
--- a/units/initrd-switch-root.service.in
Zbigniew Jędrzejewski-Szmek 03e93e
+++ b/units/initrd-switch-root.service.in
Zbigniew Jędrzejewski-Szmek 03e93e
@@ -17,10 +17,4 @@ AllowIsolate=yes
Zbigniew Jędrzejewski-Szmek 03e93e
 Type=oneshot
Zbigniew Jędrzejewski-Szmek 03e93e
 # we have to use "--force" here, otherwise systemd would umount /run
Zbigniew Jędrzejewski-Szmek 03e93e
 ExecStart=@rootbindir@/systemctl --no-block --force switch-root /sysroot
Zbigniew Jędrzejewski-Szmek 03e93e
-
Zbigniew Jędrzejewski-Szmek 03e93e
-# Just before switching to the new rootfs, systemd might send us a TERM signal
Zbigniew Jędrzejewski-Szmek 03e93e
-# depending on how fast we are to execute the main command and exit. If we get
Zbigniew Jędrzejewski-Szmek 03e93e
-# the SIGTERM signal that simply means that we succeed but haven't got enough
Zbigniew Jędrzejewski-Szmek 03e93e
-# time to exit properly. Since systemd considers SIGTERM as a failure for
Zbigniew Jędrzejewski-Szmek 03e93e
-# short-running process (aka Type=oneshot), instruct it to ignore this case.
Zbigniew Jędrzejewski-Szmek 03e93e
-SuccessExitStatus=SIGTERM
Zbigniew Jędrzejewski-Szmek 03e93e
+KillMode=none