事实上,systemd 单元是否存在指定“After=suspend.target”的竞争条件

事实上,systemd 单元是否存在指定“After=suspend.target”的竞争条件

关于在恢复时启动 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在同一源文件中),显然在恢复之前不会返回。

答案1

你说得对;帖子 #124是错的。

人们有时会写单位,这是一个问题WantedBy=sleep.target After=sleep.target。这将在睡觉前启动设备,然后不等他们完成就睡觉,这几乎肯定不是他们想要做的。很有可能,这就是发帖者的想法。

权威:基于类似的分析,我独立编写了一个这样的单元来在简历上运行 hdparm。它工作正常,就像响应中的那样帖子 #129说。我的设备每次都运行正常。我知道,因为如果我运行没有它,我可以听到硬盘驱动器发出的咔哒声。早些时候,我能够识别出udev 中的错误这导致我之前的解决方案不可靠,仅仅是因为我注意到听到了喀哒声。

相关内容