*有時*分叉的腳本的 systemd 服務文件

*有時*分叉的腳本的 systemd 服務文件

我有一個 systemd 服務來執行由 systemd 計時器啟動的監視 bash 腳本。我用過Type=oneshot看起來最適合的。然而,有時腳本需要呼叫另一個程序,這恰好會fork。一旦完成,腳本就會完成並退出,但是一旦腳本退出,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 的 shell,然後exec執行實際命令:

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

/the/forking/program將會取代已經在新 cgroup 中的 shell。當它分叉時,分叉的實例將發現自己位於新的 cgroup 中。當主腳本退出時,systemd 將殺死與該服務關聯的 cgroup 中的進程,但有問題的程式不會在其中。

也許有更合適的方法來解決您的問題,使用單元文件或其他東西。但我不知道。

相關內容