我们有一个带有 systemd 服务的内部应用程序,我们希望将其部署在正常的 systemd 目录(/etc/systemd/system 和 /usr/lib/systemd/system)之外。该位置位于另一个磁盘上(示例中为 /mnt/data)。
systemd 服务通过以下方式启用:
systemctl enable /mnt/data/sprinterd.service
它在 /etc/systemd/system 中创建一个符号链接
lrwxrwxrwx. 1 root root 27 Jun 20 22:47 sprinterd.service -> /mnt/data/sprinterd.service
重启后,由于找不到单元文件,服务未加载。从journalctl中,首先是服务加载失败的错误,然后是该单元所在磁盘的挂载。
Cannot add dependency job for unit sprinterd.service, ignoring: Unit sprinterd.service failed to load: No such file or directory.
systemd[1]: Mounted /mnt/data.
从/etc/fstab:
/dev/disk/by-uuid/c55e944f-5c63-48ad-8cd2-bd32d7b35c82 /mnt/data auto nosuid,nodev,nofail,x-gvfs-show 0 0
为了完整性,服务单元文件:
[Unit]
Description=sprinterd
[Service]
Type=simple
Environment=TERM=linux
ExecStart=/srv/s1.erp/bin/sprinterd
Restart=always
RestartSec=5
KillSignal=SIGKILL
[Install]
WantedBy=multi-user.target
我已经在 RHEL 7 和 openSuSE 13.2 上对此进行了测试。
是否支持将系统服务单元文件放在 /etc 或 /usr 之外的另一个磁盘上?如何更改挂载磁盘和加载 systemd 单元文件之间的执行顺序?
答案1
正如 @StephenHarris 所解释的,问题是目前 systemd 尝试读取该单元,符号链接的文件尚不可用
让 systemd 在安装后重新加载单元:
[Unit]
Description=reloads units stored in /mnt/data
DefaultDependencies=no
After=mnt-data.mount
Requires=mnt-data.mount
[Service]
Type=oneshot
ExecStart=/bin/systemctl daemon-reload
[Install]
WantedBy=local-fs.target
这将导致单位变得可用,因为这次这次符号链接的目标已安装。
但到那时,需要运行的作业列表才能达到默认目标已经建成,服务惯于开始吧。
要让它也重新启动您的服务:
[Unit]
Description=restart unit stored in /mnt/data
Requires=mnt-data.mount
[Service]
Type=oneshot
ExecStart=/bin/systemctl daemon-reload
ExecStartPost=/bin/systemctl start sprinterd.service
[Install]
WantedBy=multi-user.target
备择方案:
- 我已经用
ExecStart=
&进行了测试ExecStartPost=
,但它显然应该与ExecStartPre=
&一起使用ExecStart=
- 如果都是关于 1 个单位,您也可以:
ExecStart=/bin/systemctl enable /mnt/data/sprinterd.service
而不是守护进程重新加载 - 如果有多个服务,请执行以下操作守护进程重新加载
ConsistsOf=
,然后启动一个使用或PartOf=
加载所有多个服务的单元。 - 如果它的 NFS(或其他网络系统),显然
local-fs.target
不是您的最佳安装选项。
对于更老派的系统初始化-风格的方法,将 systemctl 命令放入该文件/etc/rc.local
中chmod +x
。
然后在 Devuan 的邮件列表上沾沾自喜地发布你如何需要 SysVInit 来修复 b0rked SystemD ;-)
答案2
这是一个已知的限制。希望我能为您提供解决方法。