大家好,我是冯哥的缓存。今天聊一个很多 Linux 用户绕不开的话题:合盖睡眠、休眠唤醒不了、开机比重启慢。
suspend 和 hibernate 到底有什么区别?
很多人不知道 Linux 其实有四种"睡眠"状态,Windows 的"睡眠"和"休眠"只是其中两种。
💡 提示: 大多数人说的"合盖睡眠"是 S3(Suspend to RAM)——内存通电保持数据,其他硬件断电,功耗极低。说的"休眠"是 S4(Suspend to Disk)——内存内容写进硬盘 swap 分区,完全断电,下次开机从硬盘恢复。
Linux 休眠的底层架构
Linux 的休眠功能由多个层级协同完成,理解这个架构能帮你快速定位问题在哪一层。
⚠️ 注意: 休眠失败通常发生在"驱动层"——某个硬件的驱动不支持 suspend/resume,导致整个链条卡住。显卡驱动(尤其是 NVIDIA 闭源驱动)是最常见的罪魁祸首。
第一步:确认你的系统支持哪些睡眠状态
在终端运行这条命令,看看你的硬件实际支持什么:
cat /sys/power/state
常见输出示例:
| |
|---|
freeze mem disk | |
freeze mem | 不支持 S4 休眠(swap 未配置或 BIOS 不支持) |
freeze | |
再确认 S3 挂起模式(有些新硬件默认用 s2idle 而不是 deep):
cat /sys/power/mem_sleep
| |
|---|
[s2idle] deep | |
s2idle [deep] | |
| |
💡 提示: 方括号 [ ] 内的模式是当前使用的模式。如果发现当前是 [s2idle],可以尝试切换到 deep 模式,很多"挂起耗电快"的问题就是因为用的是 s2idle 而不是真正的 S3。
第二步:确认休眠(S4)所需的 swap 配置
S4 休眠必须把内存内容写进 swap,所以:
# 查看 swap 配置
free -h
# 或
swapon --show
| |
|---|
| swap 容量 ≥ 内存大小(8GB内存需要≥8GB swap) |
| |
| |
⚠️ 注意: 很多人安装 Linux 时选了"自动分区",swap 分区只有 2GB 甚至没有,这时候 S4 休眠无法工作,下篇会聊到如何用 swapfile 补救。
第三步:查看 systemd 的睡眠配置
systemd 控制着合盖、按电源键等事件的响应行为:
# 查看 logind 的电源管理配置
cat /etc/systemd/logind.conf | grep -v "^#" | grep -v "^$"
关键配置项含义:
| | |
|---|
HandleLidSwitch | suspend | |
HandleLidSwitchExternalPower | suspend | |
HandlePowerKey | poweroff | |
HandleSuspendKey | suspend | |
HandleHibernateKey | hibernate | |
💡 提示: 如果你想合盖不挂起(比如接了外接显示器),把 HandleLidSwitch=ignore 写进 /etc/systemd/logind.conf,然后 sudo systemctl restart systemd-logind 即可。
第四步:手动测试挂起和休眠
测试休眠前,先确认 swap 足够,否则系统可能会直接关机。先手动触发,比等系统自动挂起更容易定位问题:
# 测试 S3 挂起(几秒后按任意键唤醒)
sudo systemctl suspend
# 测试 S4 休眠(需要 swap 配置正确)
sudo systemctl hibernate
# 测试混合睡眠
sudo systemctl hybrid-sleep
⚠️ 注意: 测试休眠时确保已保存所有工作!S4 休眠会把内存写进硬盘,过程中系统完全断电,如果恢复失败会相当于直接关机。
第五步:读取日志定位失败原因
挂起/唤醒失败后,最重要的是看日志:
# 查看最近一次挂起相关的日志
journalctl -b 0 | grep -i "suspend\|hibernate\|sleep\|wake\|pm:"
# 只看系统上次唤醒后的日志
journalctl -b -1 | tail -100
# 查看内核电源管理日志(更底层)
sudo dmesg | grep -i "PM\|suspend\|resume\|wake"
常见错误关键词速查:
| |
|---|
PM: Some devices failed to suspend | |
nvidia: failed to suspend | |
ACPI: Waking up from system sleep state S3 | |
PM: Basic memory bitmaps free | |
Failed to hibernate: Not enough storage | |
i915: resume failed | |
rtcwake: | |
第六步:确认哪个设备阻止了挂起
# 查看哪些设备"阻止"了挂起
cat /proc/driver/rtc
systemctl list-units --state=active | grep sleep
# 更直接:查看 wakeup 相关设备
cat /proc/acpi/wakeup
还有一个很有用的命令,可以看到有哪些程序持有"唤醒锁":
# 查看所有电源管理抑制器(谁不让睡)
systemd-inhibit --list
常见的"阻止睡眠"程序:
| |
|---|
| |
| 虚拟机运行中(VirtualBox/VMware) | |
| |
| |
各桌面环境的休眠管理界面
不同桌面环境的电源管理设置入口不同:
| | |
|---|
| | gsettings |
| | powerdevil |
| | xfce4-power-manager |
| | lxsession |
| | systemctl suspend |
💡 提示: GNOME 默认设置里没有休眠(hibernate)按钮,它被故意隐藏了,因为 GNOME 团队认为休眠功能不够稳定。如果你想在电源菜单里加上休眠按钮,需要安装扩展或修改配置。如果 GNOME 版本不同,也可以用 gnome-control-center power 直接从终端打开。
快速诊断流程
| | |
|---|
| cat /sys/power/state | |
| cat /sys/power/mem_sleep | |
| free -h | |
| sudo systemctl suspend | |
| journalctl -b 0 | grep -i suspend | |
| systemd-inhibit --list | |
常见报错速查
| | |
|---|
| | cat /etc/systemd/logind.conf |
| | journalctl -b -1 | grep -i resume |
| | sudo dmesg | grep -i "nvidia|i915|drm" |
| | swapon --show |
| | cat /proc/acpi/wakeup |
| | |
| | |
小结
| |
|---|
| |
| |
| |
| journalctl -b 0 | grep suspend |
| systemd-inhibit --list |
| |
💡 下篇预告: 实战修复:swap 不足怎么补、怎么切换 S3 deep 模式、NVIDIA 休眠黑屏怎么处理、GNOME 怎么加休眠按钮、Wi-Fi 唤醒后断线怎么解决。