SDB:挂起到磁盘
目录
背景
有两种方法可以挂起到磁盘:
- “旧”的内核空间的方法,基本上就是输出“磁盘”两个字到 /sys/power/state 文件里去。
- “新”的用户空间的方法,是由 suspend 包里的 s2disk 和 resume 命令控制的。
这篇文章主要讲用户空间的方法。
技术信息
s2disk 程序想把机器挂起,于是它做了以下事情:
- 告诉内核把当前的系统状态创建一个快照
- 从内核那里读取快照的数据,然后写入到磁盘
- 关闭机器电源
恢复程序做的事情基本相同,只不过顺序是反的:
- 在基本系统启动完成后,在挂载任何分区之前,从 initrd 里运行 resume 程序
- 它从磁盘把快照数据读出来,然后写到内核里
- 它告诉内核要恢复快照
- 内核回到了它挂起前的状态
以上的流程介绍是简化了的,因为“创建快照”可能要涉及许多复杂的操作,而“从磁盘读写”也涉及了不少如压缩和加密之类的转换。
使用 s2disk
在 openSUSE 发行版中,除非是为了侦错并且你知道你在干啥,否则最好不要直接调用 s2disk。 作为一个普通的用户,你只需要在 kpowersave 或 gnome-power-manager 中点击“挂起到磁盘”或者“休眠”就行了,或者你可以在命令行工具中使用 powersave 命令。 挂起过程的底层操作是由 SDB:Pm-utilis 来完成的,如果你需要侦错的话,你可以在终端中以 root 来调用 pm-hiberate 以调用 s2disk。这样会先检查一些前提条件,然后在 /var/lib/s2disk.conf 创建一个配置文件,再用这个配置文件来调用 s2disk。 如果 pm-hiberate 啥也没做,可以看一下 /var/log/pm-suspend.log 这个日志看看在挂起的准备工作中出什么问题了(比如没找到 swap 分区?)或是来自 s2disk 的错误信息。
配置
Pm-utils 的 pm-hiberate 用自动检测到的东西(比如恢复设备和镜像大小)来创建 /var/lib/s2disk.conf 然后从 /etc/suspend.conf 读取并添加配置好的参数,所以你是可以覆盖这些自动检测的。当心:更改 suspend.conf 里的东西可能会使你挂起失败,所以要小心点。 suspend.conf 文件是有注释的,所以阅读一下注释可能会告诉你该怎么做。
开机动画
挂起和恢复过程中的开机动画看起来挺漂亮的。但是有了动画之后你就看不到屏幕上的信息了,所以比较难侦错。在 /etc/suspend.conf 中添加
splash = n
可以禁用挂起过程中的动画。在恢复过程中,是否使用动画是和全局系统设置一致的,所以在 grub 中设置 “splash-verbose” 或者在启动的时候按 Esc 键都是可以禁用恢复过程中的动画的。
压缩
由于大部分 CPU 压缩镜像都是很快的,所以启用压缩可以缩短加载时间。压缩功能默认是开启的。如果你想关闭压缩来测试一下,可以通过在 /etc/suspend.con 中添加
compress =n
来实现。
加密
加密功能能把写入到 swap 分区的数据加密,这样只有输入了密码才能恢复系统。要设置加密的话,你先要创建一个公钥:
root@stoetzler:~# suspend-keygen libgcrypt version: 1.4.0 Key bits (between 1024 and 4096 inclusive) [1024]: Generating 1024-bit RSA keys. Please wait. Testing the private key. Please wait. Passphrase please (must be non-empty): Confirm passphrase: File name [suspend.key]: root@stoetzler:~# cp suspend.key /etc/suspend.key
别把密码忘啦!然后把下面的内容加入到 /etc/suspend.conf 里去:
encrypt = y
注意: 现在(2008-06),initrd 里是不加载任何键盘布局的,所以在恢复的时候,你只能用美式键盘,你得确定你知道如何在美式键盘上输入你的密码……
关机方法
在镜像被写入到磁盘后,有两种方法关闭机器:
- 给 BIOS 发送 ACPI 信号。(platform)
- 直接关机(shutdown)
通常应该用给 BIOS 发送 ACPI 信号的方法来关机(有一些机器上,这是必须的,否则在机器恢复之后,诸如温度控制之类的东西会不太正常)。有一些机器,使用 ACPI 会有问题(比如一关机就马上醒来),则可以使用第二种模式:
shutdown method = shutdown
其实一共有三种方法,除了 platform 和 shutdown,还有一个 reboot,但是这个只是用来侦错用的,这个选项会使系统休眠之后立刻重新并恢复。
在休眠之后启动另一个操作系统(迂回之路)
默认情况下,在恢复的时候,你不会在 GRUB 菜单中看到任何选项,而是直接恢复到之前挂起的系统。这是为了保护你的数据不受人为损害(你的系统内存都保存在 swap 分区里,如果这个分区在恢复之前被重新使用了的话,你可能会丢失所有的数据)。另一个非常重要的原因是:休眠过程完全不管那些已经挂载的分区的!所有已经挂载的分区还将保持挂载状态!所以,如果你在另一个操作系统中重新使用并修改了分区,你可能会彻底毁灭分区数据……
但是,如果你像我一样,要每年/月/周一次进瘟多死系统的话,把 SUSE 完全关机,20 分钟后再重新开启就变成非常痛苦的事情了……
所以,这儿有个迂回之路可以让你在开机的时候找回 GRUB 菜单。
休眠的过程中会更改 GRUB 设置,所以下次你再开机的时候就会直接恢复而不给你其他选择……
迂回之路:禁用这一步(别改 GRUB)。(下面会介绍更改 “99Zgrub” 这个文件,如果你不想改它的话,你也可以直接备份然后删除它。)
你只要以 root 用户打开
/usr/lib/pm-utils/sleep.d/99Zgrub
这个文件,然后到末尾,把 prepare-grub 和 grub-once-restore 注释掉。
在 openSUSE 中,是这样的
###### main() if [ "$1" = hibernate ] || [ "$1" = suspend -a "$2" = suspend_hybrid ]; then prepare-grub fi if [ "$1" = thaw ] || [ "$1" = resume -a "$2" = suspend_hybrid ]; then grub-once-restore fi
只要把 prepare-grub 和 grub-once-restore 注释掉就好了:
###### main() case $1 in hibernate) ### prepare-grub ;; thaw) ### grub-once-restore ;; esac
先要把所有的外置设备都 umount 掉!
然后就可以开开心心地去休眠了……
侦错
如果你想在恢复之后看一些统计数据(比如比较读写速度什么的),你可以让 resume 在加载镜像后和恢复快照前等个几秒钟,把以下内容添加到 /etc/suspend.conf 里去:
resume pause = 10
这样是等 10 秒钟。你应该在 grub 设置中把闪屏关闭,否则你是看不到数字的。这个等待过程可以按回车键来终止。
某些文件系统的问题
如果 grub 安装在 reiserfs 分区上的话,恢复过程可能非常慢,参见 Bug #538795。这似乎是因为 grub 在加载内核和 initrd 之前要把内存中的日志重放一遍而花了不少时间。很显然,要绕过这个问题只需创建一个独立的 /boot 分区,格式化成 ext2 文件系统,然后把 grub 移到那方面去(当然 /boot/* 的所有文件都要移)。
有很可能这个问题对其他的日志文件系统也有影响,比如 ext3 和 xfs。如果有人试过的话可以来汇报一下 ;-)
老型号 ThinkPad 笔记本的问题
有报告说在有些老型号的 ThinkPad 笔记本上恢复的时候会卡住。根据 Bug #450256,这个问题至少影响了 X31 和 T41 的一些型号,并且和最近加入内核的一个叫 ACPI 硬件签名的功能有关。从讨论来看,这个问题是由 BIOS 的一个 bug 引起的。 有两个方法来解决这个问题:
- 升级 BIOS 版本.
- 在内核参数中添加 acpi_sleep=s4_nohwsig 以关闭 ACPI 硬件签名。
待开发
目前 pm-utils 和我们的 initrd 还不允许挂起到 swap 文件或从 swap 文件恢复,只能在 swap 分区上。革命尚未成功,同志仍需努力。
参见
外部链接
- [http://sourceforge.net/projects/suspend/ Sourceforge 上的 Linux 挂起项目