Andreas Steinmetz | 6ed9fce | 2005-09-03 15:57:03 -0700 | [diff] [blame] | 1 | Author: Andreas Steinmetz <ast@domdv.de> |
| 2 | |
| 3 | |
| 4 | How to use dm-crypt and swsusp together: |
| 5 | ======================================== |
| 6 | |
| 7 | Some prerequisites: |
| 8 | You know how dm-crypt works. If not, visit the following web page: |
| 9 | http://www.saout.de/misc/dm-crypt/ |
| 10 | You have read Documentation/power/swsusp.txt and understand it. |
| 11 | You did read Documentation/initrd.txt and know how an initrd works. |
| 12 | You know how to create or how to modify an initrd. |
| 13 | |
| 14 | Now your system is properly set up, your disk is encrypted except for |
| 15 | the swap device(s) and the boot partition which may contain a mini |
| 16 | system for crypto setup and/or rescue purposes. You may even have |
| 17 | an initrd that does your current crypto setup already. |
| 18 | |
| 19 | At this point you want to encrypt your swap, too. Still you want to |
| 20 | be able to suspend using swsusp. This, however, means that you |
| 21 | have to be able to either enter a passphrase or that you read |
| 22 | the key(s) from an external device like a pcmcia flash disk |
| 23 | or an usb stick prior to resume. So you need an initrd, that sets |
| 24 | up dm-crypt and then asks swsusp to resume from the encrypted |
| 25 | swap device. |
| 26 | |
| 27 | The most important thing is that you set up dm-crypt in such |
| 28 | a way that the swap device you suspend to/resume from has |
| 29 | always the same major/minor within the initrd as well as |
| 30 | within your running system. The easiest way to achieve this is |
| 31 | to always set up this swap device first with dmsetup, so that |
| 32 | it will always look like the following: |
| 33 | |
| 34 | brw------- 1 root root 254, 0 Jul 28 13:37 /dev/mapper/swap0 |
| 35 | |
| 36 | Now set up your kernel to use /dev/mapper/swap0 as the default |
| 37 | resume partition, so your kernel .config contains: |
| 38 | |
| 39 | CONFIG_PM_STD_PARTITION="/dev/mapper/swap0" |
| 40 | |
| 41 | Prepare your boot loader to use the initrd you will create or |
| 42 | modify. For lilo the simplest setup looks like the following |
| 43 | lines: |
| 44 | |
| 45 | image=/boot/vmlinuz |
| 46 | initrd=/boot/initrd.gz |
| 47 | label=linux |
| 48 | append="root=/dev/ram0 init=/linuxrc rw" |
| 49 | |
| 50 | Finally you need to create or modify your initrd. Lets assume |
| 51 | you create an initrd that reads the required dm-crypt setup |
| 52 | from a pcmcia flash disk card. The card is formatted with an ext2 |
| 53 | fs which resides on /dev/hde1 when the card is inserted. The |
| 54 | card contains at least the encrypted swap setup in a file |
| 55 | named "swapkey". /etc/fstab of your initrd contains something |
| 56 | like the following: |
| 57 | |
| 58 | /dev/hda1 /mnt ext3 ro 0 0 |
| 59 | none /proc proc defaults,noatime,nodiratime 0 0 |
| 60 | none /sys sysfs defaults,noatime,nodiratime 0 0 |
| 61 | |
| 62 | /dev/hda1 contains an unencrypted mini system that sets up all |
| 63 | of your crypto devices, again by reading the setup from the |
| 64 | pcmcia flash disk. What follows now is a /linuxrc for your |
| 65 | initrd that allows you to resume from encrypted swap and that |
| 66 | continues boot with your mini system on /dev/hda1 if resume |
| 67 | does not happen: |
| 68 | |
| 69 | #!/bin/sh |
| 70 | PATH=/sbin:/bin:/usr/sbin:/usr/bin |
| 71 | mount /proc |
| 72 | mount /sys |
| 73 | mapped=0 |
| 74 | noresume=`grep -c noresume /proc/cmdline` |
| 75 | if [ "$*" != "" ] |
| 76 | then |
| 77 | noresume=1 |
| 78 | fi |
| 79 | dmesg -n 1 |
| 80 | /sbin/cardmgr -q |
| 81 | for i in 1 2 3 4 5 6 7 8 9 0 |
| 82 | do |
| 83 | if [ -f /proc/ide/hde/media ] |
| 84 | then |
| 85 | usleep 500000 |
| 86 | mount -t ext2 -o ro /dev/hde1 /mnt |
| 87 | if [ -f /mnt/swapkey ] |
| 88 | then |
| 89 | dmsetup create swap0 /mnt/swapkey > /dev/null 2>&1 && mapped=1 |
| 90 | fi |
| 91 | umount /mnt |
| 92 | break |
| 93 | fi |
| 94 | usleep 500000 |
| 95 | done |
| 96 | killproc /sbin/cardmgr |
| 97 | dmesg -n 6 |
| 98 | if [ $mapped = 1 ] |
| 99 | then |
| 100 | if [ $noresume != 0 ] |
| 101 | then |
| 102 | mkswap /dev/mapper/swap0 > /dev/null 2>&1 |
| 103 | fi |
| 104 | echo 254:0 > /sys/power/resume |
| 105 | dmsetup remove swap0 |
| 106 | fi |
| 107 | umount /sys |
| 108 | mount /mnt |
| 109 | umount /proc |
| 110 | cd /mnt |
| 111 | pivot_root . mnt |
| 112 | mount /proc |
| 113 | umount -l /mnt |
| 114 | umount /proc |
| 115 | exec chroot . /sbin/init $* < dev/console > dev/console 2>&1 |
| 116 | |
| 117 | Please don't mind the weird loop above, busybox's msh doesn't know |
| 118 | the let statement. Now, what is happening in the script? |
| 119 | First we have to decide if we want to try to resume, or not. |
| 120 | We will not resume if booting with "noresume" or any parameters |
| 121 | for init like "single" or "emergency" as boot parameters. |
| 122 | |
| 123 | Then we need to set up dmcrypt with the setup data from the |
| 124 | pcmcia flash disk. If this succeeds we need to reset the swap |
| 125 | device if we don't want to resume. The line "echo 254:0 > /sys/power/resume" |
| 126 | then attempts to resume from the first device mapper device. |
| 127 | Note that it is important to set the device in /sys/power/resume, |
| 128 | regardless if resuming or not, otherwise later suspend will fail. |
| 129 | If resume starts, script execution terminates here. |
| 130 | |
| 131 | Otherwise we just remove the encrypted swap device and leave it to the |
| 132 | mini system on /dev/hda1 to set the whole crypto up (it is up to |
| 133 | you to modify this to your taste). |
| 134 | |
| 135 | What then follows is the well known process to change the root |
| 136 | file system and continue booting from there. I prefer to unmount |
| 137 | the initrd prior to continue booting but it is up to you to modify |
| 138 | this. |