我不明白当主机挂起时 systemd 计时器应该如何表现:
这是一个简单的服务:foo.service
[Unit]
Description=Test timer
[Service]
Type=simple
ExecStart=echo "TEST TIMER"
以及对应的定时器:foo.timer
[Unit]
Description=Run foo every day
[Timer]
OnCalendar=Mon..Sun 17:47:00
如果我启动计时器,在计时器到期前几秒挂起主机systemctl suspend
,并在几分钟后唤醒系统,则会触发计时器,并且在 journald 中打印 TEST TIMER。
systemd 调试日志大致如下:
Nov 03 17:53:27 footest kernel: PM: suspend exit
Nov 03 17:53:27 footest kernel: random: crng reseeded on system resumption
Nov 03 17:53:27 footest kernel: Restarting tasks ... done.
Nov 03 17:53:27 footest systemd[1]: foo.timer: Timer elapsed.
Nov 03 17:53:27 footest kernel: OOM killer enabled.
Nov 03 17:53:27 footest kernel: ata1.00: configured for UDMA/133
Nov 03 17:53:27 footest kernel: ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
Nov 03 17:53:27 footest kernel: sd 0:0:0:0: [sda] Starting disk
进而
Nov 03 17:53:27 footest echo[434]: TEST TIMER
但是该计时器不是持久性的,据我所知不应该被触发。OnClockChange 也设置为 false。停止并重新启动主机不会触发计时器,可能是因为整个计时器在关闭之前就停止了。
这是在新安装的 Arch VM 上。
如果这是预期的行为,我认为禁用计时器的唯一方法就是使用 sleep.target 依赖项?
如果重要的话,我的用例如下:我想每天在给定时间暂停主机。但是,如果我在计时器结束前的某个时间手动暂停主机,则计时器会在主机唤醒后立即触发,这并不理想……
编辑:按照https://github.com/systemd/systemd/issues/26166#issuecomment-1581501093
这是 systemd 计时器的预期行为:
Generally, system suspend/hibernate across the system is mostly treated as a large scheduling latency, and all programs will "catch up" on what they were missing when coming back from suspend. And so does systemd.
答案1
这似乎是一个systemd 中的错误,这当然不应该发生。关于它的信息不多,但从错误描述来看,持久性似乎仅适用于实际停机时间,即机器关闭时(而不是休眠/挂起)。我猜在修复之前,您应该使用一个 shell 脚本,该脚本仅在当前时间与您想要的时间匹配时才挂起您的 PC。否则它应该退出而不做任何事情。真的很丑陋,不理想,并且违背了计时器的目的,但这就是它。
以下是执行该操作的脚本:
#!/bin/sh
TIME=1747
DELTA=5
MAXTIME=$((TIME + DELTA))
NOW=$(date +%H%M)
if [ $NOW -ge $TIME -a $NOW -le $MAXTIME ]
then
/bin/systemctl suspend
fi
TIME
是您的计时器预计经过的军事时间(在您的情况下为 17:47),DELTA
是该时间之后仍允许触发的分钟数,我认为 5 分钟是一个不错的范围。