systemdは管理されたプロセスの子プロセスの終了をどのように処理しますか?

systemdは管理されたプロセスの子プロセスの終了をどのように処理しますか?

systemd管理プロセスの子プロセス出口を処理する方法は?

systemdデーモンが起動したfoo後、デーモンが3つの異なるデーモン(bar1bar2および)を起動するとしますbar3。予期しないシャットダウンが発生した場合はsystemdどうなりますか?私が理解したのは、プロパティを変更して通知しないと、Solarisのサービス管理機能(SMF)がシャットダウンまたは再開されます。行動に違いはありますか?foobar2foostartdignore_errorsystemd

編集#1:

systemd動作をテストするためにテストデーモンを作成しました。このデーモンはmother_daemon子プロセスを作成するために呼び出されます。

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

これはsystemd次のデバイスによって制御されます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

デバイスmother_daemon.serviceは次のように制御されますmother_daemon.target

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

実行するとsudo systemctl start mother_daemon.target(後でsudo systemctl daemon-reload)親デーモンと5つの子デーモンを見ることができます。

子のいずれかを殺しても親には影響はありませんが、親を殺すと(したがって再開が始まる)、子が再開されます。

mother_daemon.target止まると子供たちも終わりますsudo systemctl stop mother_daemon.target

これが私の質問に対する答えだと思います。

答え1

しかし、実際にはそうではありません。

基本プロセスは、通常の方法で子プロセスの終了を処理します。

これがPOSIXの世界です。プロセスAがBを分岐し、プロセスBがC、D、およびEを分岐すると、プロセスBは終了後にC、D、およびEの状態を確認します。プロセスAはC、D、Eに何が起こったのかわからず、systemdとは何の関係もありませんSIGCHLDwait()

AがC、D、Eが終了したことを知るには、2つのことが必要です。

kevent()(人々はBSDについて賢明になるかもしれませんが、これはLinuxの問題です。)

答え2

systemdメインプロセスという概念があります。システム文書では、これを「メインサービスプロセス」または単に「メインプロセス」と呼びます。

例4ではsystemd.service ドキュメント計算の主なプロセスが紹介されますType=forking

Restart=systemd.service ドキュメントのドキュメント基本プロセスに関連するサービスを開始する際のさまざまな可能性について説明します。

上記の「例4」の主なテキストは次のとおりです。

systemd は、元のプログラムが実行され続けている間にサービスが初期化されていると考えています。サービスが正常に終了し、1つ以上のプロセスが残っている場合、サービスは開始されたと見なされます(RemainAfterExit = no)。

通常、既存のデーモンは1つのプロセスのみで構成されます。したがって、元のプロセスが終了してから1つのプロセスしか残っていない場合、systemdはそのプロセスをサービスの主要なプロセスと見なします。この場合、$ MAINPID変数はExecReload =、ExecStop =などで使用できます。

複数のプロセスがある場合、systemdは基本プロセスを決定できないため、1つのプロセスが存在するとは想定されません。この場合、$ MAINPIDは何も拡張されません。ただし、プロセスが既存のPIDファイルに書き込むことを決定した場合、systemdはそこからデフォルトのPIDを読み取ることができます。これに応じてPIDFile =を設定してください。

関連情報