Systemd – How Does Systemd Handle the Death of a Child Process?

daemonlinuxprocess-managementsystemd

How does systemd handle the death of the children of managed processes?

Suppose that systemd launches the daemon foo, which then launches three other daemons: bar1, bar2, and bar3. Will systemd do anything to foo if bar2 terminates unexpectedly? From my understanding, under Service Management Facility (SMF) on Solaris foo would be killed or restarted if you didn't tell startd otherwise by changing the property ignore_error. Does systemd behave differently?

Edit #1:

I've written a test daemon to test systemd's behavior. The daemon is called mother_daemon because it spawns children.

#include <iostream>
#include <unistd.h>
#include <string>
#include <cstring>

using namespace std;

int main(int argc, char* argv[])
{
  cout << "Hi! I'm going to fork and make 5 child processes!" << endl;

  for (int i = 0; i < 5; i++)
    {
    pid_t pid = fork();

    if (pid > 0)
      {
    cout << "I'm the parent process, and i = " << i << endl;
      }
    if (pid == 0)
      {
      // The following four lines rename the process to make it easier to keep track of with ps
    int argv0size = strlen(argv[0]);
    string childThreadName = "mother_daemon child thread PID: ";
    childThreadName.append( to_string(::getpid()) );
    strncpy(argv[0],childThreadName.c_str(),argv0size + 25);

    cout << "I'm a child process, and i = " << i << endl;
    pause();
    // I don't want each child process spawning its own process
    break;
      }
    }
  pause();
  return 0;
  }

This is controlled with a systemd unit called mother_daemon.service:

[Unit]
Description=Testing how systemd handles the death of the children of a managed process
StopWhenUnneeded=true

[Service]
ExecStart=/home/my_user/test_program/mother_daemon
Restart=always

The mother_daemon.service unit is controlled by the mother_daemon.target:

[Unit]
Description=A target that wants mother_daemon.service
Wants=mother_daemon.service

When I run sudo systemctl start mother_daemon.target (after sudo systemctl daemon-reload) I can see the parent daemon and the five children daemons.

Killing one of the children has no effect on the parent, but killing the parent (and thus triggering a restart) does restart the children.

Stopping mother_daemon.target with sudo systemctl stop mother_daemon.target ends the children as well.

I think that this answers my question.

Best Answer

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.

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