diff --git a/configure.ac b/configure.ac index a9da39f7..5e36bbee 100644 --- a/configure.ac +++ b/configure.ac @@ -37,6 +37,10 @@ PKG_CHECK_MODULES([uev], [libuev >= 1.4.0]) PKG_CHECK_MODULES([lite], [libite >= 1.5.0]) # Check for configured Finit features +AC_ARG_ENABLE(emergency_shell, + AS_HELP_STRING([--enable-emergency-shell], [Experimental emergency fallback at boot. + Only use this for debugging very early boot problems with Finit.])) + AC_ARG_ENABLE(rw-rootfs, AS_HELP_STRING([--enable-rw-rootfs], [Remount / R/W at boot, usually not for embedded])) @@ -117,6 +121,9 @@ AC_ARG_WITH(random-seed, ### Enable features ########################################################################### # Create config.h from selected features and fallback defautls +AS_IF([test "x$enable_emergency_shell" = "xyes"], [ + AC_DEFINE(EMERGENCY_SHELL, 1, [Fork off init and let PID 1 wait and start /bin/sh if init crashes.])]) + AS_IF([test "x$enable_rw_rootfs" = "xyes"], [ AC_DEFINE(REMOUNT_ROOTFS, 1, [Remount / as rw at boot])]) diff --git a/finit.c b/finit.c index 2dc2776e..0365e207 100644 --- a/finit.c +++ b/finit.c @@ -33,6 +33,7 @@ #include #include #include /* umask(), mkdir() */ +#include #include #include "finit.h" @@ -202,6 +203,33 @@ static int fismnt(char *dir) return found; } +/* + * If everything goes south we can use this to give the operator an + * emergency shell to debug the problem -- Finit should not crash! + */ +static void emergency_shell(void) +{ +#ifdef EMERGENCY_SHELL + pid_t pid; + + pid = fork(); + if (pid) { + waitpid(pid, NULL, 0); + fprintf(stderr, "\n=> Embarrassingly, Finit has crashed. Check /dev/kmsg for details.\n"); + fprintf(stderr, "=> For more, remove 'quiet' and add '--debug' to the kernel command line.\n\n"); + + /* + * Become session leader and set controlling TTY + * to enable Ctrl-C and job control in shell. + */ + setsid(); + ioctl(STDIN_FILENO, TIOCSCTTY, 1); + + execl(_PATH_BSHELL, _PATH_BSHELL, NULL); + } +#endif /* EMERGENCY_SHELL */ +} + int main(int argc, char* argv[]) { int err; @@ -215,6 +243,11 @@ int main(int argc, char* argv[]) if (getpid() != 1) return client(argc, argv); + /* + * In case of emergency. + */ + emergency_shell(); + /* * Hello world. */