svn commit: trunk/busybox/init

vda at busybox.net vda at busybox.net
Sat Jan 31 19:26:14 UTC 2009


Author: vda
Date: 2009-01-31 19:26:12 +0000 (Sat, 31 Jan 2009)
New Revision: 25184

Log:
init: remove wait() loop on restart, it may be dangerous



Modified:
   trunk/busybox/init/init.c


Changeset:
Modified: trunk/busybox/init/init.c
===================================================================
--- trunk/busybox/init/init.c	2009-01-31 19:08:20 UTC (rev 25183)
+++ trunk/busybox/init/init.c	2009-01-31 19:26:12 UTC (rev 25184)
@@ -418,14 +418,16 @@
 	_exit(-1);
 }
 
-static struct init_action *mark_terminated(int pid)
+static struct init_action *mark_terminated(pid_t pid)
 {
 	struct init_action *a;
 
-	for (a = init_action_list; a; a = a->next) {
-		if (a->pid == pid) {
-			a->pid = 0;
-			return a;
+	if (pid > 0) {
+		for (a = init_action_list; a; a = a->next) {
+			if (a->pid == pid) {
+				a->pid = 0;
+				return a;
+			}
 		}
 	}
 	return NULL;
@@ -444,7 +446,7 @@
 		mark_terminated(wpid);
 		/* Unsafe. SIGTSTP handler might have wait'ed it already */
 		/*if (wpid == pid) break;*/
-		/* More reliable */
+		/* More reliable: */
 		if (kill(pid, 0))
 			break;
 	}
@@ -697,11 +699,11 @@
  */
 static void stop_handler(int sig UNUSED_PARAM)
 {
+	smallint saved_bb_got_signal;
 	int saved_errno;
-	smallint saved_bb_got_signal;
 
+	saved_bb_got_signal = bb_got_signal;
 	saved_errno = errno;
-	saved_bb_got_signal = bb_got_signal;
 	signal(SIGCONT, record_signo);
 
 	while (1) {
@@ -714,14 +716,13 @@
 		 * code which is resilient against this.
 		 */
 		wpid = wait_any_nohang(NULL);
-		if (wpid > 0)
-			mark_terminated(wpid);
+		mark_terminated(wpid);
 		sleep(1);
 	}
 
 	signal(SIGCONT, SIG_DFL);
+	errno = saved_errno;
 	bb_got_signal = saved_bb_got_signal;
-	errno = saved_errno;
 }
 
 /* Handler for QUIT - exec "restart" action,
@@ -747,8 +748,14 @@
 
 		if (open_stdio_to_tty(a->terminal)) {
 			dbg_message(L_CONSOLE, "Trying to re-exec %s", a->command);
-			while (wait(NULL) > 0)
-				continue;
+			/* Theoretically should be safe.
+			 * But in practice, kernel bugs may leave
+			 * unkillable processes, and wait() may block forever.
+			 * Oh well. Hoping "new" init won't be too surprised
+			 * by having children it didn't create.
+			 */
+			//while (wait(NULL) > 0)
+			//	continue;
 			init_exec(a->command);
 		}
 		/* Open or exec failed */
@@ -990,14 +997,14 @@
 
 		got_sigs |= check_delayed_sigs();
 
+		if (got_sigs)
+			goto dont_block;
 		/* Wait for any child process to exit.
 		 * NB: "delayed" signals will also interrupt this wait(),
 		 * bb_signals_recursive_norestart() set them up for that.
 		 * This guarantees we won't be stuck here
 		 * till next orphan dies.
 		 */
-		if (got_sigs)
-			goto dont_block;
 		wpid = wait(NULL);
 		while (wpid > 0) {
 			struct init_action *a = mark_terminated(wpid);



More information about the busybox-cvs mailing list