因为自己的电脑装的是win10 + ubuntu20.04的双系统,所以切换到另一个系统时,需要保存一下目前系统的RAM状态到硬盘上,然后再切换,这样再切换回来的话就能直接恢复之前的状态,比较方便。
之前自己双系统的ubuntu一直都是开着休眠功能的,但是前几天不知道具体原因,系统崩了,修复很久之后好了,但是由于自己再修复过程中remove掉很多软件包(本意是想着能减少系统负担,唉),最后连terminal都找不到了,就离谱。
所以最后不得已重装系统,但是休眠功能尝试了很久才打开。之前开启休眠功能完全没这么复杂,不知道为啥。
本文就把踩的各种坑记录下来(也不能说是坑,主要是自己想研究透彻点,就尝试了很多都没成功),便于自己以后查阅。

系统信息:ubuntu 20.04
RAM:24G
安装时预设的swap空间大小:30G

成功开启使用的方法

尝试了不少次之后,成功的方法是:
直接创建一个2倍RAM大小的/swapfile文件作为交换空间
安装时预设的交换空间位于:/dev/nvme1n1p3,可以通过查看/etc/fstab看到:

cat /etc/fstab | grep swap
# 输出如下:
# swap was on /dev/nvme1n1p3 during installation
 UUID=e20d7f03-985c-45ed-86b8-d4335cc10d6f swap            swap    sw              0       0
 
我们先选择不使用这个swap area:
sudo swapoff /dev/nvme1n1p3 # 一般,在swapoff之后,直接tab键就自动补全了
此时可以查看一下交换空间的信息,用 free -m 或者 swapon --show

然后,创建swap文件: # 因为我的RAM是24G,所以就直接创建一个48G的swap文件了
sudo dd if=/dev/zero of=/swapfile bs=1M count=48k 

之后:
sudo mkswap /swapfile
sudo chmod 600 /swapfile
sudo swapon /swapfile # 启用新的swap area

然后,在/etc/fstab中,将原swap注释掉,添加一行:
/swapfile       swap    swap    defaults      0       0

之后直接使用:
sudo hibernate # 可以通过apt 安装这个命令
# 反正我这一步成功用的是这个命令,不过按道理,sudo systemctl hibernate应该也行,
# 因为hibernate只是一个脚本,调用的还是系统的hibernate命令

之后就成功了,也没有修改/etc/default/grub等文件(跟我原来使用休眠的经历类似,总之就是不复杂)

各种尝试全记录

尝试一

参考:ubuntu启用休眠,先使用命令:

sudo pm-hibernate
# 或者是命令:
sudo systemctl hibernate

测试是否支持休眠。

发现还没有装pm-hibernate,使用命令sudo apt install pm-utils来安装。

之后再次sudo pm-hibernate倒是能正常关闭系统,但是启动之后还是相当于重启了,休眠失败。

考虑可能是交换空间的问题(因为之前设置休眠的时候就对交换空间进行了一些设置)
查看交换空间信息:

sudo swapon --show # 查看一下交换空间信息
# 信息如下:
NAME           TYPE       SIZE USED PRIO
/dev/nvme1n1p3 partition 28.6G   0B   -2

之后查看/etc/fstab文件,有如下关于交换空间的信息:

# <file system> <mount point>   <type>  <options>       <dump>  <pass>
......
# swap was on /dev/nvme1n1p3 during installation
UUID=e20d7f03-985c-45ed-86b8-d4335cc10d6f none           swap    sw              0       0

可以看到,其中的swap的对应的是none,根据swapon --show的输出,将none改为 /dev/nvme1n1p3,然后尝试休眠:

sudo systemctl hibernate
# 或者是:
pm-hibernate

结果:失败。。

尝试二

看debian有关fstab文件的介绍:https://wiki.debian.org/fstab
其中提到有关最后一个label的含义:

<pass> fsck reads the <pass> number and determines in which order the file systems should be checked. Possible entries are 0, 1, and 2. The root file system should have the highest priority, 1, all other file systems you want to have checked should get a 2. 
File systems with a <pass> value 0 will not be checked by the fsck utility.

