SDB:挂起到磁盘

跳转至: 导航, 搜索
这篇文章是有关 s2disk 的,这是一个用户空间的挂起系统


背景

有两种方法可以挂起到磁盘:

  • “旧”的内核空间的方法,基本上就是输出“磁盘”两个字到 /sys/power/state 文件里去。
  • “新”的用户空间的方法,是由 suspend 包里的 s2diskresume 命令控制的。

这篇文章主要讲用户空间的方法。


技术信息

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 分区上。革命尚未成功,同志仍需努力。


参见


外部链接