![通过 systemd-logic 让 init.d 服务等待挂载](https://linux22.com/image/200869/%E9%80%9A%E8%BF%87%20systemd-logic%20%E8%AE%A9%20init.d%20%E6%9C%8D%E5%8A%A1%E7%AD%89%E5%BE%85%E6%8C%82%E8%BD%BD.png)
我有一个systemd
基于 - 的发行版 ( debian 10
) 和遗留的init.d
- 服务 ( backuppc
)。由于备份存储在外部驱动器上,我想确保备份服务在安装相应的备份分区之前不会运行,在安装不可用时暂停,并在备份后重新启动。
正如backuppc
现有的软件包一样,将init.d
-script 迁移到systemd
不是一个选项 - 而且我担心可靠性问题,这显然对于备份系统至关重要。
问题
有没有一种(优雅的)方法使遗留
init.d
服务依赖于逻辑中的挂载systemd
?是否可以通过一个其他服务/目标根据先决条件(退出安装)有条件地启动/停止另一项服务?
下面的方法可靠吗?
我目前的想法如下:
一个
check-mount.target
其中- 挂载存在时成功或失败
- 如果需要的话(重新)安装
- 在备份服务之前出现
- 启动备份服务
一个
stop-backup.service
其中- 检查活动状态
check-mount.target
- 如果挂载未激活,则停止备份服务
- 检查活动状态
重新启动计时器
check-mount.target
这就是它的样子:
#check-mount.target
[Unit]
Description="starts backuppc if mount is present, fails otherwise"
BindsTo=backup_data.mount
After=backup_data.mount
Before=backuppc.service
Wants=backuppc.service
[Install]
WantedBy=default.target
#stop-backup.service
[Unit]
Description="stops backup if mount is NOT present"
[Service]
#stop backup service if check-mount.target failed/is not active
ExecCondition=/usr/bin/bash -c '! /usr/bin/systemctl is-active --quiet backup_data.mount'
ExecStart=/usr/bin/systemctl stop backuppc
#restart will fail as long as mount is present:
Restart=on-failure
RestartSec=2
[Install]
WantedBy=default.target
#timer for check-mount.target
OnUnitInactiveSec=10
Unit=check-mount.target
[Install]
WantedBy=default.target
我不喜欢这个/其他发现:
- 它需要两个服务和一个计时器,其中一个服务不断重新启动=>我更喜欢相互触发的简单依赖关系
- 使用
Conflicts=backuppc
instop-backup.service
是不可能的,因为冲突是在执行 -test 之前执行的ExecCondition
。即备份服务始终停止。 - AFAIK
systemd
不提供NOT
逻辑,即BindsTo=*NOT*backup_data.mount
如果另一个服务失败则启动一个服务,反之亦然是不可能的(但会简化停止备份)
答案1
我相信编写一个仅调用 init.d 启动脚本函数的 systemd 服务文件应该非常简单:
* ExecStart= -> start function
* ExecStop= -> stop function
* ...
这反过来又使得依赖特定于 systemd 的指令(例如 After=、Wants= 或 Require=)变得微不足道。
这个问题甚至展示了如何将 init.d 块包含到空的 systemd 服务文件中,以使 systemd 神奇地做正确的事情:https://serverfault.com/questions/690155/whats-the-easiest-way-to-make-my-old-init-script-work-in-systemd