5

I'm using btrfs encrypted by LUKS on fedora 32 silverblue, kernel version 5.7.7 with anaconda installer default setting.

Because fedora installer automatic partition does not add swap partition or file (or I've done wrong), I added swapfile on myself for hibernation like this:

$ # swapfile under /var directory because the location is the only part user can modify on fedora silverblue
$ touch /var/swapfile
$ chattr +C /var/swapfile 
$ fallocate --length 10GiB /var/swapfile
$ sudo chown root /var/swapfile 
$ sudo chmod 600 /var/swapfile 
$ sudo mkswap /var/swapfile 
$ sudo swapon /var/swapfile

and I added swapfile_t attr for selinux:

$ ls -Z /var/swapfile
unconfined_u:object_r:swapfile_t:s0 /var/swapfile

Then I followed arch wiki instruction(https://wiki.archlinux.org/index.php/Power_management/Suspend_and_hibernate#Hibernation_into_swap_file_on_Btrfs).

my /var/swapfile's physical offset is 19793240064 and page size is 4096, so I added kernel param with grub. here's part of my /etc/default/grub kernel params now:

GRUB_CMDLINE_LINUX="rd.luks.uuid=luks-572bfd87-6fa7-4be1-8c73-4759ac9af3cd rhgb quiet resume=UUID=572bfd87-6fa7-4be1-8c73-4759ac9af3cd resume_offset=4832334"

here's my blkid:

$ sudo blkid
/dev/nvme0n1p1: UUID="5490-E733" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="46ecd0d1-6722-4b92-af73-9574a58eb332"
/dev/nvme0n1p2: UUID="c9294f4d-9c92-4c08-a037-715223443f2b" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="731852d5-26cd-43bb-8904-c4256247f97d"
/dev/nvme0n1p3: UUID="572bfd87-6fa7-4be1-8c73-4759ac9af3cd" TYPE="crypto_LUKS" PARTUUID="e74de89a-fe5f-402f-a3bf-e398ad069b5b"
/dev/sda: BLOCK_SIZE="512" UUID="C602B4D602B4CD25" TYPE="ntfs"
/dev/mapper/luks-572bfd87-6fa7-4be1-8c73-4759ac9af3cd: LABEL="fedora_fedora" UUID="337b2fcb-a61b-4976-89ac-2b3feee02963" UUID_SUB="932cfe1c-9713-4063-bda0-a8a792654c39" BLOCK_SIZE="4096" TYPE="btrfs"

and hibernation failed. it seems resume parameter problem. I tried UUID=572bfd87-6fa7-4be1-8c73-4759ac9af3cd and UUID=337b2fcb-a61b-4976-89ac-2b3feee02963 and both failed. What were wrong? How can I setup swapfile hibernate properly?

I've checked journalctl -u systemd-logind and found the message but that didn't help:

...
 localhost.localdomain systemd-logind[936]: Failed to open swap file /var/swapfile to determine on-disk offset: Permission denied
...
14
  • Fedora has changed to zram long time ago so it doesn't need to create a swap file. See Hibernation without swap enabled
    – phuclv
    Aug 31, 2020 at 9:29
  • @phuclv using zram for swap is not useful for hibernation; to hibernate the swap contents must be persisted when power is removed. Sep 21, 2020 at 19:25
  • I am having a similar problem on manjaro and have not posted a question as this question is very similar but unfortunately has no answers (usable or otherwise). Sep 21, 2020 at 19:26
  • @RidiculousRichard did you even read the linked question above? You can use zswap which uses a real swap file/partition, or just add another swap file/partition with lower priority, or create a systemd service to handle the hibernation
    – phuclv
    Sep 22, 2020 at 1:24
  • Many articles on the subject with various variants. Check these more likely ones: link1, link2, link3, link4, link5. Perhaps one of them will supply the missing ingredient.
    – harrymc
    Sep 22, 2020 at 8:05

2 Answers 2

5

The following steps enable hibernate to swap-file on Fedora Silverblue 33, with a btrfs filesystem, possibly encrypted with LUKS. Unfortunately it's not very straight forward, but it works.

Note that secure boot must be disabled for hibernation to work. Check in the BIOS settings that it's disabled.

For more background information and on why hibernation is not available out of the box, see this old Fedora Workstation wiki page.

  1. Create and configure a swap-file the same size as the system memory.
sudo touch /var/swapfile
sudo chattr +C /var/swapfile
sudo fallocate --length "$(grep MemTotal /proc/meminfo | awk '{print $2 * 1024}')" /var/swapfile
sudo chmod 600 /var/swapfile
sudo mkswap /var/swapfile
sudo swapon /var/swapfile
echo '/var/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
  1. Set the resume kernel parameters.
    First we need to calculate the offset of the swap-file. The following command is using the btrfs_map_physical.c program as described in the Arch Linux wiki page on power management.
sudo podman run --rm -it --privileged -v /var/swapfile:/var/swapfile -v /tmp:/tmp debian:stable sh -c '
  apt-get update &&
  apt-get install -qy gcc wget &&
  wget "https://raw.githubusercontent.com/osandov/osandov-linux/61679ecd914d653bab14d0e752595e86b9f50513/scripts/btrfs_map_physical.c" &&
  gcc -O2 -o btrfs_map_physical btrfs_map_physical.c &&
  ./btrfs_map_physical /var/swapfile | sed -n "2p" | awk "{print \$NF}" >/tmp/swap_physical_offset
  '
SWAP_PHYSICAL_OFFSET=$(cat /tmp/swap_physical_offset)
SWAP_OFFSET=$(echo "${SWAP_PHYSICAL_OFFSET} / $(getconf PAGESIZE)" | bc)

Then we build the actual kernel parameters and print them to the screen.

SWAP_UUID=$(findmnt -no UUID -T /var/swapfile)
RESUME_ARGS="resume=UUID=${SWAP_UUID} resume_offset=${SWAP_OFFSET}"
echo "${RESUME_ARGS}"

⚠ Make sure the output looks similar to this, just with a different UUID and offset:

resume=UUID=3d2b6777-0114-4a9d-8b98-e279e7e09cda resume_offset=7753110

If the output looks correct, set the kernel parameters with grubby:

sudo grubby --update-kernel=ALL --args="${RESUME_ARGS}"
  1. Disable systemd swap space check.
    To avoid false positive systemd errors about the swap size, if there's already an existing swap target (e.g. the default zram device).
sudo mkdir -p /etc/systemd/system/systemd-logind.service.d/
cat <<-EOF | sudo tee /etc/systemd/system/systemd-logind.service.d/override.conf
[Service]
Environment=SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1
EOF
sudo mkdir -p /etc/systemd/system/systemd-hibernate.service.d/
cat <<-EOF | sudo tee /etc/systemd/system/systemd-hibernate.service.d/override.conf
[Service]
Environment=SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1
EOF
  1. SELinux: allow systemd to access the swap-file.
    This is a workaround for missing rules in Fedora's "selinux-policy" (see 1 and 2), and should be fixed in the future version 3.14.7.
cd "$(mktemp -dt)"
cat <<-EOF | tee systemd_swapfile.te
module systemd_swapfile 1.0;

require {
    type init_t;
    type swapfile_t;
    class file { open getattr read ioctl lock };
}

allow init_t swapfile_t:file { open getattr read ioctl lock };
EOF
checkmodule -M -m -o systemd_swapfile.mod systemd_swapfile.te
semodule_package -o systemd_swapfile.pp -m systemd_swapfile.mod
sudo semodule -i systemd_swapfile.pp
cd -
  1. Reboot and test hibernate.
    First reboot to apply all settings:
systemctl reboot

Then try to hibernate:

systemctl hibernate
5
  • works perfectly! Tested on Fedora 33 KDE Spin, I executed sudo grub2-mkconfig -o /boot/grub2/grub.cfg because I did not executed grubby but modified manually /etc/default/grub
    – Thomas8
    Feb 7, 2021 at 13:11
  • for me, with the above instructions, resume from hibernation yields in a black screen.
    – user8162
    Jul 1, 2021 at 19:25
  • @user8162 you're running Fedora Silverblue? What version? Problems about hibernation are usually logged to the journal, e.g. check the log from the last boot: journalctl --boot=-1
    – njam
    Jul 12, 2021 at 18:59
  • The link to the wiki is dead. Jun 23, 2023 at 14:34
  • @artfulrobot thx, updated.
    – njam
    Jun 24, 2023 at 21:25
2
+50

The missing step for the poster was finding the the UUID of the partition containing the swapfile, when required to select the partition that the swap-file resides on. This can be retrieved using the findmnt command:

sudo findmnt -no SOURCE,UUID -T /path/to/swapfile

There are various methods published for hibernating on a swapfile, each valid in its intended environment. Below are some references, but you will find more in the comments above on the post:

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .