Shell-Script

systemd Firewall .service 單位:Type=exec 還是 Type=oneshot?

  • June 11, 2022

我正在調試防火牆 .service 單元,出現了一些問題。

其中一個問題是該單位的最佳服務類型,無論是 exec 還是 oneshot。在我的搜尋中幾乎沒有出現兩者的比較,可能是因為 exec 是 systemd (v.249 IIRC) 的一個相對較新的添加。

作為背景,該單元(稱為 iptables.service)旨在通過在網路啟動之前(network-pre.target 之前)執行 Bash 腳本(稱為 iptables.sh)來啟動和配置防火牆,例如

ExecStart=/bin/bash -c '/home/locsh/iptables.sh'

Type=oneshot具有不進入“活動”狀態的優點,因此它隨後可以被重新啟動或重新啟動,例如,通過計時器單元。在大多數範例中,它也是這兩種類型中更常見的一種,儘管沒有解釋。

type=exec的好處是會延遲後續單元的啟動,直到主服務執行完畢。這似乎對防火牆 .service 單元非常有意義,因為網路應該依賴於成功執行的腳本並保持關閉,例如,如果由於某種原因相關的 .mount 單元尚未啟動而暫時無法讀取腳本.

在任何一種情況下, Restart=on-failure似乎都是一個明顯而謹慎的補充。

第一個問題是,無論出於何種原因,其中一個是否會更好。

第二個問題是 Type=exec 是否會因為它延遲後續單元的啟動而在某些邊緣情況下引入微妙的排序週期,無論是否有“Restart=on-failure”,部分原因是單元的排序依賴性

Before=network-pre.target

在引導過程中相對較早。

你想要type=oneshot。如果您使用type=exec,則在配置防火牆之前,其他服務將能夠啟動。從systemd.service手冊頁中,對於exec

…或者換句話說:在 fork() 返回後,簡單的工作將繼續進行,而在服務程序中的 fork() 和 execve() 都成功之前,exec 將不會繼續進行。

對於oneshot

oneshot 的行為類似於 simple;但是,服務管理器會在主程序退出後考慮啟動單元。

換句話說,with Type=exec,systemd認為服務在程序成功啟動後“啟動” ,而 for Type=oneshot,systemd認為服務在程序成功完成後“啟動” 。

引用自:https://unix.stackexchange.com/questions/705839