Arch Linux配置休眠
写在前面:名词解释
休眠与睡眠
睡眠(挂起到内存,suspend to RAM),将当前运行的程序状态保存到内存,然后保留内存供电;
休眠(挂起到硬盘,suspend to disk),将当前运行的程序状态保存到硬盘,然后完全断电,这意味着可以拔掉台式机的插座,搬走之后插电再恢复。
在Linux中,休眠会使用swap,无论是swap分区还是swap文件都可以。
由于是对系统层面的修改,下文的所有操作如无特殊说明,均需要在root权限下执行。
重新生成initramfs
是下文将会使用的操作。当提到“重新生成initramfs”时,需要执行下面两种操作的一种:
- 对所有安装的内核重新生成initramfs:
1
mkinitcpio -P
- 对指定的一个内核单独重新生成initramfs,以
linux
为例可以只对当前正在使用的内核执行,因为内核在更新的时候也会自动重新生成initramfs,不使用的内核等到滚新版本的时候让它自动来就行了,节省时间。1
mkinitcpio -p linux
更新grub配置
如果配置过 update-grub 脚本,执行
1 |
|
否则执行
1 |
|
Windows+Arch双系统休眠需要注意的地方
本节内容默认关闭了Windows快速启动。
- EFI分区:如果双系统共用同一个EFI分区,当休眠其中一个系统并启动另一个系统时,根据 ArchWiki ,EFI分区可能遭到破坏。通常来说并不会出现问题(咱这么干过并且没事),但是这么做的时候务必确保手头有现成的WindowsPE盘以及Linux的liveCD(可以通过 ventoy 把两个功能整合在同一个U盘里),以在EFI分区万一真的被破坏的时候,可以从容地修复引导。
- 文件系统:当休眠其中一个系统并启动另一个系统时,如果挂载了在另一个系统中处于挂载状态的分区,那么可能发生数据损失;并且如果对这个分区进行了写入操作,文件系统几乎一定会损坏。由于Windows通常并不能读取Linux的分区,这种情况最可能出现在“休眠了Windows之后启动Linux,并挂载了Windows分区”的时候,这时尽快结束当前操作,重启回到Windows,并对这个分区执行
chkdsk
检查与修复。
如果不需要休眠
在以下两种方案中选择一种,以禁用休眠功能并在桌面环境中隐藏休眠按钮,避免误触引发意料之外的后果。参考 ArchWiki ,虽然是KDE的wiki页但是对其它桌面环境同样有效。
- 创建文件
/etc/polkit-1/rules.d/99-disable-hibernate.rules
,填入以下内容:1
2
3
4
5
6
7
8
9
10
11// Disable hibernate for all users
polkit.addRule(function(action, subject) {
if ((action.id == "org.freedesktop.login1.hibernate")) {
return polkit.Result.NO;
}
});
polkit.addRule(function(action, subject) {
if ((action.id == "org.freedesktop.login1.hibernate-multiple-sessions")) {
return polkit.Result.NO;
}
}); - 创建文件
/etc/systemd/sleep.conf.d/00-disable-hibernation.conf
,填入以下内容:只需要保证该文件位于
/etc/systemd/sleep.conf.d/
路径下即可,文件名并不重要。1
2
3
4[Sleep]
AllowHibernation=no
AllowSuspendThenHibernate=no
AllowHybridSleep=no
配置休眠
详细资料参见 ArchWiki 。
需要确保至少有一个足够大的swap分区或者swap文件。Linux不支持跨swap休眠,休眠数据必须存储在单一的swap分区或者swap文件上。具体的大小根据内存的大小判断。
测试平台:Oracle Virtualbox虚拟机,VMware虚拟机不支持休眠。测试涵盖了swap分区,ext4的swap文件和btrfs的swap文件三种形式,均可以休眠并成功恢复。
配置initramfs
Arch Linux使用mkinitcpio
来管理initramfs。mkinitcpio
支持两种initramfs,一种基于busybox(这是默认值),另一种基于systemd。
基于systemd的似乎更现代,支持并行启动,开机更快。但是有一些功能在基于systemd的initramfs上面似乎并没有平替。
例如systemd似乎无法使用救急shell,并且似乎无法在initramfs阶段执行fsck检查文件系统(都是根据wiki的推测,wiki这一块讲的感觉很含糊)
相关的说明可以参考ArchWiki-mkinitcpio ,属于进阶阅读内容。
需要编辑/etc/mkinitcpio.conf
,找到这一行:
1 |
|
- 继续使用基于busybox的initramfs,则需要加入
resume
钩子,并且确保resume
在udev
之后:1
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block filesystems resume fsck)
- 改为使用基于systemd的initramfs,则systemd自带休眠支持:
1
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block filesystems fsck)
或者,考虑去掉可能无用的base
和fsck
1
HOOKS=(systemd autodetect microcode modconf kms keyboard sd-vconsole block filesystems)
完成编辑后,重新生成initramfs。
指定休眠的位置
从systemd v255和mkinitcpio v38开始,当系统运行在UEFI上时,
systemd-sleep
将自动选择合适的交换空间进行休眠,并且所用交换空间的信息存储在HibernateLocation
EFI变量中。在下次启动时,systemd-hibernate-resume
从EFI变量读取位置,系统恢复。这意味着除非系统使用传统BIOS或您想选择与自动选择的不同的交换空间,否则以下步骤不是必需的。
休眠到swap分区
休眠到swap分区的操作相对比较简单,首先获取swap分区的UUID:
1 |
|
图中UUID是851b93b3-ab5a-401c-88ad-5487cd4ad270
接下来需要添加内核参数,对于使用grub引导的系统,编辑/etc/default/grub
文件,找到GRUB_CMDLINE_LINUX_DEFAULT
一行,在其中添加resume=UUID=
最后更新grub配置;完成后需要重启才能使更改生效。
休眠到swap文件
1.swap文件位于btrfs分区
首先获取swap文件所在分区的UUID:
1 |
|
swap文件是/swap/swapfile
,位于/dev/sda2
分区,UUID是5df5e112-f1ec-4639-9871-c3bdd2da41ac
然后需要获取swap文件相对于分区的偏移量。
1 |
|
图中偏移量是1451264
接下来需要添加内核参数,对于使用grub引导的系统,编辑/etc/default/grub
文件,找到GRUB_CMDLINE_LINUX_DEFAULT
一行,在其中添加resume=UUID= resume_offset=
最后更新grub配置;完成后需要重启才能使更改生效。
2.swap文件位于其它文件系统分区
其它文件系统(ext4,xfs等等)均适用此方法。
首先获取swap文件所在分区的UUID:
1 |
|
swap文件是/swapfile
,位于/dev/sda2
分区,UUID是ccbc7703-d83e-4846-b70b-61eec5b3f9ec
然后需要获取swap文件相对于分区的偏移量。
1 |
|
图中需要的数值为第一行physical_offset
列,偏移量是352256
或者可以这样直接获取偏移值:
1 |
|
图中偏移量是352256
接下来需要添加内核参数,对于使用grub引导的系统,编辑/etc/default/grub
文件,找到GRUB_CMDLINE_LINUX_DEFAULT
一行,在其中添加resume=UUID= resume_offset=
最后更新grub配置;完成后需要重启才能使更改生效。
测试休眠
任意启动几个软件,然后使用桌面环境自带的休眠,或者使用
1 |
|
电源完全关闭后,重新开机并进入Arch Linux,确认应用是否成功恢复。
成功断电并且成功恢复说明配置成功。