svn commit: trunk/busybox/init

vda at busybox.net vda at busybox.net
Wed Dec 26 18:33:02 UTC 2007


Author: vda
Date: 2007-12-26 10:32:58 -0800 (Wed, 26 Dec 2007)
New Revision: 20687

Log:
init: don't spawn tons of waiting children, one is enough
init: shrink signal disabling code
init: rename some functions
   text    data     bss     dec     hex filename
 778657     832    7344  786833   c0191 busybox_old
 778445     832    7344  786621   c00bd busybox_unstripped



Modified:
   trunk/busybox/init/init.c


Changeset:
Modified: trunk/busybox/init/init.c
===================================================================
--- trunk/busybox/init/init.c	2007-12-25 16:08:53 UTC (rev 20686)
+++ trunk/busybox/init/init.c	2007-12-26 18:32:58 UTC (rev 20687)
@@ -96,8 +96,9 @@
 /* Function prototypes */
 static void delete_init_action(struct init_action *a);
 static int waitfor(pid_t pid);
-static void shutdown_signal(int sig);
+static void halt_reboot_pwoff(int sig) ATTRIBUTE_NORETURN;
 
+static void loop_forever(void) ATTRIBUTE_NORETURN;
 static void loop_forever(void)
 {
 	while (1)
@@ -259,26 +260,25 @@
 }
 
 /* Open the new terminal device */
-static void open_stdio_to_tty(const char* tty_name, int fail)
+static void open_stdio_to_tty(const char* tty_name, int exit_on_failure)
 {
 	/* empty tty_name means "use init's tty", else... */
 	if (tty_name[0]) {
-		int fd = device_open(tty_name, O_RDWR);
-		if (fd < 0) {
+		int fd;
+		close(0);
+		/* fd can be only < 0 or 0: */
+		fd = device_open(tty_name, O_RDWR);
+		if (fd) {
 			message(L_LOG | L_CONSOLE, "Can't open %s: %s",
 				tty_name, strerror(errno));
-			if (fail)
+			if (exit_on_failure)
 				_exit(1);
-			if (!ENABLE_DEBUG_INIT)
-				shutdown_signal(SIGUSR1);
-			else
+			if (ENABLE_DEBUG_INIT)
 				_exit(2);
-		} else {
-			dup2(fd, 0);
-			dup2(fd, 1);
-			dup2(fd, 2);
-			if (fd > 2) close(fd);
+			halt_reboot_pwoff(SIGUSR1); /* halt the system */
 		}
+		dup2(0, 1);
+		dup2(0, 2);
 	}
 	set_sane_term();
 }
@@ -412,9 +412,7 @@
 		}
 #endif
 
-		/* Establish this process as session leader and
-		 * _attempt_ to make stdin a controlling tty.
-		 */
+		/* _Attempt_ to make stdin a controlling tty. */
 		if (ENABLE_FEATURE_INIT_SCTTY)
 			ioctl(0, TIOCSCTTY, 0 /*only try, don't steal*/);
 	}
@@ -525,7 +523,7 @@
 	waitpid(pid, NULL, 0);
 }
 
-static void shutdown_system(void)
+static void kill_all_processes(void)
 {
 	sigset_t block_signals;
 
@@ -535,7 +533,8 @@
 	run_actions(SHUTDOWN);
 
 	/* first disable all our signals */
-	sigemptyset(&block_signals);
+	sigfillset(&block_signals);
+	/*sigemptyset(&block_signals);
 	sigaddset(&block_signals, SIGHUP);
 	sigaddset(&block_signals, SIGQUIT);
 	sigaddset(&block_signals, SIGCHLD);
@@ -545,7 +544,7 @@
 	sigaddset(&block_signals, SIGTERM);
 	sigaddset(&block_signals, SIGCONT);
 	sigaddset(&block_signals, SIGSTOP);
-	sigaddset(&block_signals, SIGTSTP);
+	sigaddset(&block_signals, SIGTSTP);*/
 	sigprocmask(SIG_BLOCK, &block_signals, NULL);
 
 	message(L_CONSOLE | L_LOG, "The system is going down NOW!");
@@ -565,12 +564,12 @@
 	sleep(1);
 }
 
