我有一个(简单的)自定义服务,它在从 ACPI S3(“挂起”)恢复时运行,该脚本只是通过 WOL(LAN 唤醒)唤醒服务器。
这是由 systemd 驱动的,脚本位于 /etc/systemd/system/on_resume.service 中,并由以下命令添加:
chmod +x on_resume.service
systemctl enable on_resume.service
systemctl status on_resume.service
问题是该脚本仅在系统通过使用 XFCE 中的“挂起”小部件(菜单中的一个简单按钮)进入睡眠状态时运行。
如果我执行 echo "mem" > /sys/power/state,系统也会进入睡眠状态,但当系统重新启动时该服务不会运行。
在这两种情况下,我只需按下电源按钮即可将其恢复。
问题是,这两种将系统放入S3的方法有什么区别(如果有的话)?为什么 systemd 在使用 XFCE 功能时只运行脚本?
为了简单起见,假设该脚本具有以下简单内容(该特定脚本用于测试,并且具有完全相同的问题,因此它是重现该问题的最小版本):
#!/bin/sh
case "$1" in
thaw|resume)
echo "test" > /tmp/testfile_resume
;;
esac
exit 0
当系统进入睡眠状态时,我确实通过 XFCE 的“电源管理器”锁定了屏幕,但是,我尝试将其关闭,并且使用 XFCE 的“挂起”按钮仍然可以工作。
然后,我尝试在使用小部件和手动使用 sys 文件系统时尝试比较 syslog,但似乎没有任何表明失败或任何值得注意的事情。
有什么不同?
请注意,我并不真正关心功能,我完全可以使用按钮而不是键入命令,但我想了解原因。
答案1
TL;DR:你想使用systemctl suspend
.
/sys/power/state
是XFCE最终调用的内核API。
内核 API 本身不运行挂钩脚本。软件希望能够在挂起之前(以及恢复之后)挂接以运行命令。因此,最简单的方法是让程序运行挂起钩子,调用内核,然后运行恢复钩子。
这就是 Linux,随着时间的推移,已经编写了几个这样的程序。systemd
是目前最突出的一个。
技术细节
XFCE,或 systemctl 挂起 -> systemd-logind -> systemd -> systemd-sleep -> linux 内核。
可以通过不同的方式连接到此,在开始的三个不同链接中的每一个中systemd
:)。您的脚本/etc
由后两者之一中安装的某些程序运行。请参阅man systemd-sleep
、 和man systemd.special
。不幸的是,目前使用这些钩子的确切方法还没有很好的记录。 (systemd 级别尤其需要一点关爱)。
至于第一个可能的钩子:登录“抑制剂”系统旨在供 GUI 应用程序使用。它涉及接收 DBus 信号。