我想知道是否有一种方法Systemd
可以在启动或重新加载(仅重新加载配置)时重新启动A.service
(),如果可能的话,无需编辑系统安装和升级的内容。After
B.service
B.service
A.service
即使B.service
未安装、禁用或停止,也应启动。
A.service
:
[Unit]
After = B.service network-online.target
Wants = B.service
[Service]
Type=oneshot
ExecStart = /script.sh start
ExecStop = /script.sh stop
RemainAfterExit=yes
[Install]
WantedBy = network-online.target
B.service
:
[Unit]
After=syslog.target network.target
[Service]
Type=forking
ExecStart=/cmd start
ExecStop=/cmd stop
ExecReload=/cmd reload
PIDFile=/var/run/cmd.pid
[Install]
WantedBy=multi-user.target
答案1
您可以PartOf
在该[Unit]
部分中使用。
例子:PartOf=B.service
从手册页来看,
部分=
配置类似于 Requires= 的依赖关系,但仅限于停止和重新启动单元。当 systemd 停止或重新启动此处列出的单元时,操作将传播到该单元。请注意,这是一种单向依赖关系 - 对此单位的更改不会影响列出的单位。
答案2
我无法控制stop
with PartOf=
,也A
不能停止 with B
,所以我最终使用了覆盖供应商设置,似乎有效。
/etc/systemd/system/B.service.d/override.conf
[Service]
ExecStart=
ExecStart=/bin/sh -c '/cmd start || exit $?; sleep 5; [ -x /script.sh ] && /script.sh start; exit 0'
ExecReload=
ExecReload=/bin/sh -c '/cmd reload || exit $?; sleep 5; [ -x /script.sh ] && /script.sh start; exit 0'
/cmd
实现是异步的,并且访问也需要访问的资源/script.sh
,我发现没有什么比(目前)更好的方法来睡眠几秒钟了。
systemctl [--no-block] try-restart
我在直接使用之前尝试过使用/script.sh
但没有成功。
答案3
目前 systemd 不涵盖这种情况。仅通过服务文件无法实现此功能。一种可能性是通过具有相同名称的 shell 脚本劫持 systemctl,并在其中检查 B.service 是否即将重新/启动或重新加载,并对 A.service 执行适当的操作,并在需要时更新rc.local 在启动时也达到正确的状态。我对 docker.service 和networking.service 有这个问题,但我总是一起重新启动它们:
systemctl restart docker.servicenetworking.service
显然,如果 systemd 本身在内部操作 B.service(例如通过其他服务文件),这将不会有效。