Como o systemd manipula a morte de um filho de um processo gerenciado?

5

Como o systemd manipula a morte dos filhos de processos gerenciados?

Suponha que systemd lance o daemon foo , que então lança outros três daemons: bar1 , bar2 e bar3 . systemd fará qualquer coisa para foo se bar2 terminar inesperadamente? Pelo que entendi, em Service Management Facility (SMF) no Solaris foo seria eliminado ou reiniciado se você não dissesse startd alterando a propriedade ignore_error . O systemd se comporta de maneira diferente?

Editar # 1:

Eu escrevi um daemon de teste para testar o comportamento de systemd . O daemon é chamado de mother_daemon porque gera filhos.

#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;
  }

Isso é controlado com uma unidade systemd chamada 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

A unidade mother_daemon.service é controlada pelo mother_daemon.target :

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

Quando eu executo sudo systemctl start mother_daemon.target (depois de sudo systemctl daemon-reload ) eu posso ver o daemon pai e os cinco daemons filhos.

Matar um dos filhos não tem efeito sobre o pai, mas matar o pai (e, assim, desencadear um reinício) reinicia os filhos.

Parar mother_daemon.target com sudo systemctl stop mother_daemon.target também termina os filhos.

Acho que isso responde à minha pergunta.

    
por Dennis Dragonbain 26.09.2016 / 20:28

2 respostas

3

Não faz.

O processo principal lida com a morte de seus filhos, da maneira normal.

Este é o mundo POSIX. Se o processo A tiver bifurcado B e o processo B tiver bifurcado C, D e E; então o processo B é o que vê o status SIGCHLD e wait() da terminação de C, D e E. O Processo A não sabe o que acontece com C, D e E, e isso é independente do systemd.

Para A estar ciente do término de C, D e E, duas coisas precisam acontecer.

(Pode-se ficar esperto com kevent() nos BSDs. Mas esta é uma questão do Linux.)

    
por 28.09.2016 / 19:40
3

systemd tem o conceito de um processo principal. Na documentação do systemd, isso é chamado de "processo de serviço principal" ou simplesmente "processo principal".

O exemplo 4 na documentação do systemd.service descreve se o processo principal é calculado quando Type=forking .

A documentação de Restart= nos documentos systemd.service descrever as diferentes possibilidades de quando um serviço é iniciado em relação ao processo principal.

Este é o texto-chave do "exemplo 4" vinculado acima:

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.

    
por 26.09.2016 / 21:10