-static void shutdown_signal(int sig)
+static void halt_reboot_pwoff(int sig)
 {
 	const char *m;
 	int rb;
 
-	shutdown_system();
+	kill_all_processes();
 
 	m = "halt";
 	rb = RB_HALT_SYSTEM;
@@ -588,7 +587,9 @@
 	loop_forever();
 }
 
-static void exec_signal(int sig ATTRIBUTE_UNUSED)
+/* Handler for HUP and QUIT - exec "restart" action,
+ * else (no such action defined) do nothing */
+static void exec_restart_action(int sig ATTRIBUTE_UNUSED)
 {
 	struct init_action *a, *tmp;
 	sigset_t unblock_signals;
@@ -596,10 +597,11 @@
 	for (a = init_action_list; a; a = tmp) {
 		tmp = a->next;
 		if (a->action & RESTART) {
-			shutdown_system();
+			kill_all_processes();
 
-			/* unblock all signals, blocked in shutdown_system() */
-			sigemptyset(&unblock_signals);
+			/* unblock all signals (blocked in kill_all_processes()) */
+			sigfillset(&unblock_signals);
+			/*sigemptyset(&unblock_signals);
 			sigaddset(&unblock_signals, SIGHUP);
 			sigaddset(&unblock_signals, SIGQUIT);
 			sigaddset(&unblock_signals, SIGCHLD);
@@ -609,11 +611,11 @@
 			sigaddset(&unblock_signals, SIGTERM);
 			sigaddset(&unblock_signals, SIGCONT);
 			sigaddset(&unblock_signals, SIGSTOP);
-			sigaddset(&unblock_signals, SIGTSTP);
+			sigaddset(&unblock_signals, SIGTSTP);*/
 			sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL);
 
 			/* Open the new terminal device */
-			open_stdio_to_tty(a->terminal, 0 /* - shutdown_signal(SIGUSR1) [halt] if open fails */);
+			open_stdio_to_tty(a->terminal, 0 /* - halt if open fails */);
 
 			messageD(L_CONSOLE | L_LOG, "Trying to re-exec %s", a->command);
 			BB_EXECLP(a->command, a->command, NULL);
@@ -812,19 +814,25 @@
 	parse_inittab();
 
 	if (ENABLE_FEATURE_KILL_REMOVED) {
+		/* Be nice and send SIGTERM first */
 		for (a = init_action_list; a; a = a->next) {
 			pid_t pid = a->pid;
 			if ((a->action & ONCE) && pid != 0) {
-				/* Be nice and send SIGTERM first */
 				kill(pid, SIGTERM);
-				if (CONFIG_FEATURE_KILL_DELAY)
-					if (fork() == 0) { /* child */
-						sleep(CONFIG_FEATURE_KILL_DELAY);
-						kill(pid, SIGKILL);
-						_exit(0);
-					}
 			}
 		}
+#if CONFIG_FEATURE_KILL_DELAY
+		if (fork() == 0) { /* child */
+			sleep(CONFIG_FEATURE_KILL_DELAY);
+			for (a = init_action_list; a; a = a->next) {
+				pid_t pid = a->pid;
+				if ((a->action & ONCE) && pid != 0) {
+					kill(pid, SIGKILL);
+				}
+			}
+			_exit(0);
+		}
+#endif
 	}
 
 	/* remove unused entrys */
@@ -858,12 +866,12 @@
 		}
 		/* Set up sig handlers  -- be sure to
 		 * clear all of these in run() */
-		signal(SIGHUP, exec_signal);
-		signal(SIGQUIT, exec_signal);
-		signal(SIGUSR1, shutdown_signal);
-		signal(SIGUSR2, shutdown_signal);
+		signal(SIGHUP, exec_restart_action);
+		signal(SIGQUIT, exec_restart_action);
+		signal(SIGUSR1, halt_reboot_pwoff); /* halt */
+		signal(SIGUSR2, halt_reboot_pwoff); /* poweroff */
+		signal(SIGTERM, halt_reboot_pwoff); /* reboot */
 		signal(SIGINT, ctrlaltdel_signal);
-		signal(SIGTERM, shutdown_signal);
 		signal(SIGCONT, cont_handler);
 		signal(SIGSTOP, stop_handler);
 		signal(SIGTSTP, stop_handler);




More information about the busybox-cvs mailing list