Integrate TuxOnIce into Ubuntu's hibernation process

Warning: At the moment I can not recommend to use this script in conjunction with filewriter if you use a journaling filesystem for your root partition (ext3, reiser, ...). The reason is that when using filewriter the initramfs-script in /etc/initramfs-tools/scripts/local-premount/resume_tuxonice mounts this partition read-only to get the hibernation file's target. Unfortunately, the journal will be replayed in any case, so "mount -r /dev/hdX" does not mean "mount /dev/hdX, but don't make any changes on it". And this may result in a filesystem corruption because the resumed system things that these open transaction have not been handled yet. I'll do some changes to the scripts during the weekend, so please be patient of you want to "suspend to file".

Yesterday, I described how to patch TuxOnIce-support into Ubuntu's kernel image. Today we will learn how to integrate this into Ubuntu's default hibernation framework, pm-hibernate. By doing this, you'll benefit from TuxOnIce' features without modifying your bootloader's configuration file and will be able to use your desktop's "Suspend to Disk"-command without changing any system file (because a customized system file might be overwritten on your next update). Furthermore, you will be able to combine suspend to disk with encrypted swap devices or (I prefer this) suspend to a file on your encrypted root partition.

Please note that the scripts I'll introduce are tested only by myself (yet), and they still lack of some features. I would be happy about every improvement. And of course I do not provide any warranty, you'll do this on your own risk. I think that the worst thing that might happen is that data on your root partition gets lost. But of course you're doing backups, don't you?

So, let's start. Oh, wait... did you ensure that you have a suitable backup? Ok. First I'll introduce what has to be done, and at the end I'll provide the scripts that implements this. Well, the first thing we have to do is to add resume support into Ubuntu's initramfs-Image. That is the file stored in /boot, starting with 'initrd.img' and ending with your kernel's version. If you're curious: it's a gzip'd cpio-archive, you can extract it using the following command:

$ mkdir -p initramfs 
$ cd initramfs 
$ gunzip -c /boot/initrd.img-2.6.27-7-tuxonice | cpio -vi

This file is made by 'update-initramfs', a command that creates a "mini-linux" containing some basic binaries, libraries and kernel modules. Furthermore, it executes hooks from /usr/share/initramfs-tools/hooks and from /etc/initramfs-tools/hooks, adds runtime configuration from /usr/share/initramfs-tools/conf.d and /etc/initramfs-tools/conf.d and some event scripts from /usr/share/initramfs-tools/scripts and /etc/initramfs-tools/scripts. We'll use all of the /etc-stuff.

Normally, when you boot your system, the following happens (extremely shortened): Before mounting the root partition, /usr/share/initramfs-tools/script/local will run all executables inside of scripts/local-top and scrips/local-premount (note that the /usr/share- and /etc-trees get merged in the resulting archive). scripts/local-top/cryptroot asks for passwords to decrypt any encrypted partition that needs to be mounted before the system starts, for example '/' and your swap partition if you're using swsusp. It ensures that you entered the correct password by checking the partitions filesystem (otherwise an "unkown fstype, bad superblock or wrong password"-error is shown). Next, scripts/local-premount/resume will check for a hibernation image in your swap partition. If any, it will start resuming this image by executing '/bin/resume', otherwise the system will continue booting.

So, we have a few problems if we want to integrate TuxOnIce-support into this process, and it will not become easier if we want to resume from an encrypted swap device. But for the moment let's assume that this isn't the case - your swap partition is not encrypted or you want to use TuxOnIce FileWriter feature. We need a replacement for script/local-premount/resume, and to prevent any delay in the boot process it would be nice to disable the original resume script. Because we may want to switch between both systems later, it's a bad idea to just overwrite it - instead, we will add an additional script named /etc/initramfs-tools/scripts/local-premount/tuxonice-resume and use a hook stored in /etc/initramfs-tools/hooks/tuxonice to disable classic swsusp if neccessary. This is done by unsetting the 'execute'-bit of this file.

