Suspend to disk HOWTO
~~~~~~~~~~~~~~~~~~~~~
Copyright (C) 2006 Pavel Machek <pavel@suse.cz>
Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>

I. Quick start

You'll need the 2.6.17-rc1 kernel or above, or a recent -mm kernel.  It has to
be configured to support software suspend.  It is also recommended to configure it to
support RAM disks, initial RAM disks, loopback block devices, and the ext2 filesystem.

You'll also need /dev/snapshot for the suspend tool to work:

crw-r--r--  1 root root 10, 231 Jan 13 21:21 /dev/snapshot

For compression, you'll additionally need the Marc Lehmann's libLZF library
to be installed on your system, and for encyption you'll need OpenSSL.

First, edit Makefile and the conf/suspend.conf file to reflect the
configuration of your system.  The value of the RESUME_DEVICE constant in Makefile
must be the same as the value of the "resume device" parameter in the configuration
file and it must be the full path of your suspend swap partition device file.

There should be just one resume partition, for now. You'll need at most 1/2 of
your RAM of free space on it, but in some cases it may be smaller, too.  The suspend
tool may be configured to create quite small snapshot images but then some contents
of the RAM will have to be swapped out before suspend.

Next, build the userspace tools in the usual way:

$ make suspend
$ make resume

To install the suspend tool, become root and run:

# make install-suspend

The installation procedure for the resume tool depends on whether you use an initrd
or not.

If you don't use an initrd, you'll need one to run the resume tool.  It's not
anything to worry about, though.  Become root, run:

# make install-resume-initrd

and add the following line to the GRUB configuration file (right after your
kernel configuration):

	initrd (hd0,0)/resume-initrd

where (hd0,0) should be replaced with the identification of your boot partition
(please refer to the GRUB documentation for details).
[In fact this will work if you have a separate boot partition.  If you don't,
the line you should add to the GRUB configuration file is:

	initrd (hd0,0)/boot/resume-initrd

where (hd0,0) should be replaced with the identification of your root partition.]
If you use LILO, please refer to its documentation for the information related to
initrd files.

If you use an initrd already, you should know how to put the resume binary into it.
Also, you ought to have a linuxrc script or binary on the initrd, so you'll need to
make it execute the resume binary at the very end.

To suspend-to-disk, run

./suspend

Suspend is easy, resume is slightly harder. Resume application has to
be run without any filesystems mounted rw, and without any journalling
filesystems mounted at all, preferably from initrd (but read-only ext2
should do the trick, too).  However, if you have followed the instructions above,
the resume tool should be started automatically when the kernel boots.

If you prefer to run resume manually, it is also easy

./resume

but you MUST ensure not to mount any filesystems rw and any journaled filesystems
at all before that.  Otherwise you can lose data.


II. Installation

1) For compression you'll need the Marc Lehmann's libLZF library.  If it's not installed
on your system, download the tarball from http://www.goof.com/pcg/marc/liblzf.html,
unpack it, go to the directory containing the source and run

$ ./configure
$ make

Next, become root and run

# make install

[This will put the lzf.h file into /usr/local/include, the library
into /usr/local/lib, and the lzf binary into /usr/local/bin.]

For encryption you'll need the OpenSSL library, but it should be installed on your
system anyway.  If it is not (highly unlikely), please refer to the documentation at
http://www.openssl.org for installation instructions.

2) You'll need to compile the suspend and resume tools.  To do this run

$ make suspend
$ make resume

in the directory where you have placed the sources.

3) Create the configuration file for the suspend tool.  Its default name
is /etc/suspend.conf, but this can be customized by changing CONFIG_FILE
in config.h. It is also possible to specify the configuration file name
from the command line, by using the -f option, eg.

# suspend -f <config_file>

The configuration file must contain the resume device specification, eg.

resume device = /dev/<your_swap_partition>

Optionally, it can contain the snapshot device specification, eg.

snapshot device = /dev/snapshot

and the following parameters:

