如何同时使用 dm-crypt 和 swsusp¶
作者:Andreas Steinmetz <ast@domdv.de>
一些先决条件:您了解 dm-crypt 的工作原理。如果不了解,请访问以下网页:http://www.saout.de/misc/dm-crypt/ 您已阅读并理解 交换分区休眠。您已阅读 使用初始 RAM 磁盘 (initrd) 并了解 initrd 的工作原理。您知道如何创建或修改 initrd。
现在您的系统已正确设置,您的磁盘已加密,但交换设备和启动分区除外,启动分区可能包含一个用于加密设置和/或救援目的的迷你系统。您甚至可能已经有一个 initrd 来完成当前的加密设置。
此时,您还希望加密您的交换分区。但是,您仍然希望能够使用 swsusp 进行休眠。这意味着您必须能够输入密码,或者在恢复之前从外部设备(如 pcmcia 闪存盘或 USB 存储设备)读取密钥。因此,您需要一个 initrd,它设置 dm-crypt,然后要求 swsusp 从加密的交换设备恢复。
最重要的一点是,您设置 dm-crypt 的方式应确保您休眠/恢复到的交换设备在 initrd 和正在运行的系统中始终具有相同的主/次设备号。实现这一点的最简单方法是始终首先使用 dmsetup 设置此交换设备,这样它将始终看起来像以下内容
brw------- 1 root root 254, 0 Jul 28 13:37 /dev/mapper/swap0
现在,将您的内核设置为使用 /dev/mapper/swap0 作为默认恢复分区,这样您的内核 .config 文件将包含
CONFIG_PM_STD_PARTITION="/dev/mapper/swap0"
准备您的引导加载程序以使用您将创建或修改的 initrd。对于 lilo,最简单的设置如下所示
image=/boot/vmlinuz
initrd=/boot/initrd.gz
label=linux
append="root=/dev/ram0 init=/linuxrc rw"
最后,您需要创建或修改您的 initrd。假设您创建了一个 initrd,它从 pcmcia 闪存卡读取所需的 dm-crypt 设置。该卡格式化为 ext2 文件系统,插入卡时位于 /dev/hde1。该卡至少包含一个名为“swapkey”的文件中的加密交换分区设置。您的 initrd 的 /etc/fstab 文件包含类似以下内容
/dev/hda1 /mnt ext3 ro 0 0
none /proc proc defaults,noatime,nodiratime 0 0
none /sys sysfs defaults,noatime,nodiratime 0 0
/dev/hda1 包含一个未加密的迷你系统,它通过从 pcmcia 闪存盘读取设置来设置您的所有加密设备。接下来是您的 initrd 的 /linuxrc 脚本,它允许您从加密交换分区恢复,如果恢复没有发生,则继续从 /dev/hda1 上的迷你系统启动
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
mount /proc
mount /sys
mapped=0
noresume=`grep -c noresume /proc/cmdline`
if [ "$*" != "" ]
then
noresume=1
fi
dmesg -n 1
/sbin/cardmgr -q
for i in 1 2 3 4 5 6 7 8 9 0
do
if [ -f /proc/ide/hde/media ]
then
usleep 500000
mount -t ext2 -o ro /dev/hde1 /mnt
if [ -f /mnt/swapkey ]
then
dmsetup create swap0 /mnt/swapkey > /dev/null 2>&1 && mapped=1
fi
umount /mnt
break
fi
usleep 500000
done
killproc /sbin/cardmgr
dmesg -n 6
if [ $mapped = 1 ]
then
if [ $noresume != 0 ]
then
mkswap /dev/mapper/swap0 > /dev/null 2>&1
fi
echo 254:0 > /sys/power/resume
dmsetup remove swap0
fi
umount /sys
mount /mnt
umount /proc
cd /mnt
pivot_root . mnt
mount /proc
umount -l /mnt
umount /proc
exec chroot . /sbin/init $* < dev/console > dev/console 2>&1
请不要在意上面奇怪的循环,busybox 的 msh 不支持 let 语句。现在,脚本中发生了什么?首先,我们必须决定是否尝试恢复。如果使用“noresume”或任何用于 init 的参数(如“single”或“emergency”)作为启动参数进行引导,则我们不会恢复。
然后我们需要使用 pcmcia 闪存盘中的设置数据来设置 dmcrypt。如果设置成功,如果我们不想恢复,我们需要重置交换设备。“echo 254:0 > /sys/power/resume”这行代码随后尝试从第一个设备映射器设备恢复。请注意,无论是否恢复,都必须在 /sys/power/resume 中设置设备,否则稍后的休眠将失败。如果恢复开始,脚本执行将在此处终止。
否则,我们只需移除加密的交换设备,并将其留给 /dev/hda1 上的迷你系统来完成整个加密设置(您可以根据自己的喜好修改)。
接下来是众所周知的更改根文件系统并从那里继续启动的过程。我倾向于在继续启动之前卸载 initrd,但您可以自行修改。