在Linux上启用休眠

介绍

休眠是一种将内存数据存储在硬盘中,在下次电脑启动的时候回写数据进入内存,保证电脑可以恢复到关机前的状态的技术。 大多数情况下,Linux发行版的休眠默认关闭。 传统的休眠方式是休眠到交换分区,现指出,休眠到硬盘的性能已经和休眠到交换分区一致,为避免交换分区过小或者没有交换分区带来的问题,本文介绍休眠到硬盘的方法。

此教程只适用于ext4文件系统。 此教程大部分内容来自Arch wiki。 Wiki相关内容: 休眠 内核参数 initramfs

步骤

为了使用休眠功能,您必须创建一个 swap 分区或文件、#配置 initramfs 以便在早期用户空间启动恢复过程,并指定交换空间的位置以便 initramfs 可以访问,例如:由 systemd 定义的 HibernateLocation EFI 变量或 resume= 内核参数。 —— Arch wiki

如Arch wiki所说,我们需要完成三个步骤,创建交换文件、配置内核参数、配置initramfs。

第一步:创建交换文件

确定交换文件大小

1
cat /sys/power/image_size

输出13069914112,该值除以1024^2即为交换文件大小,单位为GB,本例中为12G,

创建交换文件

按照上一步输出的空间大小来创建交换文件,本例中创建了一个13G的交换文件,保险起见,略大于规定值。

1
sudo fallocate -l 13G /swapfile

设定权限

1
sudo chmod 600 /swapfile

标记为交换文件

1
sudo mkswap /swapfile

启用交换文件

1
sudo swapon /swapfile

让改变持久化,重启系统后维持更改

将以下行添加到 /etc/fstab 文件的末尾:

1
/swapfile none swap sw 0 0

检查是否成功开启

1
swapon --show

输出类似于

1
2
NAME      TYPE SIZE USED PRIO
/swapfile file 13G 0B -2

第二步:配置 initramfs

initramfs 是现代 Linux 系统启动流程的重要组成部分,它为系统提供一个灵活的启动环境,确保系统能够从复杂的存储设备启动,同时提供了一个基本的恢复机制。

编辑initramfs配置文件

1
sudo vim /etc/mkinitcpio.conf 

找到HOOKS,添加resume参数,添加完后,类似于

1
HOOKS=(base udev autodetect keyboard microcode modconf kms keyboard keymap consolefont block filesystems resume fsck)

注意: 如果使用堆叠存储作为交换空间,例如 dm-crypt、RAID 或 LVM,则最终映射的设备必须在早期用户空间中可用,并且在恢复过程启动之前。也就是说,在这样的设置中,resume 钩子必须放在诸如 encrypt、lvm2 等钩子之后。

重新生成initramfs

可以参考手动生成

1
mkinitcpio -P

第三步:配置内核参数,指定休眠位置

找到交换文件所在分区的UUID

1
df /swapfile

输出类似于

1
2
文件系统          1K的块      已用     可用 已用% 挂载点
/dev/nvme1n1p2 256918980 171665036 72130412 71% /

/dev/nvme1n1p2即为交换文件所在分区。

接下来找到该分区的UUID

1
lsblk -o NAME,UUID

这个命令会输出所有分区的UUID,将找到的交换文件所在分区的UUID记下。 输出类似于

1
2
3
4
5
6
7
8
9
10
11
12
13
NAME        UUID
nvme0n1
├─nvme0n1p1 AE48-3356
├─nvme0n1p2
├─nvme0n1p3 D65648A856488AE7
├─nvme0n1p4 A828C18128C14ECE
└─nvme0n1p5 C276493676492C8B
nvme1n1
├─nvme1n1p1 985A9A115A99EC6E
├─nvme1n1p2 b7a8b0d3-8a88-4053-84e5-48488d8371f7
├─nvme1n1p3
├─nvme1n1p5 e0cb5c0e-ca4a-4e2e-b237-1612a87441b8
└─nvme1n1p6 7e49be86-d941-4545-adef-7fae39f5a05e

这里可以看到,/dev/nvme1n1p2的UUID为b7a8b0d3-8a88-4053-84e5-48488d8371f7,将这个UUID记下。

找到交换文件的偏移量

1
sudo filefrag -v /swapfile | awk '$1=="0:" {print substr($4, 1, length($4)-2)}'

输出结果即位偏移量,即offset,记下输出的数字。

编辑内核参数

编辑grub配置文件

1
sudo vim /etc/default/grub

找到GRUB_CMDLINE_LINUX_DEFAULT,添加resume参数和resume_offset参数

1
GRUB_CMDLINE_LINUX_DEFAULT="quiet resume=UUID=找到的UUID resume_offset=找到的offset"

例如

1
GRUB_CMDLINE_LINUX_DEFAULT="quiet resume=UUID=b7a8b0d3-8a88-4053-84e5-48488d8371f7 resume_offset=34816"

更新grub

1
sudo grub-mkconfig -o /boot/grub/grub.cfg

重启

1
sudo reboot

测试

1
sudo systemctl hibernate

🎉恭喜,Linux已经成功启用了休眠功能。