[BusyBox] RE: Init problems?!?

ROGERS,KIM (HP-Cupertino,ex3) kim_rogers at hp.com
Mon Nov 12 19:21:14 UTC 2001


We had a similar problem, so put the following into each of the shells
(shell_main)....

    /* Set signal to  default in case we are run as linuxrc. We don't use 
     * the compile
     * switch since we may need to run a little script before init can run
     * therefore, busybox would not run as linuxrc.
     * Without this we can get into a hang situation if a child
     * (shell command) completes and signals the parent (us) before the
     * parent blocks, becuase do_signal will take the signal, and later
     * when we call waitpid, we will hang forever.
     * This really needs to happen unconditionally, to ensure proper job
     * control and if-then-else conditional processing as well.
     */
    signal(SIGCHLD, SIG_DFL);

Without the above setting of signal handler to default, depending on timing,
the kernel would "eat" the signal (since we are PID 1) and then the shell
would never find out that it's child completed, and move on to the next
command in the shell script. This happened to us when we had a shell script
as the "linuxrc" script...

Hope this helps.


_______________________________________________________________________

Kim Rogers				e-mail:  kim_rogers at hp.com
Embedded Software Operation
Hewlett-Packard Company
1501 Page Mill Road. (ms 6L-1603)	Phone:	(650) 857-4831
Palo Alto, CA 94304-1100		Fax:	(650) 852-8061
_______________________________________________________________________


> -----Original Message-----
> From: Tony Battersby [mailto:tonyb at cybernetics.com]
> Sent: Monday, November 12, 2001 2:06 PM
> To: busybox at busybox.net
> Subject: [BusyBox] RE: Init problems?!?
> 
> 
> I have been tracking down similar problems to the ones 
> reported on this list.  I am using
> ttylinux (http://www.tzi.de/~pharao90/ttylinux/) as the base 
> for an embedded system, which
> uses BusyBox 0.60.1.  I added the command to start my 
> embedded application to rc.local,
> which is the last thing the rc.sysinit script does before 
> exiting to let init spawn getty.
> The first thing my application does is call daemon() to put 
> itself in the background.  I
> found that sometimes the application would start up 
> successfully on power-on, but
> sometimes it wouldn't.  By adding printf's before and after 
> the call to daemon() I was
> able to determine that when the application didn't start 
> successfully, the application was
> able to call daemon() but no child ever returned from the 
> call (yes, I did pass the second
> argument of daemon as a 1 to prevent it from closing stdout 
> and redirecting the printf).
> 
> So, instead of calling daemon() directly, I changed the code 
> to use fork() - exit() -
> setsid() below so that I could experiment (the other stuff 
> daemon() does is irrelevant for
> our purposes).
> 
> int main(int argc, char *argv[])
> {
>    switch(fork())
>       {
>       case -1 :
>          perror("fork()");
>          exit(1);
> 
>       case 0 :
>         /* Child */
>         break;
> 
>       default :
>          /* Parent */
>          printf("Parent exiting\n");
>          exit(0);
>       }
> 
>    printf("Sleeping\n");
>    sleep(1);
>    printf("Awake\n");
> 
>    if (setsid() == -1)
>       {
>       perror("setsid()");
>       exit(1);
>       }
> 
>    for (;;)
>       {
>       printf("Running...\n");
>       sleep(1);
>       }
> }
> 
> Running this program from the end of rc.local, I get either:
> 
> Parent exiting
> 
> or:
> 
> Parent exiting
> Sleeping
> 
> ...depending on the luck of the draw.  Logging in and doing a 
> "ps" shows that the program
> is not running (probably killed by init).  Putting a "sleep 
> 2" in rc.local just after
> starting the program gets:
> 
> Parent exiting
> Sleeping
> Awake
> Running...
> 
> ...and the process is still running when I log in.  This all 
> implies that when the
> rc.sysinit script exits allowing init to continue, all child 
> processes that haven't called
> setsid() yet will be killed.  This is of course a race 
> condition since it is difficult to
> guarantee that a child has had a chance to run.
> 
> BTW, my inittab looks like:
> 
> ::sysinit:/etc/rc.d/rc.sysinit
> 
> tty1::respawn:/sbin/getty 38400 tty1
> tty2::respawn:/sbin/getty 38400 tty2
> tty3::respawn:/sbin/getty 38400 tty3
> tty4::respawn:/sbin/getty 38400 tty4
> tty5::respawn:/sbin/getty 38400 tty5
> tty6::respawn:/sbin/getty 38400 tty6
> 
> ::shutdown:/etc/rc.d/rc.reboot
> ::ctrlaltdel:/sbin/reboot
> 
> I also noticed that once getty is started, additional output 
> of the test program
> ("Running...") no longer shows up on the screen.
> 
> Hopefully this message will narrow it down for the 
> maintainers of BusyBox so that the
> problem can be fixed (assuming that it is a bug).  For now, 
> adding a sleep at the end of
> rc.local is a simple workaround.
> 
> Anthony J. Battersby
> Cybernetics
> 
> 
> 
> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://busybox.net/mailman/listinfo/busybox
> 





More information about the busybox mailing list