[PATCH] halt: add option to call telinit when using external init

Alexander Shishkin virtuoso at slind.org
Tue Jul 21 21:31:51 UTC 2009


In case our init is not a busybox applet, but an external program
like SysV init or upstart, we'd want to be able to call telinit
(or somesuch) to switch to an appropriate runlevel instead of
simply rebooting (or otherwise shutting down).

function                                             old     new   delta
halt_main                                            149     186     +37
.rodata                                           125022  125038     +16
static.signals                                         3       -      -3
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 2/0 up/down: 53/-3)              Total: 50 bytes

Signed-off-by: Alexander Shishkin <virtuoso at slind.org>
---
 init/Config.in |   18 ++++++++++++++++++
 init/halt.c    |   17 ++++++++++++++---
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/init/Config.in b/init/Config.in
index 1a1be4a..ab89afc 100644
--- a/init/Config.in
+++ b/init/Config.in
@@ -93,6 +93,24 @@ config HALT
 	help
 	  Stop all processes and either halt, reboot, or power off the system.
 
+config FEATURE_CALL_TELINIT
+	bool "Call telinit on shutdown and reboot"
+	default n
+	depends on HALT && !INIT
+	help
+	  In case when halt and friends are provided by busybox, but init
+	  is not, call an external program (normally telinit) to facilitate
+	  a switch to a proper runlevel.
+
+config TELINIT_PATH
+	string "Path to telinit executable"
+	default "/sbin/telinit"
+	depends on FEATURE_CALL_TELINIT
+	help
+	  When busybox halt and friends have to call external telinit
+	  to facilitate proper shutdown, this path is to be used when
+	  locating telinit executable.
+
 config MESG
 	bool "mesg"
 	default n
diff --git a/init/halt.c b/init/halt.c
index 3a23eca..cde7fc7 100644
--- a/init/halt.c
+++ b/init/halt.c
@@ -90,9 +90,20 @@ int halt_main(int argc UNUSED_PARAM, char **argv)
 				rc = kill(pidlist[0], signals[which]);
 			if (ENABLE_FEATURE_CLEAN_UP)
 				free(pidlist);
-		}
-		if (rc) {
-			rc = kill(1, signals[which]);
+
+			if (rc)
+				rc = kill(1, signals[which]);
+		} else if (ENABLE_FEATURE_CALL_TELINIT) {
+			/* runlevels:
+			 * 0 == shutdown
+			 * 6 == reboot */
+			const char *const args[] = {
+				"telinit",
+				which == 2 ? "6" : "0",
+				NULL
+			};
+
+			rc = execvp(CONFIG_TELINIT_PATH, (char **)args);
 		}
 	} else {
 		rc = reboot(magic[which]);
-- 
1.6.3.3



More information about the busybox mailing list