我想编写一个服务单元文件,它将启动一个守护进程,并在它死后重新启动它。我有:
[Unit]
Description=lmgrd
[Service]
User=flexlm
Group=flexlm
ExecStartPre=/usr/bin/cp /nfs/lmgrd/* /lm/
ExecStart=/lm/lmgrd -c /lm/license.lic -l /lm/lmgrd.log
Restart=on-failure
RestartSec=3
RemainAfterExit=yes
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target这会复制文件并启动守护进程,但是如果我杀死守护进程(lmgrd),它就不会重新启动。我怎么才能解决这个问题?
发布于 2023-02-01 10:20:42
我怀疑它不会重新启动,因为systemd认为服务最初没有运行守护进程。如果您在守护进程还在的时候查看systemctl status,您可能会看到"Status: active (exited)“,并且没有列出主PID。
默认情况下,FlexLM lmgrd将在启动时分叉(守护进程);初始进程几乎立即退出,而子进程是需要跟踪的“主”守护进程。
问题是,systemd还没有被告知--如果服务中没有Type=设置,缺省值实际上是Type=simple,它告诉systemd跟踪初始进程。因此,一旦lmgrd去功能化,systemd就认为"main“进程已经退出,并且通常会在停止时报告服务。
在您的示例中,systemd仍然假装服务仍然是“活动的”,因为RemainAfterExit=yes已经设置,但实际上不再跟踪任何进程;仍在运行的lmgrd进程只被认为是一个剩余的子/工作进程,其退出不再影响服务状态。
要解决这个问题,请删除RemainAfterExit=选项并添加Type=forking选项。后者是处理将“去后台”或“分叉到后台”的服务的正确方法。(Systemd将自动确定主进程,而不需要"PID文件“)。
或者,您可以继续使用Type=simple (但仍然删除RemainAfterExit!)但是,相反,将进程配置为不去守护- FlexLM有-z选项“在前台运行”。
(通常推荐使用Type=simple,但并不总是更好的选择;Type=forking还具有在服务准备好时通知系统的优点,这通常比Type=simple的“简单性”优势要大。尽管只有当守护进程正确地执行其“守护”( lmgrd )时才重要--如果系统配置了任何依赖于此的服务--在本例中也可能没有,所以-z是可以使用的。
对于一般的经验规则,不要使用RemainAfterExit=yes,除非有问题的ExecStart被期望退出(大多数情况下,您也会对此类服务使用Type=oneshot )。例如,nftables.service可能使用此选项,因为即使在nft进程退出之后,防火墙规则集仍然保持加载状态。然而,对于长寿命的守护进程来说,RemainAfterExit=yes的唯一影响是负面的--它使系统忽略故障。
另外需要注意的是,systemd不会在ExecStart中展开通配符(这些命令是在不使用shell的情况下运行的,所以通常的shell运算符都不能工作)。该命令将尝试复制一个名为*的文件。
您应该将其更改为递归复制目录的内容:
ExecStartPre=/usr/bin/cp -rv /nfs/lmgrd/. /lm/或者为通配符展开运行一个shell:
ExecStartPre=/bin/sh -c "cp -v /nfs/lmgrd/* /lm/"https://unix.stackexchange.com/questions/733890
复制相似问题