[BusyBox] [BUG] rc2, init and askfirst action

Jean Wolter jw5 at os.inf.tu-dresden.de
Fri Aug 6 09:53:16 MDT 2004


Hello,

init hangs and is not able to reape orphaned processes if somone uses
an askfirst action in inittab.

init uses vfork on systems without a mmu (and for some reasons on our
system too because __ARCH_HAS_MMU__ is undefined). vfork() waits until
the child process calls exit() or execve(). Unfortunatly the child
waits for a key before executing execve(). Therefore init blocks and can't
react to any event (not even reboot works)

Attached is the relevant source code from init, showing the
redefinition of fork depending on __ARCH_HAS_MMU__ (do we have to
define this by ourselves or where does it come from) and the endless
loop in the child process leading to a blocked init.

regards,
Jean

#if defined(__UCLIBC__) && !defined(__ARCH_HAS_MMU__)
#define fork	vfork
#endif

static pid_t run(const struct init_action *a)
{
	if ((pid = fork()) == 0) {
		/* If the init Action requires us to wait, then force the
		 * supplied terminal to be the controlling tty. */
		if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) {
		}

		if (a->action & ASKFIRST) {
			char c;
			/*
			 * Save memory by not exec-ing anything large (like a shell)
			 * before the user wants it. This is critical if swap is not
			 * enabled and the system has low memory. Generally this will
			 * be run on the second virtual console, and the first will
			 * be allowed to start a shell or whatever an init script
			 * specifies.
			 */
			messageD(LOG, "Waiting for enter to start '%s'"
						"(pid %d, terminal %s)\n",
					  cmdpath, getpid(), a->terminal);
			bb_full_write(1, press_enter, sizeof(press_enter) - 1);
			while(read(0, &c, 1) == 1 && c != '\n')
				;
		}
		/* Now run it.  The new program will take over this PID,
		 * so nothing further in init.c should be run. */
		execv(cmdpath, cmd);
	}
	sigprocmask(SIG_SETMASK, &omask, NULL);
	return pid;
}


More information about the busybox mailing list