2014-02-13
Init's (historical) roles
Historically (by which I mean since at least V6 Unix), init aka PID 1 has had three and then four roles:
- It inherits orphan processes, ie processes that have had their regular
parent exit. Doing this almost certainly simplified a bunch of V7
kernel code because it meant that every process has a parent process.
- Starting up the user level of Unix on boot. Originally this was done
by running a monolithic shell script, as can still be sort of
seen in OpenBSD. System V init modularized and generalized it
into the multi-file form.
- Starting, managing, and restarting the
getty
processes for the console and (other) serial lines. System V init generalized this so that init started and restarted whatever you told it to via entries in/etc/inittab
. - Shutting down the user level of the system and rebooting. This
role first appeared in System V init, using the modularity that
it had introduced for booting. Modern BSDs also give
init
responsibility for rebooting (and it will run a shell script as part of this), but as late as 4.4 BSDreboot(8)
did almost all of the work itself and there was no concept of running a shell script to bring services down in any orderly way;reboot(8)
just killed everything in sight.
(Really. You can read the 4.4 BSD reboot(8)
source
if you want, it's not long. The violence starts at the 'kill(-1,
SIGTERM)
'.)
Putting the three (and then four) roles on the shoulders of a single
process is likely due to both conservation of resources in early
Unixes (given that they ran in very limited environments they likely
didn't want to take up memory with extra programs) and simple least
complexity and effort. Once you had init
as the inheritor of
orphan processes you might as well make it do all the other roles
since it was already there. Why throw in additional programs without
a good need? It probably helped that even in V7 the other two roles
were pretty simple and minimal, per eg the V7 /etc/rc
.
As a historical note, it was BSD Unix that decided that init
was
so crucial that the system should be rebooted if it ever exited.
V7 Unix will probably get into an odd state if init
ever exits
but as far as I can tell from the kernel source PID 1 is not treated
specially as far as exiting goes; as a practical matter V7 Unix
just assumes it will never happen. Even what happens if /etc/init
can't be executed on boot is not strictly a kernel thing in V7.
(In the initial environment of BSD, this decision was probably doubly
correct. Even if you never have to deal with any orphaned processes or
the kernel cleaned them up itself (let's wave our hands aggressively
here), losing init means that getty
processes will not be restarted on
serial lines when people log out, which over time makes it impossible
for anyone to log in. Of course in the modern era of networked machines
this is no longer such an issue and you probably care a lot more about
sshd
than about getty
s.)
Some modern init systems have split some or most of these roles out
from PID 1. Solaris, for example, moved everything except the first
role to separate processes (the SMF stuff runs in svc.startd
et
al and getty
processes are handled through ttymon
and sac
).