[systemd-devel] [PATCH 07/11] Support init=/bin/bash on the kernel command line

Werner Fink werner at suse.de
Fri Jun 13 07:41:06 PDT 2014


From: Ruediger Oertel <ro at suse.de>

Process 1 (aka init) needs to be started with an empty signal mask.
That includes the process 1 that's started after the initrd is finished.
When the initrd is using systemd (as it does with dracut based initrds)
then it is systemd that calls the real init.  Normally this is systemd
again, except when the user uses for instance "init=/bin/bash" on the
kernel command line.

---
 src/core/main.c |    9 +++++++++
 1 file changed, 9 insertions(+)

diff --git src/core/main.c src/core/main.c
index d5d1ee2..c082354 100644
--- src/core/main.c
+++ src/core/main.c
@@ -1831,6 +1831,7 @@ finish:
         if (reexecute) {
                 const char **args;
                 unsigned i, args_size;
+                sigset_t ss, o_ss;
 
                 /* Close and disarm the watchdog, so that the new
                  * instance can reinitialize it, but doesn't get
@@ -1914,6 +1915,11 @@ finish:
                 args[i++] = NULL;
                 assert(i <= args_size);
 
+                /* reenable any blocked signals, especially important
+                 * if we switch from initial ramdisk to init=... */
+                sigemptyset(&ss);
+                sigprocmask(SIG_SETMASK,&ss,&o_ss);
+
                 if (switch_root_init) {
                         args[0] = switch_root_init;
                         execv(args[0], (char* const*) args);
@@ -1932,6 +1938,9 @@ finish:
                         log_error("Failed to execute /bin/sh, giving up: %m");
                 } else
                         log_warning("Failed to execute /sbin/init, giving up: %m");
+
+                /* back to saved state if reexec failed */
+                sigprocmask(SIG_SETMASK,&o_ss,NULL);
         }
 
         if (arg_serialization) {
-- 
1.7.9.2



More information about the systemd-devel mailing list