Things will become worse when trying to use this in conjunction with an encrypted swap device. The 'cryptroot'-hook would add this device into it's list and ask for a password before booting, but if it contains an active hibernation image, 'fstype' will not recognize it and so crypttool will reject the password ("unkown fstype..."). So we could write a patch for this tool and wait for an official release, or just wrap arround it. The 'tuxonice'-hook will rename 'fstype' to 'fstype.orig' and replace it by a customized script. This executes the original binary, and if it fails to determine the filesystem, the wrapper will test for TuxOnIce. This is done by comparing offset 4086 of the input device to 0xEDC302E9 using "dd". If matching, the wrapper returns "TuxOnIce" as filetype and 'cryptroot' (in scripts/local-top, not in hooks) will accept it.

Ok, but we still have to hook into Ubuntu's hibernation system. This is done by a script placed in '/etc/pm/sleep.d/01tuxonice'. It checks for a valid image file (if using filewriter). A valid image has to start with "TuxOnIce", the rest doesn't matter. And it should be large enough to save the whole memory into it. For this reason, this script will create or enlarge the file to the size of your memory, determined by the 'MemTotal:'-line in /proc/meminfo (because of this the first hibernation process after installing this script, changing the hibernation file or enlarging your memory will take quite a while). Finally, it writes resume information to a temporary file (this is the content of /sys/power/tuxonice/resume after defining /sys/power/tuxonice/file/target - have a look at the original documentation for details). Suspending to swap is much easier: The swap device has to be written to /sys/power/tuxonice/resume. When resuming, /etc/pm/sleep.d/01tuxonice removes the temporary file (if any).

There are two additional scripts in /etc/acpi/suspend.d/01-tuxonice.sh and /etc/acpi/resume.d/01-tuxonice.sh. These are wrappers for the (depricated?) acpi hibernation framework which is used when you press the "sleep button" on your keyboard, for example.

So, to use this scripts, download http://dau-sicher.de/stuff/tuxonice-ubuntu-initramfs.tar.gz and extract it into your filesystem's root (or into any other directory if you only want to have a look at it). A configuration file will be overwritten, so it is a good idea to make a copy of it (even if you made a backup before - you did it, didn't you?):

$ cd ~ 
$ wget http://dau-sicher.de/stuff/tuxonice-ubuntu-initramfs.tar.gz 
$ cd / 
$ sudo cp /etc/initramfs-tools/conf.d/resume /etc/initramfs-tools/conf.d/resume.orig 
$ sudo tar xvzf ~/tuxonice-ubuntu-initramfs.tar.gz

Now, let's have a look at '/etc/initramfs-tools/conf.d/resume'. You will find three parameters:

RESUME_METHOD="tuxonice" 
RESUME=file:/.hibernation-file 
RESUME_INFO=/.tuxonice-resume.info

The first one (RESUME_METHOD) enables TOI-support. If set to any other value then "tuxonice", the classic swsusp method will be used. The second one is known from the original configuration file. In this example, it points to the file where the hibernation image should be stored. It doesn't matter on which partition or device it is stored, but it has to be on your root partition if you want to use encrypted devices. When using a swap device, omit the 'file:'-prefix. If it is an unencrypted swap device, you may prepend a 'swap:'-prefix, but this shouldn't be neccessary. The last one, RESUME_INFO (described as 'temporary file' before), will be used in conjunction with filewriter to save the hibernation file's offset before suspending. This is required because TuxOnIce will not mount your root device to get this location by itself - instead, we will have to mount it read-only, extract the resume information and unmount it again. For this reason, RESUME_INFO must be a file on your root partition!

