1

I have a question regarding how the init process in UNIX works. As i understand it the init process is the first to start and then other processes fork off it.

Say we start the init process then fork a child process which we call exec on with a new program which happens to cause the child to wait for some I/O input. Now the parent init process could wait on the child but if it did that then there are no other processes to be run. Conversely if the init process does not wait and instead falls into a waiting loop or something then when the child is resumed the parent is now taking up processor time doing nothing.

What is the best way to manage this problem? Should the init process simply always run an infinite loop and we not worry about the wasted resources? Or is there a better way.

Any help would be much appreciated, Ben

BenJacob
  • 957
  • 10
  • 31

4 Answers4

1

There is a solution for this: SIGCHLD. It's a signal that can be delivered to parent when a child changes its status (stops or exits). So the parent can goes sleeping (sigpause, sigsuspend for example) and will be interrupted when a child terminates, then the parent runs an appropriate signal handler to call one of the wait-family functions.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
  • So am I right in thinking that the `wait` system call only resumes the parent process once the child terminates and the `SIGCHILD` signal is different to the `wait` mechanism? – BenJacob Apr 25 '16 at 11:43
  • `wait` is used to: get the exit status of the terminated child, and remove the child process from the process list (no zombie). `wait` does not resume anything. `wait` can synchronously wait for child termination, SIGCHILD is an asynchronous event to warn that a children terminated. – Jean-Baptiste Yunès Apr 25 '16 at 14:14
1

Process 1 must never exit; many (all?) implementations of Unix will force a system crash if it does.

However, process 1 doesn't need to do anything more than this (I'm assuming the kernel opens fds 0, 1, and 2 on the console before transferring control to user space - check your kernel's documentation for that and other details of the bootstrap environment, if you're actually gonna write init yourself):

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>

int main(void)
{
    pid_t child = fork();
    if (child == -1) {
        perror("init: fork");
        return 1;
    }
    if (child == 0) {
        execl("/etc/rc", "/etc/rc", (char*)0);
        perror("/etc/rc");
        return 1;
    }
    for (;;)
        wait(0);
}

After starting /etc/rc it does go into an infinite loop, calling wait over and over again, and throwing away the results. But wait is a blocking system call. Each time it's called the kernel will take the CPU away from process 1 and give it to a process that has useful work to do; wait will only return when there is an exited child to report. (If there are no processes with useful work to do, the CPU will be put into a low-power "sleep" state until some external event, e.g. a human typing on the keyboard or a network packet arriving, gives a running process some work to do.)

With this minimal init, it is entirely /etc/rc's responsibility to start up all of the programs needed to make the computer do something useful, and those programs' responsibility to keep running as long as needed; if it should come to pass that every process other than this one exits, it'll just sleep in wait forever. More sophisticated implementations will do more, e.g. restarting network servers if they crash.

zwol
  • 135,547
  • 38
  • 252
  • 361
0

I would not worry about resources during init start up. Your server is booting up and not being used for it's intended purpose, therefore there is not a performance demand on it during that time.

I have never seen a process written to take standard input during the boot up process, although this is possible if you wanted to write one. I know the init scripts can be written with dependencies, depending on which distro you use and what exactly is the boot up process(upstart, system V init, etc). But by default, they run in a sync fashion on a order that the init uses. I am not sure how blocking that sync process...waiting for input would effect the system. Most likely, it would do just that....stop and wait for input before continuing.

dman
  • 10,406
  • 18
  • 102
  • 201
0

The init process does indeed run an infinite loop but this doesn't use any significant resource as it is interrupt driven. It simply waits for processes to die or for other signals to be sent to it. During the wait intervals, zero CPU cycles are used by init.

jlliagre
  • 29,783
  • 6
  • 61
  • 72