Gentoo/Userspace software suspend
Userspace software suspend, also known as µswsusp or uswsusp, is a system for hibernating/suspending. It supports suspend-to-RAM, suspend-to-disk, and "suspend-to-both".
Uswsusp is an altenative to TuxOnIce (Suspend2), which is the suspend-to-disk tool recommended by the Gentoo Power Management Guide. It is the successor to swsusp, a suspend-to-disk mechanism built into 2.6 kernels that notably lacked support for LVM.
Comparison with TuxOnIce
TuxOnIce has many more features than uswsusp, like writing to multiple swap devices. An interesting feature that both uswsusp and TuxOnIce have is "suspend-to-both", where the system state is recorded to both RAM and disk so the computer can resume quickly while staying resilient to power loss. On uswsusp, "suspend-to-both" is a explicit method to suspend, ready to use; on TuxOnIce it requires a bit of configuration: user needs to manually set /sys/power/tuxonice/powerdown_method to 3 or do it by a helper, like hibernate-script which can be set with option PowerdownMethod 3.
Uswsusp has, arguably, a better design than TuxOnIce, as most of its code is in userland rather than in the kernel. TuxOnIce requires patches to the mainline kernel, meaning you have to either run sys-kernel/tuxonice-sources or patch your kernel by hand. Running tuxonice-sources may not be an option if you're already running a patched kernel (xen-sources, hardened-sources, etc.) or you need a newer kernel version than the tuxonice-sources ebuilds offer.
Installation
Make sure your kernel has initramfs and suspend support enabled. You can probably leave "Default resume partition" blank if you're using an initramfs.
Linux Kernel Configuration: Suspend kernel config |
General setup ---> [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support Power management and ACPI options ---> [*] Suspend to RAM and standby [*] Hibernation (aka 'suspend to disk') [*] ACPI (Advanced Configuration and Power Interface) Support ---> -*- Button |
Unmask sys-power/suspend, the userspace programs for uswsusp. Emerge suspend and the sys-power/hibernate-script wrapper.
sys-power/suspend ~amd64
Configuration
Uswsusp
Uswsusp reads its configuration from /etc/suspend.conf. The key parameter is resume device, which you should set to the path of your swap device.
snapshot device = /dev/snapshot resume device = /dev/RESUME_DEVICE compute checksum = y compress = y
Hibernate script
The hibernate script, described in the Gentoo Power Management Guide, is a wrapper for various suspend and hibernate implementations. It handles stopping and starting any services and drivers that don't play well with suspend, as well as invoking the actual suspend commands.
Recommended settings:
SaveClock yes # this will save current system time into RTC when suspending. Unmount /boot /mnt/tmp # in case resume fails, or filesystem is accessed during boot, better to umount it cleanly before suspend. FullSpeedCPU yes # perform suspend as fast as we can, even if we chose to save power on batteries for example. OnSuspend 55 sync # execute command during suspend GentooModulesAutoload yes # hack for Gentoo SwitchToTextMode no # save if you are using kernel mode switching
That'll get you started, but you may have to do further machine-specific configuration. Check out man hibernate.conf, especially the VBE and force options.
Integration with initramfs
You will need an initramfs that runs resume. If you don't have one, this page can walk you through making one. If you already have one -- either homemade or generated by genkernel -- you will likely have to configure your initramfs to support uswsusp. If you're not sure whether you use an initramfs, check for an initrd line in your bootloader configuration (/boot/grub/grub.conf or /boot/lilo/lilo.conf).
Genkernel
It looks like the current version of genkernel doesn't support uswsusp, but the next version might. bug 156445 explains the current situation and contains a patch to make uswsusp work.
The simple manual method:
Modify:
#!/bin/sh . /etc/initrd.defaults . /etc/initrd.scripts +swsusp_resume() { + /sbin/resume +} splash() {
Basically it will use standard genkernel process with the patched linuxrc script and inject the resume utility and suspend.conf into the initramfs.
Custom initramfs
If you use a custom initramfs that mounts your root file system and/or activates your swap, you need to alter your usual init steps slightly to get resume from suspend-to-disk working. Basically, you need to manually invoke uswsusp's userspace resume utility before the root partition is mounted.
The minimal example below shows how to integrate uswsusp with a simple LVM/dm-crypt setup. If used, make sure that sys-apps/busybox and sys-fs/lvm2 were emerged with the static USE flag enabled and sys-fs/cryptsetup was emerged with the dynamic USE flag disabled.
Populating directory tree
Create and populate the directories for your initramfs. The commands below work for amd64; for x86, substitute /usr/lib64 with /usr/lib:
Init script example
Write an init script to suit your needs.
The example script here assumes a single dm-crypt/LUKS partition, inside of which is an LVM volume group, inside of which is the root volume and the swap volume. The swap volume is the "resume device" (configured in /etc/suspend.conf) where uswsusp dumps the machine's state, so the resume has to happen after the swap is unlocked, but before the root volume is mounted. If the resume command finds a suspend image, then the command never returns and the rest of the script is not executed; otherwise, init proceeds normally.
#!/bin/sh mount -t proc proc /proc mount -t sysfs sysfs /sys sleep 2 # wait for kernel msgs to quiet if cryptsetup luksOpen /dev/sda2 vault; then vgchange -ay vault_vg resume mount -r /dev/mapper/vault_vg-root /newroot if [[ -x /newroot/sbin/init ]]; then umount /sys /proc exec switch_root /newroot /sbin/init fi fi # Uncomment if you want a rescue shell # exec sh
If you want to add more advanced functionality to your init script, like reading kernel command line parameters or loading a keymap, consult the excellent init script in the DM-Crypt with LUKS article.
Install script
This script builds an initramfs image from your ~/initramfs directory tree and copies the image to /boot. Run this script whenever you change a file in your initramfs.
#!/bin/sh if ! mount | grep ' on /boot ' > /dev/null; then echo 1>&2 "WARNING: /boot doesn't appear to be mounted" fi find . | cpio --quiet -o -H newc | gzip -9 > /boot/initramfs.img
Configuring the bootloader
Configure your bootloader to use your initramfs image. For Grub, add/edit an initrd line to the appropriate boot entry in grub.conf.
title Linux root (hd0,0) kernel /vmlinuz initrd /initramfs.img
Usage
Uswsusp uses three userspace utilities -- s2ram, s2disk, and s2both -- to execute suspend-to-RAM, suspend-to-disk, and suspend-to-both, respectively. The preferred method for suspending, however, is via the hibernate script, so you shouldn't need to invoke the s2* commands directly unless you're testing your setup.
Suspend-to-disk / Suspend-to-both
To suspend-to-disk (or suspend-to-both, depending on how you configured /etc/hibernate/hibernate.conf), just run hibernate as root:
Actually /etc/hibernate/hibernate.conf refers to /etc/hibernate/disk.conf which tries to load ususpend-disk.conf. You may want to change this line to ususpend-both.conf to use suspend-to-both.
Suspend-to-RAM
To suspend-to-RAM, run:
Troubleshooting
If something goes wrong, first try suspend/resume without X11 running, most issues are video card related.
Also try s2disk directly from text mode without hibernate script and see if it works.
Suspend to RAM is more problematic than suspend to disk as it requires hardware support and cooperation. In most recent laptops it works correctly.
USuspendRamForce yes # if hardware is unrecognized (most probably) USuspendRamAcpiSleep 3 # if you experiencing problem in waking up, also try 1 or 2
Then try:
If suspend fails not resume, look at var/log/messages, you may find modules that broke the suspend cycle, try to unload them during suspend:
UnloadModules MODULE_NAME
Try googling for how other people with your particular hardware (e.g., video card) have gotten it to work.
If the screen stays black when you resume, your computer may still be running fine even though the display is borked. Before you reset the machine, try to shut it down cleanly with Ctrl+Alt+Del or by ssh'ing in.
Integrating acpid
The following will suspend to disk when sleep button is pressed, and suspend to RAM if power button is pressed or lid is closed, add:
button) case "$action" in + power) + /usr/sbin/hibernate + + ;; + lid) + grep -q closed /proc/acpi/button/lid/LID/state && \ + /usr/sbin/hibernate-ram + ;; + sleep) + /usr/sbin/hibernate + ;;
You may need to ajust the lid button location to match your architecture.
Integrating splashutils
uswsusp can show nice splash activity during suspend/resume.
sys-power/suspend fbsplash
Add:
splash = y
FBSplash on
Recreate the initramfs overlay with the new resume and suspend.conf.
Recreate your initramfs with new suspend.conf and try again.
Links
From the forums : a simple init script to resume from uswsusp in your initramfs