最后一句说到,如果<pass>的值为0,则不会检查,还以为会有用,就将swap分区的<pass> 改为了1:

# swap was on /dev/nvme1n1p3 during installation
 17 UUID=e20d7f03-985c-45ed-86b8-d4335cc10d6f none            swap    sw              0       1

然后试图休眠
结果:失败。。

尝试三

参考:https://blog.csdn.net/miaoyuyouran/article/details/107776184
还是修改修改/etc/default/grub中的GRUB_CMDLINE_LINUX_DEFAULT,形式为: resume=UUID=xxxx

然后,更新grub:sudo update-grub

结果:不仅失败,打开之后直接黑屏了。最后通过recovery模式,用root的方式恢复/etc/default/grub文件,最终才好

尝试四,扩增swap分区

sudo dd if=/dev/zero of=/swapfile bs=1M count=20K
# 输出如下:
20480+0 records in
20480+0 records out
21474836480 bytes (21 GB, 20 GiB) copied, 53.6445 s, 400 MB/s
# 然后初始化新增的swap:
sudo mkswap /swapfile
# 输出如下:
mkswap: /swapfile: insecure permissions 0644, 0600 suggested.
Setting up swapspace version 1, size = 20 GiB (21474832384 bytes)
no label, UUID=9d24497c-e831-4500-89c5-82534ac06aef
# 根据提示,修改swapfile的权限:
sudo chmod 600 /swapfile

sudo swapon /swapfile
# 此时,查看交换空间大小
free -m 或者是 swapon --show
# 如下结果:
NAME           TYPE       SIZE USED PRIO
/dev/nvme1n1p3 partition 28.6G 1.5M   -2
/swapfile      file        20G   0B   -3

最后把/swapfile 放到 /etc/fatab 里面

然后试图休眠

尝试四,就是上述成功的那种方法

进一步尝试,用更小的swap area,看看是否可行

先用一个较小的30G的
# 先关闭之前的swap area:
sudo swapoff /swapfile
# 删除
sudo rm /swapfile
# 用 free -m 或者 swapon --show 查看,发现成功删除
# 再重新创建:
sudo dd if=/dev/zero of=/swapfile bs=1M count=30k
sudo mkswap /swapfile
sudo chmod 600 /swapfile
# 别忘了设置为交换空间!
sudo swapon /swapfile
# ok了,之后尝试休眠:
sudo systemctl hibernate
结果:失败,打开后相当于重启。

再次尝试,直接用hibernate命令:
sudo hibernate
直接失败,屏幕黑了一下又恢复原样了。

相对于之前的2倍RAM的交换空间,这次只是减小了交换空间的大小,其他都不变

生成swap时,会输出uuid信息,如果当时生成时没注意的话,可以参考另一篇文章,来查看创建的swap文件的uuid信息

:后面查看/etc/default/grub文件时,才发现里面的 resume=UUID=xxxx在重新生成/swapfile之后忘记改了。。
所以:

更改/etc/default/grub文件中相应的部分
然后更新grub:
sudo update-grub

重启之后再次尝试sudo hibernate:失败

再用一个大点儿的40G的

重复以上过程,结果:
这次屏幕黑了一会儿,而不只是一下,不过最后又恢复原样了。
猜测:黑了一会儿可能是正在将RAM转储到ROM上,但是最后一点失败了,就恢复原样了。
后续又用上面成功的2倍RAM大小的交换空间,但是还是没有休眠成功。。
就很玄学,明明这一步用的swap文件大小都跟成功的那次一样,其他配置应该也都一样,最后就是休眠不成功了。
离谱

继续尝试,别的方法

参考:https://linux.die.net/man/1/pm-is-supported
发现pm-is-supported --hibernate没有输出,说明不支持休眠;但是,cat /sys/power/state输出为:freeze mem disk,说明支持休眠。(懵)

之后参考:https://www.linuxuprising.com/2021/08/how-to-enable-hibernation-on-ubuntu.html

