[BusyBox] RE: Init problems?!?

Tony Battersby tonyb at cybernetics.com
Mon Nov 12 18:54:02 UTC 2001


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






More information about the busybox mailing list