[BusyBox-cvs] busybox.stable init.c,1.176,1.177

Erik Andersen andersen at busybox.net
Thu Apr 24 11:41:33 UTC 2003


Update of /var/cvs/busybox.stable
In directory winder:/tmp/cvs-serv8284

Modified Files:
	init.c 
Log Message:
There have been many reports of init failing to reboot and/or failing to halt
over the years.  Well I finally took the time to track this down.  It turns out
that inside linux/kernel/sys.c the kernel will call 
    machine_halt();
    do_exit(0);
when halting, or will call
    machine_power_off();
    do_exit(0);

during a reboot.  Unlike sysv init, we call reboot from within the init
process, so if the call to machine_halt() or machine_power_off() returns, 
the call to do_exit(0) will cause the kernel to panic.  Which is a very
bad thing to happen.

So I just added this little patch to fork and call the reboot
syscall from within the forked child process, thereby neatly 
avoiding the problem.

But IMHO, both calls to do_exit(0) within linux/kernel/sys.c
are bugs,

 -Erik


Index: init.c
===================================================================
RCS file: /var/cvs/busybox.stable/init.c,v
retrieving revision 1.176
retrieving revision 1.177
diff -u -d -r1.176 -r1.177
--- init.c	22 Oct 2002 19:15:43 -0000	1.176
+++ init.c	24 Apr 2003 11:41:30 -0000	1.177
@@ -47,6 +47,10 @@
 #ifdef BB_SYSLOGD
 # include <sys/syslog.h>
 #endif
+#if (__GNU_LIBRARY__ > 5) || defined(__dietlibc__)
+#include <sys/reboot.h>
+#endif
+
 
 #define INIT_BUFFS_SIZE 256
 
@@ -77,13 +81,6 @@
 };
 
 
-#if (__GNU_LIBRARY__ > 5) || defined(__dietlibc__) 
-  #include <sys/reboot.h>
-  #define init_reboot(magic) reboot(magic)
-#else
-  #define init_reboot(magic) reboot(0xfee1dead, 672274793, magic)
-#endif
-
 #ifndef _PATH_STDPATH
 #define _PATH_STDPATH	"/usr/bin:/bin:/usr/sbin:/sbin"
 #endif
@@ -695,6 +692,23 @@
 
 
 #ifndef DEBUG_INIT
+static void init_reboot(unsigned long magic)
+{
+	pid_t pid;
+	/* We have to fork here, since the kernel calls do_exit(0) in
+	 * linux/kernel/sys.c, which can cause the machint to panic when 
+	 * the init process is killed.... */
+	if ((pid = fork()) == 0) {
+#if (__GNU_LIBRARY__ > 5) || defined(__dietlibc__)
+		reboot(magic);
+#else
+		reboot(0xfee1dead, 672274793, magic);
+#endif
+		_exit(0);
+	}
+	waitpid (pid, NULL, 0);
+}
+
 static void shutdown_system(void)
 {
 	sigset_t block_signals;



More information about the busybox-cvs mailing list