我正在调试防火墙服务单元,出现了一些问题。
这些问题之一是该单位的最佳服务类型,无论是 exec 还是 oneshot。在我的搜索中几乎没有出现这两者的比较,可能是因为 exec 是 systemd 中相对较新的添加项(v.249 IIRC)。
作为背景,该单元(称为 iptables.service)旨在通过在网络启动之前运行 Bash 脚本(称为 iptables.sh)来激活和配置防火墙(IE,在网络预目标之前),例如,
ExecStart=/bin/bash -c '/home/locsh/iptables.sh'
类型=一次性具有不进入“活动”状态的优点,因此随后可以重新启动或重新激活,例如,通过定时器单元。在大多数示例中,它也是两种类型中更常见的一种,尽管没有解释。
类型=执行优点是会延迟后续单元的启动,直到主服务执行完毕。这对于防火墙服务单元来说似乎非常有意义,因为网络应该依赖于脚本的成功运行,否则保持关闭状态,例如,如果由于某种原因相关的 .mount 单元尚未激活而暂时无法读取脚本。
重新启动=失败时在这两种情况下,这似乎都是一个明显且谨慎的补充。
第一个问题是无论出于何种原因其中一个或另一个可能会更好。
第二个问题是 Type=exec 是否延迟了后续单元的启动,在某些边缘情况下可能会引入微妙的排序周期,无论有或没有“Restart=on-failure”,部分原因是单元的排序依赖性
Before=network-pre.target
在启动过程中相对较早。
答案1
你要type=oneshot
。如果您使用type=exec
,其他服务将能够在配置防火墙之前启动。从systemd.service
手册页中,对于exec
:
...或者换句话说:在 fork() 返回后,simple 会立即继续执行进一步的作业,而在服务进程中的 fork() 和 execve() 都成功之前,exec 不会继续执行。
对于oneshot
:
oneshot 的行为与 simple 类似;但是,服务管理器将在主进程退出后考虑该单元。
换句话说,随着Type=exec
,systemd
服务已“启动”开始了,而对于Type=oneshot
,systemd
一旦进程成功,就认为服务已“启动”完全的。