PATCH: removing hardcoded paths from init

Gabriel L. Somlo somlo at cmu.edu
Fri Jan 19 23:19:19 UTC 2007


On Thu, Jan 18, 2007 at 01:56:28AM +0100, Denis Vlasenko wrote:
> 
> FEATURE_EXEC_PREFER_APPLETS is ok I think.

Denis,

Enclosed is the patch that adds FEATURE_EXEC_PREFER_APPLETS to the
config setup, changes xfuncs.c spawn() to use it instead of
STANDALONE_SHELL, and makes use of it from init.c to remove hardcoded
paths.

I'm working on another patch to have a busybox-specific family of exec*p
routines that use FEATURE_EXEC_PREFER_APPLETS; when that's done, we
can redo spawn(), init.c, and whatever else we think necessary to just
call these exec functions instead of the standard library exec
functions.

Just wanted this patch to get in so I can stop getting 'Bummer,
couldn't execute /sbin/umount' type error messages from init when I
don't have the symlinks installed :)

Regards,
Gabriel

diff -NarU5 busybox-svn-17314.orig/Config.in busybox-svn-17314/Config.in
--- busybox-svn-17314.orig/Config.in	2007-01-15 15:18:07.000000000 -0500
+++ busybox-svn-17314/Config.in	2007-01-19 17:58:46.000000000 -0500
@@ -229,10 +229,18 @@
 		LDFLAGS=-L<libselinux-lib-path> \
 		make
 
 	  Most people will leave this set to 'N'.
 
+config FEATURE_EXEC_PREFER_APPLETS
+        bool "exec prefers applets"
+        default n
+        help
+          This is an experimental option which directs applets about to
+          call 'exec' to try and find an applicable busybox applet before
+          searching the executable path for a binary or symlink to execute.
+
 config BUSYBOX_EXEC_PATH
 	string "Path to BusyBox executable"
 	default "/proc/self/exe"
 	help
 	  When Busybox applets need to run other busybox applets, BusyBox
@@ -437,11 +445,11 @@
          on a filesystem with few inodes.
 
 config INSTALL_APPLET_DONT
        bool
        prompt "not installed"
-       depends on FEATURE_INSTALLER || FEATURE_SH_STANDALONE_SHELL
+       depends on FEATURE_INSTALLER || FEATURE_SH_STANDALONE_SHELL || FEATURE_EXEC_PREFER_APPLETS
        help
          Do not install applet links. Useful when using the -install feature
          or a standalone shell for rescue pruposes.
 
 endchoice
diff -NarU5 busybox-svn-17314.orig/init/init.c busybox-svn-17314/init/init.c
--- busybox-svn-17314.orig/init/init.c	2007-01-15 15:18:06.000000000 -0500
+++ busybox-svn-17314/init/init.c	2007-01-19 17:13:38.000000000 -0500
@@ -387,10 +387,11 @@
 	static const char press_enter[] =
 #ifdef CUSTOMIZED_BANNER
 #include CUSTOMIZED_BANNER
 #endif
 		"\nPlease press Enter to activate this console. ";
+	void *app;
 
 	/* Block sigchild while forking.  */
 	sigemptyset(&nmask);
 	sigaddset(&nmask, SIGCHLD);
 	sigprocmask(SIG_BLOCK, &nmask, &omask);
@@ -558,11 +559,12 @@
 		}
 #endif
 
 		/* Now run it.  The new program will take over this PID,
 		 * so nothing further in init.c should be run. */
-		execv(cmdpath, cmd);
+		app = ENABLE_FEATURE_EXEC_PREFER_APPLETS ? find_applet_by_name(cmdpath) : NULL;
+		execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : cmdpath, cmd);
 
 		/* We're still here?  Some error happened. */
 		message(LOG | CONSOLE, "Bummer, cannot run '%s': %m", cmdpath);
 		_exit(-1);
 	}
