Update on hibernation in Fedora Workstation

Photo by Ruiqi Kong on Unsplash (cropped)

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.

FAQs and Guides For System Administrators

18 Comments

  1. 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.

  2. 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.

  3. 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.

  4. darthVoid

    Hello,

    Nice article, however you can’t use a CoW file for swap :

    swapon -av
    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

    chattr +C /var/swap/swapfile

    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.

    • Easier to set chattr +C on /var/swap before creating /var/swap/swapfile

  5. darthVoid

    One more thing :

    This is wrong :

    btrfs subvolume rm /var/swap

    You have to do :

    btrfs subvolume delete /var/swap

    Delete subvolume 406 (no-commit): '/var/swap'
  6. Arvid

    Pandas do NOT hibernate ^^

  7. 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.

  8. BR Web

    Is there an equivalent guide to enable hibernation in Fedora Silverblue?

  9. BR Web

    I tried with Fedora Workstation and got an error after the last command:

    swapon: /var/swap/swapfile: swapon failed: Invalid argument

  10. 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?

  11. Rich

    Any reason why

    mkswap

    is used instead of

    btrfs filesystem mkswapfile

    ?

Leave a Reply


The interval between posting a comment and its appearance will be irregular so please DO NOT resend the same post repeatedly. All comments are moderated but this site is not monitored continuously so comments will not appear as soon as posted.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

The opinions expressed on this website are those of each author, not of the author's employer or of Red Hat. Fedora Magazine aspires to publish all content under a Creative Commons license but may not be able to do so in all cases. You are responsible for ensuring that you have the necessary permission to reuse any work on this site. The Fedora logo is a trademark of Red Hat, Inc. Terms and Conditions