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.