systemd 服务文件中的动态逻辑

systemd 服务文件中的动态逻辑

我正在尝试重写init.d包含以下代码的服务文件:

    if [ ! -r /var/spool/torque/server_priv/serverdb ]; then
            DAEMON_SERVER_OPTS="-t create $DAEMON_SERVER_OPTS"
    fi
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_SERVER_OPTS

我将其重写如下:

[Service]
Type=forking
ExecStart=/usr/sbin/pbs_server
PIDFile=/var/spool/torque/server_priv/server.lock

但我不知道如何表示ifsystemd 中的内容。

答案1

正如已经说过的,故意不支持复杂的逻辑systemd。如果需要执行任何启动逻辑(并且它不是守护进程本身的一部分),那么编写一个小 shell 脚本并在ExecStart=.

不过,有一点需要考虑。外壳脚本一定不自己进行任何流程管理。外壳脚本必须 exec守护进程。这是为了避免干扰 systemd 自己的进程监视和管理。

错误的 shell 脚本示例:

#!/bin/sh
if [ ! -r /var/spool/torque/server_priv/serverdb ]; then
        DAEMON_SERVER_OPTS="-t create $DAEMON_SERVER_OPTS"
fi

$DAEMON -- $DAEMON_SERVER_OPTS

这使得守护进程成为 shell 解释器的子进程。如果守护进程没有分叉并且就绪协议 ( Type=) 是simple,那么它只是一个闲置的冗余进程。否则,如果守护进程分叉并且您设置了Type=forking,那么整个事情将进行三次分叉,而不是双重分叉,并且 systemd 将杀死该守护进程。

正确的 shell 脚本示例:

#!/bin/sh
if [ ! -r /var/spool/torque/server_priv/serverdb ]; then
        DAEMON_SERVER_OPTS="-t create $DAEMON_SERVER_OPTS"
fi

exec $DAEMON -- $DAEMON_SERVER_OPTS

这将 shell 进程替换为守护进程。

答案2

你不会喜欢这个,但它确实有效:

ExecStart=/bin/bash -c '\
    if [ ! -r /var/spool/torque/server_priv/serverdb ]; then \
            DAEMON_SERVER_OPTS="-t create $DAEMON_SERVER_OPTS"; \
    fi; \
    exec /usr/sbin/pbs_server -- $DAEMON_SERVER_OPT'

答案3

systemd 中没有这样的功能 - 因为这种逻辑确实属于守护进程内部。但是,如果您无法更改有问题的守护进程,您可以通过首先创建简单的单元来解决它,该单元将检查文件是否存在并创建相应的环境变量,然后将“EnvironmentFile =”添加到您的单元中。还要添加依赖项以确保您的单元始终在创建环境变量的单元之后执行。

相关内容