image size = <preferred_suspend_image_size_in_bytes>
suspend loglevel = <kernel_console_loglevel_during_suspend>
compute checksum = <y/n>
compress = <y/n>
encrypt = <y/n>
RSA key file = <path>
max loglevel = <ignored>
suspend to both = <y/n>
early writeout = <y/n>
splash = <y/n>

The "image size" parameter may be used to limit the size of the system
snapshot image created by the suspend tool, but it's not mandatory. Namely,
the suspend tool will do its best to limit the image size as required by
this parameter, but if that's not possible, it will suspend the system anyway,
with a bigger image. If "image size" is set to 0, the snapshot image will be
as small as possible.

If the "compute checksum" parameter is set to 'y', the suspend and resume
tools will use the MD5 algorithm to verify the image integrity.

If the "compress" parameter is set to 'y', the suspend and resume tools will
use the LZF compression algorithm to compress/decompress the image.

If the "encrypt" parameter is set to 'y', the suspend and resume tools will
use the Blowfish encryption algorithm to encrypt/decrypt the image.  If the
"RSA key file" option is also used, the suspend tool will generate a random
key for the Blowfish encryption that will be passed to the resume tool
within the image header with the help of the RSA cipher.  However, for this
purpose you'll need an additional RSA key file the path to which should
be the value of "RSA key file".  For more details refer to section "IV. Advanced
encryption" in this document.

If the "suspend to both" parameter is set to 'y', the suspend tool will suspend
the box to RAM after the suspend image has been saved to disk.  Then, upon
resume, if there's some battery power remaining, the box will be resumed
from RAM and the saved image will be discarded.  However, for this to work
the box must be in the suspend to RAM whitelist provided along with the tools.

If the "early writeout" parameter is set to 'y' is specified, the suspend
utility will start syncing the resume device early in the process of writing
the image to it.  [This has been reported to speed up the suspend on some
boxes and eliminates the "fast progress meter and long fsync wait" effect.]

The "splash" parameter is used to make suspend and/or resume use a splash system
(when set to 'y').  Currently the bootsplash.org's splash system is supported.

The resume tool can use the same configuration file that is used by the
suspend tool, but it will ignore most of the above parameters.  It will use the
value of "suspend loglevel" as the kernel console loglevel during resume. Additionally
it will use the value of "max loglevel" as the kernel console loglevel to switch to in
case the resume fails (this parameter is ignored by the suspend tool).

It is not necessary to set "compute checksum = y" and/or "compress = y",
and/or "encrypt = y" for the resume tool.  The appropriate information related to
these options will be passed to it in the image header by the suspend tool.
However, the resume tool will only use the splash system if "splash = y" is set for it
explicitly.

4) You'll need to create the snapshot device file:

# mknod /dev/snapshot c 10 231

If the name of this file is equal to SNAPSHOT_DEVICE in swsusp.h, it is not
necessary to specify it in the configuration file.

If you use "make install-suspend" to install the suspend tool, it will also
install the configuration file from the conf directory in your /etc
directory and it will create the snapshot device file for you if it's not present.

Now you should be able to use the suspend tool. It is recommended, however,
to put the tool into a directory located directly on the root filesystem,
for safe testing.

5) It is recommended to place the resume tool on an initrd.  It may be done
using "make install-resume-initrd", but I'll describe the full procedure in case
you want to do something in a different way.  For simplicity I will only cover the
fastest method of setting it up that will allow you to get the resume tool up and
running quickly.  [The described procedure reflects the actions performed by
"make install-resume-initrd".]

(a) Configure the kernel to support RAM disks, initial RAM disks, loopback
block devices, and the ext2 filesystem, and install it.

(b) Create the /initrd directory if it doesn't exist already.

(c) Create a blank file, as large as to accommodate all files you'll
be placing on the initrd filesystem.  In the simplest case that will be the
resume tool itself, some directories and some device files.

The resume tool is linked statically, so you won't need any libraries to run it.
On my box the size of it was smaller that 2 MB, so I could do:

$ dd if=/dev/zero of=initrd bs=2000k count=1

