How does systemd handle the death of a child of a managed process?

It doesn't.

The main process handles the death of its children, in the normal way.

This is the POSIX world. If process A has forked B, and process B has forked C, D, and E; then process B is what sees the SIGCHLD and wait() status from the termination of C, D, and E. Process A is unaware of what happens to C, D, and E, and this is irrespective of systemd.

For A to be aware of C, D, and E terminating, two things have to happen.

  • A has to register itself as a "subreaper". systemd does this, as do various other service managers including upstart and the nosh service-manager.
  • B has to exit(). Services that foolishly, erroneously, and vainly try to "dæmonize" themselves do this.

(One can get clever with kevent() on the BSDs. But this is a Linux question.)


systemd has the concept of a main process. In the systemd documentation this is referred to as the "main service process" or simply the "main process".

Example 4 in the systemd.service documentation describes have the main process is calculated when Type=forking.

The documentation for Restart= in the systemd.service docs describe the different possibilities for when a service is started in relation to the main process.

Here's the key text from "example 4" linked above:

systemd will consider the service to be in the process of initialization while the original program is still running. Once it exits successfully and at least a process remains (and RemainAfterExit=no), the service is considered started.

Often, a traditional daemon only consists of one process. Therefore, if only one process is left after the original process terminates, systemd will consider that process the main process of the service. In that case, the $MAINPID variable will be available in ExecReload=, ExecStop=, etc.

In case more than one process remains, systemd will be unable to determine the main process, so it will not assume there is one. In that case, $MAINPID will not expand to anything. However, if the process decides to write a traditional PID file, systemd will be able to read the main PID from there. Please set PIDFile= accordingly.