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.
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 chattr +C /var/swap
sudo restorecon /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
sudo bash -c 'echo add_dracutmodules+=\" resume \" > /etc/dracut.conf.d/resume.conf'
sudo dracut -f
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 delete /var/swap
sudo rm /etc/dracut.conf.d/resume.conf
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.
Pramod
You need to put swapfile on a separate subvolume, [/var/swap could be the subvol, but better to create it outside the @ root subvolume and mount it], and create the swapfile with
after
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.
Zbigniew Jędrzejewski-Szmek
Indeed, hibernation works with SecureBoot enabled. It turns out I had some unrelated selinux AVC which prevented from hibernation from being attempted, and didn’t actually verify this. I thought I understand the whole process…
I asked the FedoraManagazine editors to make edits to drop the chunk about SecureBoot and modify the commands to include ‘chattr +C’.
msizanoen
Hibernation working with secure boot enabled is a security bug and will be fixed eventually: https://bugzilla.redhat.com/show_bug.cgi?id=2333706
Ben
Good point. Though I’d put it as: kernel lockdown precludes hibernation. If kernel lockdown is disabled then hibernation+Secure Boot work fine but is less secure due to the plaintext hibernated image being open to tampering.
Hibernation currently requires unencrypted/plaintext swap. A system booted with kernel lockdown enabled (usually the default when Secure Boot is on), will refuse to use unencrypted swap, therefore will not be able to hibernate.
As noted in the other comments, UEFI Secure Boot and Linux’s kernel lockdown are complementary and largely but not totally independent of each other. Per kernel_lockdown(7), “On an EFI-enabled x86 or arm64 machine, lockdown will be automatically enabled if the system boots in EFI Secure Boot mode.” However this isn’t actually happening for at least my system, presumably due to the RH bug referred to by @msizanoen. tbc, my system currently has kernel lockdown disabled (with or without hibernation set up/plaintext swap).
The real reason why hibernation won’t work when kernel lockdown is enabled is that under lockdown “Unencrypted hibernation/suspend to swap are disallowed” (kernel_lockdown(7)).
So: kernel lockdown refuses to use unencrypted swap, and hibernate requires unencrypted swap. Choose one.
FTR: I have hibernation working with Secure Boot enabled, and lockdown is indeed disabled (kernel 6.12.9-200.fc41.x86_64). The ‘Linux swap: Invalid’ reflects the unencrypted swap; when I swapoff the swap file the warning goes away.
Host Security ID: HSI:4! (v1.9.27)
HSI-1
...
✔ UEFI secure boot: Enabled
...
Runtime Suffix -!
✔ fwupd plugins: Untainted
✔ CET OS Support: Supported
✔ Linux swap: Encrypted
✔ Linux kernel: Untainted
✘ Linux kernel lockdown: Disabled
✘ Linux swap: Invalid
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
?
hpt
[ 3641.479274] BTRFS warning (device dm-1): swapfile must be on one device
I hit this issue. What shall I do, please? Thanks!
Hugh
It would be great to have a sleep mode that switches to hibernate after a certain amount of time or battery use.
I often “sleep” a notebook and then leave it for longer than I intended.
Serg
You need:
systemctl suspend-then-hibernate
BR Web
I was able to execute all steps successfully using the chattr +C /var/swap as well, then when I tried to execute sudo systemctl hibernate I get the following message:
“Call to Hibernate failed: Access denied”
I followed the exact steps plus the suggested update on a fresh Fedora Workstation 41 installation, what am I doing wrong, please help, thank you
Gregory Bartholomew
Sorry BR Web, it seems this procedure was not adequately tested. The author has requested revisions/corrections and I am attempting to make them now.
Edit: The revisions have been made. Please try again.
gb
BR Web
Unfortunately the updated version doesn’t work either on my device, it will hibernate once, then it will never hibernate again, also, after resuming from the first hibernation Bluetooth will. be dead, not very reliable with my device
Gregory Bartholomew
Devices not resuming properly after hibernation is a known problem on Linux. I think that is why it is not enabled by default. Things might be improving a little, depending on your hardware, but it is an area that is in-development and about the only way to know if it will work for some particular hardware is to try it and see. Personally, I prefer to shutdown my PC when I’m not using it. IMO, having to periodically save all my work is not at all a bad thing.
Ben
The info in this article was not quite correct for my “new” Fedora 41 install on a Lenovo ThinkPad T14 Gen 5 (AMD), with Secure Boot enabled. However it pointed me in the right direction.
Three things need to be done:
1. create a swap file
2. update dracut to add resume support (uncertain if this is required but it didn’t hurt)
3. update SELinux policy to properly tag the swapfile
– if you don’t do this, you’ll get a “Call to Hibernate failed: Access denied” error when invoking
Here’s what I did:
SWAPFILE=/var/swap/swapfile
sudo btrfs subvolume create /var/swap
sudo btrfs filesystem mkswapfile --size $SWAPSIZE --uuid clear $SWAPFILE
echo $SWAPFILE none swap defaults 0 0 | sudo tee --append /etc/fstab
sudo swapon --all --verbose
# https://wiki.archlinux.org/title/Dracut#Hibernation
echo 'add_dracutmodules+=" resume "' | sudo tee /etc/dracut.conf.d/resume.conf
sudo dracut --force
sudo semanage fcontext --add --type swapfile_t $SWAPFILE
sudo restorecon -RF /var/swap
Unfortunately after all that, the T14’s wifi ath11k_pci driver has a fatal bug that was fixed ca. 2023 but reverted in August 2024 and remains open:
https://bugzilla.kernel.org/show_bug.cgi?id=214649
Gregory Bartholomew
FWIW, sometimes the problems with PCI devices resuming from hibernate can be mitigated: https://fedoramagazine.org/use-sysfs-to-restart-failed-pci-devices/
Ben
Thanks for the pointer re. restarting PCI devices: alas in my instance attempting the PCI
after a hibernation caused a kernel panic ;-(. So I guess I’ll await the kernel fix for the underlying problem.
Matthew
This coupled with changing /etc/systemd/logind.conf so that the lid action does suspend-then-hibernate has finally got my linux where I want it. I don’t know why Linux distros have decided they dislike suspend-then-hibernate, but I love it. I’d much rather my machine save to disk and come back to life with more battery than anything else.
Berend
I tried this on Fedora KDE yesterday and got got access denied as well.
bootctl gives me ” systemd-boot not installed in ESP.”
tried a bunch of extra things and got locked out of KDE, so i will wait for a beter solution.
Would be awsome to get this to work. my laptop drains fast while in suspend mode.