On Thursday 03 April 2008 23:33, Harald Kuethe wrote:
> > ----- Original Message -----
> > From: "Denys Vlasenko" <[EMAIL PROTECTED]>
> > To: "Harald Kuethe" <[EMAIL PROTECTED]>
> > Cc: <[email protected]>
> > Sent: Wednesday, April 02, 2008 11:41 PM
> > Subject: Re: [PATCH] init.c, halt command not working
>
> ...
>
> > kill() returns 0 (success), so the system thinks that SIGTERM is delivered.
> > But init does not print your debug message. Very strange.
> > killall did the very same thing: "kill(1, SIGTERM)" and it worked...
>
> > Please try attached idagnostic patch.
> > It will spam your console if it will detect that init
> > has TERM blocked or set to unexpected handler.
>
> > Try to "kill 1" and "kill -USR1 1" and report what init says.
> > --
> > vda
>
> This patch adds no additional output :-/
> I put some more debugging output into the init_main function to find out
> where it hangs.
> It showed that init_main does not return from the run_actions(ASKFIRST);
> call,
> this explains that the additional diagnostics didn't come up.
>
> Following lines are copied from our inittab:
> ...
> ::askfirst:-/bin/sh
> vc/2::askfirst:-/bin/sh
> vc/3::askfirst:-/bin/sh
> ...
>
> It looks as if the init process is replaced by the shell without finishing
> generating the virtual consoles and waiting in the while loop
> because there are only 2 init processes here (there were some more (one for
> each vc) with the fork() instead of the vfork())
Huh. Soulds almost as if vfork() never returns in parent... ?!
Can you check?
static pid_t run(const struct init_action *a)
{
pid_t pid;
sigset_t nmask, omask;
/* Block sigchild while forking (why?) */
sigemptyset(&nmask);
sigaddset(&nmask, SIGCHLD);
sigprocmask(SIG_BLOCK, &nmask, &omask);
pid = vfork();
+bb_error_msg("vfork returned %d", (int)pid);
sigprocmask(SIG_SETMASK, &omask, NULL);
...
and here:
static void run_actions(int action_type)
{
struct init_action *a, *tmp;
for (a = init_action_list; a; a = tmp) {
tmp = a->next;
if (a->action_type == action_type) {
// Pointless: run() will error out if open of device
fails.
///* a->terminal of "" means "init's console" */
//if (a->terminal[0] && access(a->terminal, R_OK |
W_OK)) {
// //message(L_LOG | L_CONSOLE, "Device %s cannot
be opened in RW mode", a->terminal /*, strerror(errno)*/);
// delete_init_action(a);
//} else
if (a->action_type & (SYSINIT | WAIT | CTRLALTDEL |
SHUTDOWN | RESTART)) {
+bb_error_msg("before waitfor(run(a))");
waitfor(run(a));
+bb_error_msg("after waitfor(run(a))");
delete_init_action(a);
} else if (a->action_type & ONCE) {
+bb_error_msg("before run(a)");
run(a);
+bb_error_msg("after run(a)");
delete_init_action(a);
} else if (a->action_type & (RESPAWN | ASKFIRST)) {
/* Only run stuff with pid==0. If they have
* a pid, that means it is still running */
if (a->pid == 0) {
+bb_error_msg("before a->pid = run(a)");
a->pid = run(a);
+bb_error_msg("after a->pid = run(a)");
}
}
and here:
static void waitfor(pid_t pid)
{
/* waitfor(run(x)): protect against failed fork inside run() */
if (pid <= 0)
return;
+bb_error_msg("waiting for %d", (int)pid);
/* Wait for any child (prevent zombies from exiting orphaned processes)
* but exit the loop only when specified one has exited. */
while (wait(NULL) != pid)
continue;
}
--
vda
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox