*時々*フォークするスクリプトのsystemdサービスファイル

*時々*フォークするスクリプトのsystemdサービスファイル

私は、systemd タイマーによって開始される監視 bash スクリプトを実行する systemd サービスを持っています。私は、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実際のコマンドに s を割り当てるシェルを実行します。

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

/the/forking/programすでに新しい cgroup 内にあるシェルを置き換えます。分岐すると、分岐したインスタンスは新しい cgroup 内にあります。メイン スクリプトが終了すると、systemd はサービスに関連付けられた cgroup 内のプロセスを強制終了しますが、問題のプログラムはその中には含まれません。

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

関連情報