*時々*分岐したスクリプトのためのシステムサービスファイル

*時々*分岐したスクリプトのためのシステムサービスファイル

システムタイマーによって開始された監視bashスクリプトを実行するシステムサービスがあります。Type=oneshot最もよく似合うようなものを使用しました。しかし、時にはスクリプトがフォークされる他のプログラムを呼び出す必要があるかもしれません。完了すると、スクリプトは完了して終了しますが、スクリプトが終了すると、systemdは残りのすべての子プロセスを終了します。

これを防ぐために使用できますが、KillMode=processスクリプトの他のパスでは、シャットダウン後に他のプロセス(フォークされていない)が実行され続ける危険があります。

この問題を処理する最良の方法は何ですか?

しかし、フォークされたプログラムはdhcpcdですが、質問は一般的に適用されると思います。 dhcpcd は最初に ifplugd によって開始されます。これは、システムがdhcpcdが実行されなくなった状態で終了する場合に備えた安全スクリプトです。

答え1

プロセスは、次のようにサービスに関連付けられている制御グループ(cgroup)に属するため終了します(システムサービスの場合)。

/sys/fs/cgroup/systemd/system.slice/your-service.service

プロセスをcgroupから移動するには、他のcgroupに割り当てる。 「親cgroup」が正しいようです。システムサービスの場合:

echo <PID> > /sys/fs/cgroup/systemd/system.slice/tasks
# or even to the general systemd cgroup
echo <PID> > /sys/fs/cgroup/systemd/tasks

最初からこのcgroupでいくつかのコマンドを実行するには、cgroupに自分自身を割り当てるシェルを実行してから、実際execのコマンドを実行します。

sh -c 'echo "$$" > /sys/fs/cgroup/systemd/tasks; exec /the/forking/program'

/the/forking/program新しいcgroupにすでに存在するシェルは置き換えられます。フォークされると、フォークされたインスタンスは新しいcgroupにそれ自体が見つかります。デフォルトスクリプトが終了すると、systemdはサービスに関連付けられているcgroupのプロセスを終了しますが、問題のプログラムはそのサービスに含まれません。

たぶん、ユニットファイルなどを使用して問題を解決するためのより適切な方法があるかもしれません。しかし、わかりません。

関連情報