Goals and rationale
Hibernation stores the state of the whole operating system — the contents of memory used by the kernel and all programs — on disk. The machine is then completely powered off. Upon next boot, this state is restored and the old kernel and all the programs that were running continue execution.
Hibernation is nowadays used less often, because “suspend” — the state where CPU is powered down, but the contents of memory are preserved, works fine on most laptops and other small devices. But if the suspend is implemented poorly and it drains the battery too quickly, or if the user needs to completely power off the device for some reasons, hibernation can still be useful.
We need a storage area for hibernation. The kernel allows two options:
– either a single large-enough swap device, usually a partition,
– or a single large-enough swap file on some file system.
Fedora Linux installations by default do not use a normal swap device or file. Instead, a zram device is created, which is an in-memory compressed swap area. It is not suitable for hibernation. This means that hibernation does not work out-of-the-box on Fedora Linux. This guide describes how to create a swap file to enable hibernation.
Limitations
This method only works on UEFI!
To check that the system uses UEFI:
bootctl
If this commands prints “Not booted with EFI”, then the method described below won’t work. Refer to the original Hibernation in Fedora Workstation (for Fedora Linux 36) instead.
Another severe limitation is that SecureBoot must be disabled. The kernel does not allow hibernation with SecureBoot! Disabling SecureBoot reduces the security of the machine somewhat. Thus, do this only if you think that hibernation is more worth it.
Implementation
First, check whether Secure Boot is on:
bootctl
If this prints “Secure Boot: disabled” then SB is off. Otherwise, reboot the machine, go into UEFI settings, and disable Secure Boot.
Second, create and enable a swap file:
SWAPSIZE=$(free | awk '/Mem/ {x=$2/1024/1024; printf "%.0fG", (x<2 ? 2*x : x<8 ? 1.5*x : x) }') sudo btrfs subvolume create /var/swap sudo mkswap --file -L SWAPFILE --size $SWAPSIZE /var/swap/swapfile sudo bash -c 'echo /var/swap/swapfile none swap defaults 0 0 >>/etc/fstab' sudo swapon -av
This should print a message that swap was enabled on /var/swap/swapfile. The swap file is added to fstab, so it’ll be permanently active. This is a good thing, it should make the system more reliable in general.
Now we are ready to test hibernation:
systemctl hibernate
After the system has shut down, boot it again and let one of the kernels start. The machine should return to the previous state from before hibernation.
This method does not require further configuration because systemd automatically stores the location of the swap file before entering hibernation in an UEFI variable, and then after the reboot, reads that variable and instruct the kernel to resume from this location. This only works on UEFI systems, but is otherwise quite simple and robust.
Reverting the changes
sudo swapoff -v /var/swap/swapfile sudo sed -r -i '/.var.swap.swapfile/d' /etc/fstab sudo btrfs subvolume rm /var/swap
After that, reenable SecureBoot if appropriate.
Troubleshooting
This process mail fail in two ways:
- either going into hibernation fails, i.e. the kernel does not save the state and the machine does not actually power off,
- or loading of saved state fails, and we end up with a fresh boot.
In both cases, the first step is to look at journalctl -b, in particular any error lines.
Lorenzo
Creating a swapfile on a BTRFS filesystem could increase IO operations a lot due to copy-on-write, couldn’t it?
Or is COW somehow disabled for swap files?
Patrick O'Callaghan
COW needs to be disabled for swapfiles. Not sure if this happens automatically. However you can certainly have a swapfile and zram, and give the zram higher priority so the swapfile is normally not used except for hibernation.
Tometzky
Actually it seems that Fedora 41 after recent updates started to work also when Secure boot is enabled. At least on my new laptop with encrypted swap partition and zram disabled with “touch /etc/systemd/zram-generator.conf”:
$ cat /proc/meminfo | grep -E ‘^(MemTotal|SwapTotal)’
MemTotal: 32104280 kB
SwapTotal: 41943036 kB
$ cat /etc/fstab | grep swap | cut -d’ ‘ -f 1
UUID=4ec0c9b4-de29-4828-8287-97252f489ab8
$ readlink -f /dev/disk/by-uuid/4ec0c9b4-de29-4828-8287-97252f489ab8
/dev/dm-1
$ lsblk /dev/dm-1
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
luks-fddfcbb6-24e8-4c20-8745-4e66bd335dda 253:1 0 40G 0 crypt [SWAP]
$ sudo bootctl 2>/dev/null | grep -i ‘Secure Boot’
Secure Boot: enabled (user)
So you don’t need to risk disabling secure boot just to use hibernate. Just using sleep can drain the laptop battery and risk overheating a laptop is some event wakes it while closed or stored in a bag for commuting.
Especially that some security conscious companies require Secure Boot.
Patrick O'Callaghan
I used to have to jump through hoops to get hibernation to work on BTRFS, including calculating a physical disk offset and editing it into the boot command line. See for example https://btrfs.readthedocs.io/en/latest/Swapfile.html
This is a welcome simplification.
Is it still necessary to mark the swapfile as NODATACOW, or is this now automatic? Also, AFAIK the subvolume containing the swapfile cannot be snapshotted.
darthVoid
Hello,
Nice article, however you can’t use a CoW file for swap :
swapon: /var/swap/swapfile: found signature [pagesize=4096, signature=swap]
swapon: /var/swap/swapfile: pagesize=4096, swapsize=33285996544, devsize=33285996544
swapon /var/swap/swapfile
swapon: /var/swap/swapfile: swapon failed: Invalid argument
[46666.195078] BTRFS warning (device nvme0n1p3): swapfile must not be copy-on-write
Maybe chaning the attirube on the file with
could help…
Zbigniew Jędrzejewski-Szmek
I didn’t see this issue on my system. I’ll need to figure out the details here and possibly update the article.
BR Web
I had the exact same error on a fresh Fedora Workstation 41 installation
Matthew
Easier to set chattr +C on /var/swap before creating /var/swap/swapfile
darthVoid
One more thing :
This is wrong :
You have to do :
Delete subvolume 406 (no-commit): '/var/swap'
Arvid
Pandas do NOT hibernate ^^
Kevin
Does the zram swap have to be disabled somehow too?
Patrick O'Callaghan
You can create hooks to disable zram when hibernating and turn it back on when waking. e.g.:
$ cat /etc/systemd/system/hibernate-preparation.service
[Unit]
Description=Enable swap file and disable zram before hibernate
Before=systemd-hibernate.service
[Service]
SyslogIdentifier=%N
User=root
Type=oneshot
ExecStartPre=/bin/bash -c ‘ \
swapon -a; \
swapoff /dev/zram0; \
exit 0; \
‘
ExecStart=/bin/true
[Install]
WantedBy=systemd-hibernate.service
$ cat /etc/systemd/system/hibernate-preparation.service
[Unit]
Description=Enable swap file and disable zram before hibernate
Before=systemd-hibernate.service
[Service]
SyslogIdentifier=%N
User=root
Type=oneshot
ExecStartPre=/bin/bash -c ‘ \
swapon -a; \
swapoff /dev/zram0; \
exit 0; \
‘
ExecStart=/bin/true
[Install]
WantedBy=systemd-hibernate.service
$ cat /etc/systemd/system/hibernate-resume.service
[Unit]
Description=Enable zram swap after resuming from hibernation
After=hibernate.target
[Service]
SyslogIdentifier=%N
User=root
Type=oneshot
ExecStart=/bin/bash -c ‘ \
if ! swapon –show=NAME –noheadings | grep -q /dev/zram0; then \
swapon /dev/zram0; \
fi; \
exit 0; \
‘
[Install]
WantedBy=hibernate.target
Zbigniew Jędrzejewski-Szmek
No, zram swap is not a problem in any way. (When looking for a candidate device to use for hibernation, systemd will skip zram and zswap devices. And the in-memory compressed pages are just like any kind of memory. They’ll be written to the swap area and then restored.)
Patrick O'Callaghan
I’m pretty sure that when I tried this (back in the F36 days) it definitely was a problem. I got error messages about zram not being permanent storage, i.e. it was trying to use zram for hibernation even when a disk-based swapfile was enabled. That’s why I added hooks to disable it when hibernating and enable it again when resuming. However it’s possible that this is no longer necessary.
BR Web
Is there an equivalent guide to enable hibernation in Fedora Silverblue?
BR Web
I tried with Fedora Workstation and got an error after the last command:
swapon: /var/swap/swapfile: swapon failed: Invalid argument
BR Web
Due to the previous error I mentioned, I tried using a SWAP partition instead, the system will hibernate once, then if I try to hibernate again, it will not, it will try but automatically come back on, I don’t think this is related to having used a SWAP partition?
Rich
Any reason why
is used instead of
?