rob at landley.net
Mon Nov 10 11:17:26 PST 2008
On Monday 10 November 2008 06:11:16 Vladimir Dronnikov wrote:
> > reboot -f
> > echo "Kernel has been instructed to reboot"
> > while true; do sleep 9999; done
> > because otherwise, if script exits, runsvdir
> > will loop back and restart services, and this is definitely
> > what you dont want to happen!
> Wonder what happens when init dies and kernel oopses? Does kernel
> sync/umount filesystems?
Nope, it's a normal oops.
The kernel's theory on oopses is that the system is no longer in a good state,
so it should stop writing to the disk _now_ because it may be writing
(However, this doesn't apply to network access, so it continues to route
packets. A common trick years ago was to set up your routing tables and then
have PID 1 exit so the kernel paniced, because the paniced kernel would
continue to route packets with _no_userspace_running_. Darn hard to hack a
system like that.)
> If so I'd let it be.
> Wonder also does kernel sync/umount filesystems when one issues
Nope, that's up to userspace to do.
> I still view some awkwardness in the procedure. You treat init as perpetuum
> mobile of which we have to break a detail to get it stopped. I mostly tend
> to treat it as a process that just exits when your system have accomplished
> its task. Where am I wrong, Denys?
You're wrong in that the kernel guys have defined init as a special process
that panics the kernel if it exits. This has been true for Linux for 18
years, and was true of other Unixes before that.
PID 1 is special, in lots of little ways. It's the default reaper of zombie
processes whose parents have exited. It's the default target of signals for
processes that don't otherwise have a parent (such as anything that's called
daemonize()). Various system things that must belong to a userspace process
get attached to init because it's guaranteed to be there. (Back before we
had so many kernel threads, interrupt routines that needed a process context
would borrow PID 1's. These days, those new kernel threads have init as
Internally, the kernel has a variable "init_task" statically referencing PID
1's context, which is used by things like daemonize() (the kernel internal
version in kernel/exit.c; I'm actually indirectly responsible for Andrew
Morton creating that sucker long ago:
http://lkml.indiana.edu/hypermail/linux/kernel/0105.0/0045.html). There are
also a couple of different "task_reparent_to_init()" functions in the
On a design level, the purpose of the kernel is to run userspace. The kernel
launches one task by hand, and then that task is in charge of the system from
then on. If that task ever exits, the kernel doesn't know what it's supposed
to be doing anymore, at a design level. It was decreed back in the 1970's
that PID 1 _should_not_exit_, and unix has gone along with that ever since
As for standards on this, see SUSv3 section 4.12, reserving PID 1 for the
See the definition of _exit(), which says:
The parent process ID of all of the calling process' existing child
processes and zombie processes shall be set to the process ID of an
implementation-defined system process. That is, these processes shall be
inherited by a special system process.
(How you're supposed to do that if the special system process is the one
exiting is left as an exercise for the reader.)
The definition of kill() says:
The unspecified processes to which a signal cannot be sent may include the
scheduler or init.
Keep in mind that this standard tried to be so vague that it could allow
Windows NT and IBM's System 360 to be specified as Posix compliant...
More information about the busybox