@@ -676,10 +678,11 @@
 
 static void exec_signal(int sig ATTRIBUTE_UNUSED)
 {
 	struct init_action *a, *tmp;
 	sigset_t unblock_signals;
+	void *app;
 
 	for (a = init_action_list; a; a = tmp) {
 		tmp = a->next;
 		if (a->action & RESTART) {
 			shutdown_system();
@@ -711,11 +714,12 @@
 			/* Setup stdout, stderr on the supplied terminal */
 			dup(0);
 			dup(0);
 
 			messageD(CONSOLE | LOG, "Trying to re-exec %s", a->command);
-			execl(a->command, a->command, NULL);
+			app = ENABLE_FEATURE_EXEC_PREFER_APPLETS ? find_applet_by_name(a->command) : NULL;
+			execlp(app ? CONFIG_BUSYBOX_EXEC_PATH : a->command, a->command, NULL);
 
 			message(CONSOLE | LOG, "exec of '%s' failed: %m",
 					a->command);
 			sync();
 			sleep(2);
@@ -850,17 +854,17 @@
 	file = fopen(INITTAB, "r");
 	if (file == NULL) {
 		/* No inittab file -- set up some default behavior */
 #endif
 		/* Reboot on Ctrl-Alt-Del */
-		new_init_action(CTRLALTDEL, "/sbin/reboot", "");
+		new_init_action(CTRLALTDEL, "reboot", "");
 		/* Umount all filesystems on halt/reboot */
-		new_init_action(SHUTDOWN, "/bin/umount -a -r", "");
+		new_init_action(SHUTDOWN, "umount -a -r", "");
 		/* Swapoff on halt/reboot */
-		if(ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "/sbin/swapoff -a", "");
+		if(ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");
 		/* Prepare to restart init when a HUP is received */
-		new_init_action(RESTART, "/sbin/init", "");
+		new_init_action(RESTART, "init", "");
 		/* Askfirst shell on tty1-4 */
 		new_init_action(ASKFIRST, bb_default_login_shell, "");
 		new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
 		new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
 		new_init_action(ASKFIRST, bb_default_login_shell, VC_4);
@@ -1037,13 +1041,13 @@
 		if (!sysinfo(&info) &&
 			(info.mem_unit ? : 1) * (long long)info.totalram < 1024*1024)
 		{
 			message(CONSOLE,"Low memory: forcing swapon.");
 			/* swapon -a requires /proc typically */
-			new_init_action(SYSINIT, "/bin/mount -t proc proc /proc", "");
+			new_init_action(SYSINIT, "mount -t proc proc /proc", "");
 			/* Try to turn on swap */
-			new_init_action(SYSINIT, "/sbin/swapon -a", "");
+			new_init_action(SYSINIT, "swapon -a", "");
 			run_actions(SYSINIT);   /* wait and removing */
 		}
 	}
 
 	/* Check if we are supposed to be in single user mode */
@@ -1066,11 +1070,12 @@
 	if (getenv("SELINUX_INIT") == NULL) {
 		int enforce = 0;
 
 		putenv("SELINUX_INIT=YES");
 		if (selinux_init_load_policy(&enforce) == 0) {
-			execv(argv[0], argv);
+			void *app = ENABLE_FEATURE_EXEC_PREFER_APPLETS ? find_applet_by_name(argv[0]) : NULL;
+			execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : argv[0], argv);
 		} else if (enforce > 0) {
 			/* SELinux in enforcing mode but load_policy failed */
 			/* At this point, we probably can't open /dev/console, so log() won't work */
 			message(CONSOLE,"Unable to load SELinux Policy. Machine is in enforcing mode. Halting now.");
 			exit(1);
diff -NarU5 busybox-svn-17314.orig/libbb/xfuncs.c busybox-svn-17314/libbb/xfuncs.c
--- busybox-svn-17314.orig/libbb/xfuncs.c	2007-01-15 15:18:04.000000000 -0500
+++ busybox-svn-17314/libbb/xfuncs.c	2007-01-19 17:13:59.000000000 -0500
@@ -181,11 +181,11 @@
 pid_t spawn(char **argv)
 {
 	/* Why static? */
 	static int failed;
 	pid_t pid;
-	void *app = ENABLE_FEATURE_SH_STANDALONE_SHELL ? find_applet_by_name(argv[0]) : 0;
+	void *app = ENABLE_FEATURE_EXEC_PREFER_APPLETS ? find_applet_by_name(argv[0]) : 0;
 
 	// Be nice to nommu machines.
 	failed = 0;
 	pid = vfork();
 	if (pid < 0) return pid;
diff -NarU5 busybox-svn-17314.orig/scripts/defconfig busybox-svn-17314/scripts/defconfig
--- busybox-svn-17314.orig/scripts/defconfig	2007-01-15 15:17:59.000000000 -0500
+++ busybox-svn-17314/scripts/defconfig	2007-01-19 18:10:04.000000000 -0500
@@ -25,10 +25,11 @@
 CONFIG_FEATURE_SUID=y
 CONFIG_FEATURE_SYSLOG=y
 CONFIG_FEATURE_SUID_CONFIG=y
 CONFIG_FEATURE_SUID_CONFIG_QUIET=y
 # CONFIG_SELINUX is not set
+#CONFIG_FEATURE_EXEC_PREFER_APPLETS is not set
 CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe"
 
 #
 # Build Options
 #



More information about the busybox mailing list