Never return to a drained laptop again!
Table of Contents
There have been several occasions where I haven’t used my laptop in a few days, only to return to a completely drained battery. This is not only annoying, but also not very good for the battery.
Maybe it’s a false memory, but I want to recall that most OS’s used to have a “Suspend, and then hibernate” feature. But now hibernation isn’t even a default option in Ubuntu?
This is a short guide on how to enable hibernation on Ubuntu 24.10.
Setting it up #
Resizing the swap file #
My system had a swap file (as opposed to a swap partition), but it was only 4GB in size (iirc). For hibernation purposes, it’s recommended that your swap should be the size of your RAM, although there are ways to get away with less.
This command told me that my swap file was located at /swap.img
.
swapon --show
To resize it, I did the following commands:
# Disable the swap file
sudo swapoff -a
# Remove the old swap file
sudo rm /swap.img
# Use `dd` to create a new 16GB file with zeroes
sudo dd if=/dev/zero of=/swap.img count=16384 bs=1MiB
# Set the correct permissions
sudo chmod 600 /swap.img
# Enable this file to be used as swap
sudo swapon /swap.img
Instead of creating the file manually, it’s also possible to use the command mkswap
, which will
set up the file with the correct permissions.
Since I already had a swap file, it was already listed in /etc/fstab
as:
/swap.img none swap sw 0 0
Add kernel parameter to grub
#
We need to pass resume
and resume_offset
as kernel parameters at boot.
systemd
and initramfs
will
try to figure out where the resume data is. See man initramfs-tools
and
man systemd-hibernate-resume
. But maybe when we are using a swap file rather than a
partition, we need to where on a specific partition that file is?In /etc/default/grub
, we add the resume
parameter as the UUID
of partition where the swap file lives. And resume_offset
is where on that partition the file begins. (I think?)
How do we find these values?
The UUID
we can find with the findmnt
command:
sudo findmnt -no UUID -T /swap.img
And it should print the UUID. E.g.:
abcd1234-1234-1234-bdbd-asdfaaaabbbb
We find the offset with the filefrag
command.
sudo filefrag -v /swap.img
File size of /swap.img is 17179869184 (4194304 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 425983: [22118400..] 22544383: 425984:
...
I’ve “highlighted” where the swap file starts, our offset, with square brackets, i.e. 22118400
.
GRUB_CMDLINE_LINUX_DEFAULT="<...> resume=UUID=<your uuid> resume_offset=<some offset>"
Example:
GRUB_CMDLINE_LINUX_DEFAULT="<...> resume=UUID=abcd1234-1234-1234-bdbd-asdfaaaabbbb resume_offset=1234"
And finally, to add this to your grub
menu, run:
sudo update-grub
Then reboot to make it go into effect. After reboot, you can test it out by running:
systemctl hibernate
Suspend, then hibernate #
I don’t want my system to hibernate all the time, I just want it to hibernate if I don’t use it for a while. Thankfully, Chris Arderne has us covered.
We can get this behavior by changing the HandleLidSwitch
parameter in /etc/systemd/logind.conf
:
[Login]
HandleLidSwitch=suspend-then-hibernate
If the battery goes below 5%, the computer will hibernate. But we can also set it to hibernate based on time!
In /etc/systemd/sleep.conf
we can set the HibernateDelaySec
paramter. I’ve set it to go into hibernation after 30 minutes.
[sleep]
...
HibernateDelaySec=1800
And then restart the logind service:
sudo systemctl restart systemd-logind.service
Sources #
- Arch Linux Wiki
- Chris Arderne blog
man systemd-sleep.conf
man logind.conf