我写了一个 LSB 初始化脚本,它可以管理我的守护进程的多个实例:
rcfoo start
启动所有实例(在某个/etc
配置文件中找到),rcfoo stop
停止所有实例,rcfoo status
显示所有实例的状态,并rcfoo reload
重新加载使用更改的配置更新守护进程.
首先,我想知道如何检测要使用某些[email protected]
systemd 单元文件的实例。AFAIK 我必须指定所有实例,例如foo@A
,foo@B
等等。
其次,我的 LSB 脚本可以报告扩展状态,这意味着它可以显示是否reload
需要服务(我reload
实际上优化为只重新加载需要它的服务)。如何制作自定义状态报告?我认为脚本必须systemd-notify
用于自定义状态消息。
幸运的是,我对 LSB 脚本的最终扩展,即通过添加single <instance>
(如 in rcfoo start single A
)来操作单个实例,是 systemd 开箱即用的支持。
所以我的基本问题是第一个问题。
我找到了两种可能的解决方案:
编写一个接受实例参数和命令参数的“包装脚本”。然后脚本必须搜索请求的实例是否真的在
/etc
. 该脚本实际上确实提供了start
,stop
和reload
, 而守护进程的 PID 由 systemd 通过PIDFile=
.另外编写一个
[email protected]
包含 , 等的包装脚本ExecStart=
的服务单元ExecStop=
。实例名称由%i
那里表示。不太好的事实是您必须知道实例名称,并且当使用无效的名称时,systemd 会创建一个不可操作的实例,该实例会反复重启(直到使用 手动清理systemctl reset-failed
)。这种方法没有解决有条件重启的问题。所以你会systemctl start foo@A
。或者,您可以通过编写生成器读取配置文件并为找到的每个实例创建一个服务实例单元文件来摆脱包装脚本。正在使用的命令行由生成器使用配置文件组装。额外的 shell 命令(例如,创建运行时目录,或等待守护进程 fork 完成)由生成器通过
ExecStartPre=
和添加ExecStartPost=
。有一些问题没有解决,但开发列表中代表的 systemd 社区实际上并没有帮助:他们告诉我生成器是一个高级概念,我不应该使用它,实际上并没有回答我的问题。
此答案中缺少的内容是:如何配置启动和停止所有服务的 sytemd 目标?我以为我会有一个,但它在启动时失败(生成的单元文件是空的,原因不明)。