服务:kvm虚拟机的睡眠管理是否应该去掉,完全交给宿主机管理,比较符合native
还是各有一套睡眠电源方案才是native
结论
去掉 guest 的「睡眠 + 休眠」,只保留「锁屏 +(可选)关屏」;睡眠 / 唤醒 / 断电这一层统一归宿主管理。
理由:guest 的 sleep 在本地没有物理含义 —— VM 没有独立的电、显示、盖子、电源开关,它的「屏幕」只是宿主上的一个控制台窗口。guest 睡眠的唯一实际效果是「把域挂起」,而这件事 libvirt 做得更好:virsh suspend / resume 是宿主动作,可控、可查、不依赖 guest 的 ACPI。所以「各有一套」只在把 VM 当成与宿主平级的独立机器时才成立 —— 而它的物理现实是宿主上的一个进程。
前提与判据
优化目标不同,结论会相反,先声明前提:
- 目标 A(本机取向):不出幽灵状态、行为可预期 ⇒ 去掉 guest 睡眠。
- 目标 B:与「真机 Win10」体验一致 ⇒ 各有一套。
判据:这台 VM 有没有独立的物理平面(电 / 显示 / 盖子 / 电源键)?没有 ⇒ 按 A 收。
本机实测(只读取证)
| 项 | 实测值 | 出处 |
|---|---|---|
| 域 XML | 有 <acpi/>,无 <pm> 段(⇒ 采用 libvirt 默认能力) | virsh dumpxml win10-old |
| guest 休眠 | 无 hiberfil.sys ⇒ 休眠已关(快速启动随之关) | docs/legacy-win-vm.md:39 |
| 宿主 AC 方案 | 变暗 900s / 关屏 1800s / 自动睡眠 216000s(60 小时,实际从不自动睡) / 电源键=1 / 合盖=64 | ~/.config/powerdevilrc |
| 宿主睡眠约束 | 严禁代发睡眠/挂起指令;排查睡眠只许读日志与配置 | docs/sources/from-nixos-doctor-profile/USER.md:107,113 |
| 宿主睡眠实测 | s2idle 下 gateway 跨 10h 存活;唤醒后网络空窗 ≈2 分 46 秒;WiFi 假死需睡前 rmmod / 醒后 modprobe | docs/leaked-knowledge-and-open-items.md L3;docs/from-nixos-doctor/hardware.md |
逐项裁决
| VM 内的电源动作 | 在 VM 里到底意味着什么 | 裁决 |
|---|---|---|
| 显示器熄灭 | 只黑掉 guest 的虚拟输出 ⇒ 控制台窗口变黑、看着像挂了(真正的屏是宿主的) | 可关,或调到很长 |
| 睡眠 S3 | QEMU 把域挂起 ⇒ 控制台定格、要唤醒事件才回来;对宿主没有任何省电收益(电费由宿主决定) | 去掉 |
| 休眠 S4 | guest 整机 RAM 落盘(慢、占地) | 已关,保持 |
| 快速启动 | 混合休眠 ⇒ 关机不彻底、状态残留(对 VM 是病) | 已关,保持 |
| 电源按钮 | ACPI ⇒ 等价 kvm stop | 保留(guest 可能忽略 ACPI,兜底 kvm poweroff) |
| 合盖 | VM 没有盖子 | 无意义,别在 guest 配 |
| 宿主睡眠时 VM 在跑 | 域被冻住 ⇒ 醒来有时钟跳变(本项目已踩过) | 宿主别自动睡(现状即是);真要睡先 virsh suspend / kvm stop |
三层落地
- 域层(推荐,纯声明式,最 native):三个方案 XML 各加
<pm><suspend-to-mem enabled='no'/><suspend-to-disk enabled='no'/></pm>⇒ 从能力层去掉睡眠与休眠,guest 里powercfg /a直接显示「不可用」,Windows 电源菜单里的「睡眠」自动消失 —— 不用进 guest 改任何东西。 - guest 层(体验补充):① 电源按钮 = 关机(否则能力去掉后按它什么都不发生;设好后
kvm stop发的 ACPI 才能真关机)② 关屏/变暗与宿主对齐或干脆不关(唯一影响是控制台窗口黑不黑)③ 硬盘停转 = 从不(避免 guest 内设备省电带来的卡顿)。其余(处理器电源、亮度、USB 选择性暂停)在 VM 里没有物理对应,保持默认。 - 宿主层:保持不自睡(当前
AutoSuspendIdleTimeoutSec=216000= 60 小时,实际从不自动睡);宿主真要睡,睡之前先virsh suspend win10-old或kvm stop。
复核命令
# 域层是否生效(应出现 suspend-to-mem / suspend-to-disk enabled='no')
virsh -c qemu:///system dumpxml win10-old | grep -A3 "<pm"
# guest 内(在 Windows 里跑):看睡眠/休眠是否为「不可用」
powercfg /a
# guest 内:电源按钮动作(3 = 关机)与睡眠/休眠超时
powercfg /q SCHEME_CURRENT SUB_BUTTONS
powercfg /q SCHEME_CURRENT SUB_SLEEP
边界
- 本机制不动宿主的睡眠策略(受「不许代发睡眠/挂起信号」约束:排查与取证只读取日志与配置)。
- guest 侧三条补充设置的现状值待实测(取证时 VM 处于关机态);能力层去掉后,睡眠/休眠相关的超时项自动失去作用。
- 「宿主睡眠时域被冻住、醒来时钟跳变」属宿主睡眠策略范畴,不在本篇。