fedora, btrfs, and hibernation
Here’s how to hibernate to disk when using the automatic partitioning scheme in Fedora 34 (btrfs+zram), optionally with luks enabled.
Originally this post was a lot longer, detailing each and every step suited for you to copy and paste. I decided to go ahead and automate the whole process with ansible instead.
A few things to keep in mind:
- only run this after you’ve audited the playbook and understand what it’s doing
- you’re using this at your own risk
- Secure Boot must be disabled
- this has only been tested with Fedora 34
FAQ
- Where can I read more about why I can’t do this anymore?
- Does btrfs make a difference?
Yes, you may notice the steps to create a swapfile are different than what you’re used to. We’ll have to use kernel 5.0+, and set NOCOW
in order to gain btrfs swapfile support. More information is available on the btrfs wiki along with the ArchWiki.
Process
Below provides a very high level overview of the process, for more detail, check out my ansible playbook.
- create an empty swapfile
- set its attributes to
NOCOW
(chattr +C
) - allocate the swapfile to be the same size as your system’s memory
- note: you may be okay with a swap partition smaller than the size of your memory
- set its attributes to
- set up a Linux swap area on your swapfile
- enable your swapfile for paging and swapping
- update
/etc/fstab
with your swapfile information - since there’s already an existing swap target (default zram device), create
systemd
overrides to avoid false positive errors about swap size. - get the physical swap offset by running btrfs_map_physical.c, as recommended by the ArchWiki.
- since this step includes running some C program from the internet, I’ve opted to use a container (you should be auditing the code regardless though)
- calculate the real swap offset
- this is done by dividing the physical swap offset from above by the system’s page size
- construct resume arguments for grub
- use the uuid of your swapfile along with the swap offset calculated above
- use
grubby
to update kernel arguments to includeresume
andresume_offset
- add the resume module to
dracut
and regenerate the initramfs- add resume module under
/etc/dracut.conf.d/resume.conf
dracut -f
- add resume module under
After this, you’ll need to reboot and test hibernation with:
sudo systemctl hibernate
If you’re on GNOME, and would like hibernation back in in the status menu, check out the Hibernate Status Button GNOME shell extension.