mirror of
https://github.com/troglobit/finit.git
synced 2026-10-02 05:52:48 +07:00
Fix #38: Add --enable-emergency-shell fallback debug mode
This patch adds a very special debug mode to Finit. With this feature enabled the actual duties of PID 1 is forked off early to a child. If that child ever dies, usually due to a SIGSEGV, this wakes up the real PID 1 which lauches a debug shell on the console. Remember to disable 'quiet' and enable '--debug' on the kernel command line to get all the debug logs -- which these days goes into the kernel log in /dev/kmsg -- simply `cat /dev/kmsg` and use Ctrl-C to get the shell prompt back. Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
@@ -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])])
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <mntent.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h> /* umask(), mkdir() */
|
||||
#include <sys/wait.h>
|
||||
#include <lite/lite.h>
|
||||
|
||||
#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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user