(d) Run mke2fs on this file, eg.

$ /sbin/mke2fs -F -m0 initrd

(e) Become root and mount the filesystem, eg.

# mount -t ext2 -o loop initrd /mnt

(f) Create the console device, the snapshot device, and the resume device on it, eg.

# mkdir /mnt/dev
# mknod /mnt/dev/console c 5 1
# mknod /mnt/dev/snapshot c 10 231
# mknod /mnt/dev/hda2 b 3 2

[The initrd filesystem will be mounted as the root filesystem, so the paths
with respect to it must be the same as in your "normal" root filesystem.]

(g) Create the proc and etc directories on it (the resume tool will use them), eg.

# mkdir /mnt/proc
# mkdir /mnt/etc

(h) Copy the resume tool to the initrd filesystem and link it to linuxrc, eg.

# cp resume /mnt/
# cd /mnt
# ln -s resume linuxrc

(i) Put the configuration file for the resume tool in the etc directory on
the initrd filesystem, eg.

# cp /etc/suspend.conf /mnt/etc/

(j) Unmount the initrd filesystem and move the file containing it to your /boot
directory, eg.

# umount /mnt
# mv initrd /boot/resume-initrd

(k) In the GRUB configuration file add the initrd to the configuration of the
newly installed kernel, eg.

	initrd (hd0,0)/resume-initrd

(if you use LILO, please refer to its documentation).

6. If you already have the resume initrd file which is called resume-initrd
and located in the /boot directory, you can install the resume tool on it
by using "make install-resume".


III. Testing

Before you start using the suspend and resume tools for real, you should test
your setup.  For this purpose it's recommended to boot the new kernel with the
"init=/bin/bash" command line argument.  Then, the kernel should run bash
instead of init and you should get a (root) command prompt with the root
filesystem mounted read-only and with no other filesystems.

If this happens, mount the sysfs and proc filesystems and enable swap:

# mount /sys
# mount /proc
# swapon -a

Next, go to the directory where the suspend tool is and do:

# ./suspend

If this fails, the tool will return to the command prompt with a (hopefully
instructive) message.  Otherwise you should be able to see some messages
from it on the screen and finally the progress meter, and the box should be powered
off.  If that happens, you can start it again and let the resume utility run
from the initrd.  If everything is fine, it will read the image and restore
the system state from it, and you will get the command prompt back.  If so,
your setup works.  Otherwise there's something wrong and you'll need to find
out what and why.

The next step is to check whether your device drivers suspend and resume correctly.
To do this, it is reasonable to boot the kernel to the runlevel 2 and run the
suspend tool.  If it suspends successfully and the resume tool is able to restore
the system state, the drivers are most probably fine.  Otherwise please report
the problem.

Finally, you can start X and try to suspend from an xterm.  If this works, you're
done.

IV. Advanced encryption

If the suspend and resume tools are compiled with the encryption support, the
RSA cipher may be used to pass the Blowfish encryption key from the suspend
tool to the resume tool within the suspend image.  This way the suspend tool
need not ask the user for a passphrase.

For this purpose you need to generate the RSA key pair using the suspend-keygen tool
provided along with the suspend and resume tools.  The output file of suspend-keygen
should be saved as /etc/suspend.key (or something else pointed to by the
"RSA key file =" configuration  parameter of suspend).  This file contains the public
modulus (n), public exponent (e) and the Blowfish-encrypted private exponent (d) of
the RSA key pair.  The RSA private exponent (d) is encrypted with a user-provided
passphrase.

Then, the suspend utility will load the contents of this file, generate a random
session key (k) and initialization vector (i) for the image encryption and use
(n, e) to encrypt these values with RSA.  The encrypted (k, i) as well as the
contents of the RSA key file will be saved in the image header.

The resume utility will read (n, e) and (encrypted) d as well as (encrypted) (k, i)
from the image header.  Then it will ask the user for a passphrase and will
try to decrypt (d) using it.  Next, it will use (n, e, d) to decrypt (k, i) needed
for decrypting the image.