At the first time, and everytime you make any changes to /etc/initramfs-tools/conf.d/resume, you have to rebuild your initrd. As mentioned before this is done by an update-script (I assume that you're running the patched kernel at the moment - if not, you should stop and reboot NOW!):

sudo update-initramfs -c -k $(uname -r)

If you modified /boot/grub/menu.lst for getting TuxOnIce support, it is a goog idea to revert this changes now.

That's it. If you hack 'sudo pm-hibernate' into your console, or use your desktop managers "Suspend to disk"-button, the system should hibernate and resume using TuxOnIce (the first suspend might take some time because the hibernation file will be created).

There are still some features missing, so if you want to help in development, have a look at the following issues:

  • consider 'resume=/noresume' kernel parameters (as the original resume-script does)
  • ensure that the resume file contains a valid hibernation image (like hibernate-script does)
  • write complete configuration into $RESUME_INFO before suspending, so you don't have to 'update-initramfs' everytime
  • this implemented, it will be possible to allow choosing between swsusp and tuxonice at suspend time
  • integrate more of the features of TuxOnIce into this scripts
  • pack this stuff into a .deb-file and merge it into ubuntu's repository ;-)

Comments

hi,
i followed your instructions but when i try to hibernate it is saying writing cache 20%....100% then atomic copy... cleaning up... and then all the led's go back on, screen turns black and my laptop (thinkpad r61) keeps running...

you know a solution for that?

Hi! I followed both the parts of the guide and tuxonice works like a charm, so thank you!
I'd like to ask you what's the relation between your scripts and the hibernate script that can be found on the tuxonice website: looks like it supports a lot of features (some important: modifying menu.lst to reflect hibernation status, support for unmounting filesystems before hibernation..) so it would be nice to implement it!

Hi Gian, the differences to hibernate-script is that this method integrates smoothly into Ubuntu's hibernation system (pm-utils).

Of course it would be possible to integrate hibernation-script into pm-utils, but I would not recommend to do so. Because these two share many features, you would have two places for many things: /etc/hibernate and /etc/pm. Which one to choose?

The things that you named (e.g. support for unmounting filesystems before hibernation) can be done using pm by creating a small shell script at /etc/pm/sleep.d. Have a look at this excelent description from the openSUSE people.

I would suggest to have a look at /var/log/syslog for TuxOnIce output. If the problem still exists, you may want to have a look at the FAQ or subscribe to the tuxonice-users mailing list.

It might help to set "extra_page_allowance" to 0 before hibernating. Add this line to /etc/pm/sleep.d/01tuxonice, just before "Writing resume info":

echo 0 > /sys/power/tuxonice/extra_pages_allowance

hi,
in syslog tuxonice sais nothing...

setting extra_page_allowance to 0 didn't help... any other idea?

thanks so far

Hi! Great work, thanks! Did you ever get it to work with filewriter and ext3?

ext3 does not make any problems. I'm very busy at the moment, but I hope that I can update this article within the next two weeks.

got it!

had to change
extra_page_allowance to 2000
and
powerdown_method to 4

Thank you for this information!

Hi,
did you get the fbsplash working on ubuntu? if so how did you do?

thanks!

I'm not using it, sorry.

Great! Much appreciated!

Hi,

thank your information about TuxOnIce.
I want to use TuxOnIce in VMWarePlayer Fedora11(kernel2.6.29.6-217) with FileWriter mode.
It can(maybe) get the image data to a file located in '/boot' director, but can't resume from this file.

the dmesg log is

TuxOnIce 3.0.1 (http://tuxonice.net)
TuxOnIce: Ignoring late initcall, as requested.
PM: Resume from partition file:/dev/dm-0:0xe14000
PM: Checking hibernation image.
PM: Error -6 checking image file
PM: Resume from disk failed.

Would you helpping me!thank you very much.

I hate this slogan: "Yes, you can" ;-)

I see you write "sudo update-initramfs -c -k $(uname -r)" in this page but "sudo update-initramfs -u -k $(uname -r)" in the file, which one should be true??

thank you.

-u updates an existing file, -c creates a new one. I think it doesn't really matter. I'm not using Ubuntu anymore, so I cannot not test it at the moment.

do you mean that I can leave it "un-tounch" ??
(seesm the original setting makes those files in root?)
I'm totally newbie in Linux...

Thank you very much.

You can choose the path by yourself. The only thing that I would suggest is that both files (RESUME and RESUME_INFO) are on your root partition (e.g. in / or in /root).

After one day to fight with the Linux, I finally able to use the tuxonice hibernate function with my xbuntu 9.04. (w/ tuxonice 3.01) Thanks for your great tuturial!!!

There is another problem I have to fix. When I press the power button in my Acer C100 , the system hibernate correctly. But when I wake it up, it goes to suspend mode again.
I read the FAQ of TuxOnIce and modified
etc/acpi/events/powerbtn

from " event=button[ /]power PWRF " to
" event=button[ /]power.*[02468ace]$ "
but the problem still appears.

May you give me some advice ? thank you very much.

you said i need to modify the following items but how can I know the correct path of them?

====
RESUME_METHOD="tuxonice"
RESUME=file:/.hibernation-file
RESUME_INFO=/.tuxonice-resume.info
======