`/etc/default/grub`中添加resume_offset项
之后 update-grub;
然后:
sudo vim /etc/initramfs-tools/conf.d/resume
注意:这里resume要小写,大写会出错:
W: initramfs-tools configuration sets RESUME=UUID=63b2777c-1ad9-4735-ba2f-fe5110d7c6b8
W: but no matching swap device is available.
然后:
sudo update-initramfs -c -k all
输出:
update-initramfs: Generating /boot/initrd.img-5.13.0-30-generic
update-initramfs: Generating /boot/initrd.img-5.13.0-40-generic
最后reboot

结果:还是失败

又看到一种方法

参考:https://askubuntu.com/q/1053134
将 pm-utils和uswsusp remove掉,然后和上面一样,更新:

sudo update-initramfs -c -k all 或者是 sudo update-initramfs -u
sudo update-grub

然后reboot。重启之后发现sudo hibernatesudo systemctl hibernate命令都能使用,不过最终还是没有休眠成功,只是相当于关机了。

后来又将uswsusp安装回来:

sudo apt install uswsusp # uswsusp提供的有swap-offset命令,可以直接查看交换空间的offset

此时发现 hibernate 命令不能用了,说明二者有冲突。再次sudo apt remove uswsusp之后, hibernate命令又能用了,但是只是关机,还是没有休眠。

更新,安装nvidia-smi之后的影响

安装nvidia的cuda toolkit之后,再次sudo hibernate就会报错:

hibernate some modules failed to unload: nvidia_drm nvidia_modeset nvidia

然后就仍停留在终端界面,不会休眠。😂

后记

所以,虽然成功开启了休眠,但是最后自己又瞎捣鼓,捣鼓了很久也没有再次休眠成功。。唉不搞了

更新,再次成功开启休眠功能

2022.4.28

在另一个新安装的ubuntu20.04(使用的是相同的镜像文件安装的)系统上再次成功开启了休眠功能,相关信息如下:

magic@ubuntu20:~$ swapon
NAME            TYPE       SIZE USED PRIO
/dev/nvme0n1p10 partition 19.1G   0B   -2

magic@ubuntu20:~$ free -g
              total        used        free      shared  buff/cache   available
Mem:             15           1          12           0           1          13
Swap:            19           0          19

简单记录如下:

安装好之后直接测试:sudo systemctl hibernate,无效,相当于关机;

之后安装hibernate:sudo apt install hibernate,然后使用:sudo hibernate,也无效,相当于关机;

之后修改/etc/fstab文件,找到swap相关的部分,文件原本相关内容如下:

# swap was on /dev/nvme1n1p3 during installation
 UUID=a7317e2e-a618-4f16-af0a-37820a22d204 none	           swap    sw              0       0

然后修改为以下内容:
 UUID=a7317e2e-a618-4f16-af0a-37820a22d204 swap            swap    defaults              0       0

退出保存之后再次:sudo hibernate,直接就成功了(这部分截图也展示不出来效果,就不截图了)
不过使用使用命令sudo systemctl hibernate还是不能达到休眠的效果。

注,后续又进行一些尝试

后面为了探索到底是哪方面的原因,将/etc/fstab文件改回了原内容:

将:
# swap was on /dev/nvme1n1p3 during installation
 UUID=a7317e2e-a618-4f16-af0a-37820a22d204 swap            swap    defaults              0       0

还修改为以下内容:
 UUID=a7317e2e-a618-4f16-af0a-37820a22d204 none	           swap    sw              0       0

之后再次sudo hibernate,仍然可以休眠成功
只不过休眠以及重新启动阶段会出现以下界面(并没有什么影响):
在这里插入图片描述
在这里插入图片描述
然后安装了pm-utils工具,然后使用:sudo pm-hibernate,跟上面一样,也可以休眠成功

但是sudo systemctl hibernate命令还是休眠失败。经过看ubuntu的官方手册文档,应该是需要修改/etc/systemd/sleep.conf跟/etc/systemd/logind.conf等文件,但是经过尝试也还是没有成功。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