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