This article explains how to configure a Debian Jessie system to hibernate using swap space that’s created just before suspending and destroyed just after resuming. This trick allows hibernation on a swap-free or swap-lite system—useful on a desktop system running with enough RAM to make swap space otherwise unnecessary.
$ rootdev=$(mount | grep ' / ' | awk '{ print $1 }')
Important! Make sure you get this right. Otherwise your system may fail to suspend or—much worse—fail to resume.
$ echo $rootdev
/dev/sda1
The second line (e.g., /dev/sda1
) should be your system’s root
partition.
uswsusp
$ sudo apt-get install uswsusp &&
sudo sh -c "cat <<EOF >/etc/uswsusp.conf
resume device = $rootdev
compress = y
early writeout = y
shutdown method = platform
image size = 0
resume offset = 0
EOF"
Hibernating using a swap file—as opposed to a swap partition—requires
special support. We’ll use uswsusp
.
The /etc/uswsusp.conf
is the configuration file for uswsusp
. The
image size
and resume offset
lines are placeholders that we’ll
overwrite each time before suspending.
Note. It’s also possible to hibernate to a swap file using systemd
,
but my only experience doing this is with Arch Linux, and, as far as I
know, the swap file must exist upon boot-up, thus preventing the swap
file from being created on demand.
resume
kernel parameter$ { grep -q '\<GRUB_CMDLINE_LINUX_DEFAULT=.*resume=' /etc/default/grub &&
(echo 'Warning: The `resume` parameter is already set.' >&2 || true) } ||
{ sudo sed --in-place \
-e "s#^\\(GRUB_CMDLINE_LINUX_DEFAULT=\"\\)#\\1resume=$rootdev #" \
/etc/default/grub &&
sudo update-grub; }
The resume
kernel is necessary to resume from a swap file.
Otherwise the kernel will not find the swap file, and the system will
boot normally—as though rebooting.
If the resume
parameter is already set, you’ll need to take
intelligent action to resolve.
dynamic-hibernate
script$ sudo wget -O /usr/local/sbin/dynamic-hibernate \
https://raw.githubusercontent.com/cmbrandenburg/pcconf/e7dbe6128a9267b1f55fed27b22fcbfdc1734b3e/bin/dynamic-hibernate &&
sudo chmod +x /usr/local/sbin/dynamic-hibernate
The dynamic-hibernate
script does the actual hibernation. It:
/etc/uswsusp.conf
with the location of the new swap
file,By default, the script requests the kernel to store the smallest image
possible when suspending, presumably by discarding disk buffers and
disk-backed pages that may be safely reloaded after resuming. In my
experience, smaller images yield faster resume speeds when using a
spinning disk, and SSDs are fast enough to make any difference
negligible. Nevertheless, if you want to change this behavior then
modify the image size
value in the script.
sudo
permission to hibernate (optional)$ sudo sed --in-place \
-e "\$a$USER ALL = NOPASSWD: /usr/local/sbin/dynamic-hibernate" \
/etc/sudoers
This gives permission to your current user account to run the
dynamic-hibernate
script without entering a password.
$ mkdir -p ~/bin &&
touch ~/bin/hibernate &&
chmod +x ~/bin/hibernate &&
cat <<EOF >~/bin/hibernate
#!/bin/sh
gnome-screensaver-command --lock
sudo /usr/local/sbin/dynamic-hibernate
EOF
Locking the screen requires the user to enter a password after resuming. Without locking the screen, anyone who resumes your computer during hibernation will gain access to your system.
The above script works only if you’re using the Gnome screensaver. If
you’re using a different screensaver then you must change the
~/bin/hibernate
script appropriately.
$ ~/bin/hibernate
Or:
$ sudo /usr/local/sbin/dynamic-hibernate
Your system will take a few moments to save state before powering off. Power the system back on, and the system should restore its state as it was before suspending.
Once you get hibernation working, it should continue to work reliably. However, here are some further considerations.
Don’t hibernate after upgrading the kernel. Reboot first. Otherwise the kernel you resume with will be a different kernel than what you suspended with, and the mismatch will cause mayhem.
If your system fails to suspend then there’s a good chance the hibernation script will print a useful error message.
If your system fails to suspend or resume then you may need to
manually delete the swap file that gets left behind
(/swap.hibernate
).
If your system fails to resume then your system will suffer the same consequences as though it crashed. This includes loss of application state, file corruption, etc.
Got feedback? Email me at c.m.brandenburg@gmail.com.