在关于在恢复时启动 anacron 的 Debian 错误报告,有人声称,由于 systemd 依赖项的工作方式,该代码片段(为简洁起见而简化)可能会在挂起时而不是恢复时触发。我无法理解使用 systemd 文档和 systemd 附带的单元文件指示的竞争条件。
[Unit]
Description=Do something at resume
After=suspend.target
[Service]
ExecStart=/bin/do-something
[Install]
WantedBy=suspend.target
这篇文章的作者继续引用systemd-suspend.service
,其中包含以下声明(再次精简为相关声明)
[Unit]
After=sleep.target
Requires=sleep.target
其次是两个不同的单元(均在后面排序)sleep.target
并行运行,因此这两个单元之间没有排序。我完全同意这一点,但是不存在两个单位都依赖于sleep.target
,据我了解。中的声明systemd-suspend.service
确保sleep.target
在睡眠之前完全启动,因此所有依赖的单元都sleep.target
启动。但是查看suspend.target
(原始单元文件真正依赖的目标),我发现以下声明:
[Unit]
BindsTo=systemd-suspend.service
After=systemd-suspend.service
suspend.target
我将这个文件理解为只有在成功启动后才声明systemd-suspend.service
已成功启动。现在,再次查看systemd-suspend.service
,我在该文件中找到以下声明:
[Service]
Type=oneshot
Exec=/lib/systemd/systemd-sleep suspend
据我了解一次性服务,在Exec
命令完成之前它们不会进入“启动”状态。因此,订购此服务的任何内容在完成After
之前都无法开始。systemd-sleep
最后,看一下 systemd-sleep,它包含一些字符串的魔术写入/sys/power/state
,该字符串会阻塞,直到系统恢复。这应该确保systemd-suspend.service
在恢复之前确实没有启动之后想要启动的所有内容。
我声称写入块的原因/sys/power/state
是该写入是由该文件的 sysfs 存储函数,这称为pm_suspend
对于非休眠模式,它依次调用enter_state
(直接pm_suspend
在同一源文件中),显然在恢复之前不会返回。