我正在尝试使用 udev 规则和 systemd 实现自动备份机制。这个想法是在热插拔特定存储设备时启动备份例程,非常类似于这个问题,顺便说一下,我自己提供了一个答案,但在这里我有兴趣讨论一些进一步的调整。即我希望在备份服务完成后卸载设备。
一些背景:
到目前为止,我已经使用 udev 启动了一个 systemd 服务,该服务本身运行一个备份例程。相关文件如下:
备份服务
[Unit]
Description=<DESCRIPTION HERE>
BindsTo=<STORAGE DEVICE UNIT HERE>.device mnt-backup.mount
After=<STORAGE DEVICE UNIT HERE>.device mnt-backup.mount
[Service]
ExecStart=<CALL TO BACKUP SCRIPT HERE>
mnt-备份.mount
[Unit]
DefaultDependencies=no
Conflicts=umount.target
Before=umount.target
[Mount]
What=/dev/disk/by-uuid/<DEVICE UUID HERE>
Where=/mnt/backup
Type=<FILESYSTEM HERE>
90-备份.规则
KERNEL=="sd*", ATTRS{serial}=="<HD SERIAL HERE>", TAG+="systemd", ENV{SYSTEMD_WANTS}+="backup.service"
问题:
现在我希望在 backup.service 完成后立即停止 mnt-backup.mount 。
根据文档执行开始后=将在 ExecStart= 中的命令之后执行,所以我尝试添加
ExecStartPost=/usr/bin/systemctl stop mnt-backup.mount
到 backup.service,即使我意识到它会停止 mnt-backup.mount,它本身受其约束,据我了解,实际上需要在 mnt-backup.mount 之前停止 backup.service 才能正常停止,从而创建循环依赖。
在测试这个时,它工作了几次,然后我经历了内核恐慌,这是我在我的机器上看到的第一次,所以这让我想知道这是否是某种原因。
任何状况之下,我的方法正确吗?
答案1
虽然我不确定以前的方法是否一定有效,但还有一种看起来更好的替代方法。
这个神奇的属性叫做不需要时停止。这应该在挂载文件中的 [Unit] 下设置为 true,因此它变为:
mnt-备份.mount
[Unit]
DefaultDependencies=no
Conflicts=umount.target
Before=umount.target
StopWhenUnneeded=true
[Mount]
What=/dev/disk/by-uuid/<DEVICE UUID HERE>
Where=/mnt/backup
Type=<FILESYSTEM HERE>
就如此容易。
这种方法的巨大优点是它受到 systemd 的明确支持,因此保证可以工作。
我也强烈建议设置拒绝手动启动在服务单元中设置为true,禁止用户手动启动服务。这个想法正是为了自动化备份机制,因此用户不应该能够显式启动它,所以最好将此责任完全留给 udev。