[HowTo] Configure hibernation with a swap file

Introduction

A swap file is a popular alternative to dedicated swap partitions.

But using a swap file requires extra steps to enable hibernation.

For quick-install steps skip to this section.


Required HOOKS in mkinitcpio.conf

Either the resume or systemd hook is required for hibernation.
The resume hook will be used here, and should be placed after filesystems.

Instructions

Use either of the following methods.

Edit main configuration file `/etc/mkinitcpio.conf`

To edit the HOOKS lines of /etc/mkinitcpio.conf you will need elevated privileges.

Execute:

sudoedit /etc/mkinitcpio.conf

If you have not set SUDO_EDITOR then you can define the variable with your favorite editor.

Execute:

SUDO_EDITOR=/usr/bin/micro sudoedit /etc/mkinitcpio.conf

Using the standard HOOKS at time of writing and including resume then it would appear as:

HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block filesystems resume fsck)

Save and close the file.

OR

Create drop-in configuration file in `/etc/mkinitcpio.conf.d/`

To use a drop-in configuration file first ensure the directory exists and then create the file with a .conf extension. Then copy the relevant lines from the original /etc/mkinitcpio.conf and edit as needed.

This bash command will accomplish all of those, and add resume to HOOKS.

Execute:

sudo mkdir -p /etc/mkinitcpio.conf.d && grep -E '^MODULES|^BINARIES|^FILES|^HOOKS' /etc/mkinitcpio.conf | sed 's/filesystems/& resume/' | sudo tee /etc/mkinitcpio.conf.d/custom.conf

After setting the required HOOKS you will need to rebuild the initramfs.

Rebuild initramfs

Execute:

sudo mkinitcpio -P

Kernel Boot options

:information_source: Beginning with mkinitcpio v38 and systemd v255 UEFI systems do not require extra boot options. The following section is retained for Traditional-BIOS systems and posterity. :information_source:

The resume=$DEVICE parameter is required for hibernation. When using a swap file the device on which the file resides should be used. In addition, swap files used for resume also require a special second option in the form of resume_offset=$OFFSET.

Instructions

Find $DEVICE UUID and swap file offset

Instructions

The most reliable address for a device is the UUID.
To find the UUID of your devices/partitions you may use a command such as blkid.
When setting resume=$DEVICE using a UUID the option should appear as resume=UUID=$UUID.
And when using a swap file the UUID of the device or partition containing the swap file should be used.

Find UUID

Here we will assume it is on the same root / device.

Execute:

findmnt / -o UUID
Find offset

For btrfs:

sudo btrfs inspect-internal map-swapfile -r /swapfile

For all other filesystems:
Execute:

sudo filefrag -v /swapfile | awk '$1=="0:" {print substr($4, 1, length($4)-2)}'

Add the boot options

Instructions

Use either of the following methods.

Edit main configuration file `/etc/default/grub`

To edit the CMDLINE lines of /etc/default/grub you will need elevated privileges.

Execute:

sudoedit /etc/default/grub

If you have not set SUDO_EDITOR then you can define the variable with your favorite editor.

Execute:

SUDO_EDITOR=/usr/bin/micro sudoedit /etc/default/grub

Assuming no other options then it would appear as:

GRUB_CMDLINE_LINUX="resume=UUID=$UUID resume_offset=$OFFSET"

(with $UUID and $OFFSET replaced by the actual values found in the previous sections)

Save and close the file.

OR

Create drop-in configuration file `/etc/default/grub.d/hibernation.cfg`

Execute:

_UUID=$(findmnt / -o UUID -n); _OFFSET=$(sudo filefrag -v /swapfile | awk '$1=="0:" {print substr($4, 1, length($4)-2)}'); sudo mkdir -p /etc/default/grub.d; printf 'GRUB_CMDLINE_LINUX+=" resume=UUID=%s'"$_UUID"" resume_offset=%s""$_OFFSET"'"\n' | sudo tee /etc/default/grub.d/hibernation.cfg

Update Grub

After rebuilding intramfs or after adding boot options, or both, grub needs to be updated.

Instructions

Execute:

sudo update-grub

OR:

sudo grub-mkconfig -o /boot/grub/grub.cfg

Quick Install Instructions

For a few bash commands to add the resume hook (and optionally boot options) use these.

Click to show

Traditional BIOS systems require boot options.

Click to show.

For btrfs:

printf '\nCreating and editing /etc/default/grub.d/hibernation.cfg.\n\n'; _UUID=$(findmnt / -o UUID -n); _OFFSET=$(sudo btrfs inspect-internal map-swapfile -r /swapfile); sudo mkdir -p /etc/default/grub.d; printf 'GRUB_CMDLINE_LINUX+=" resume=UUID=%s'"$_UUID"" resume_offset=%s""$_OFFSET"'"\n' | sudo tee /etc/default/grub.d/hibernation.cfg; printf '\nDone.\n\n'

For all other filesystems:

printf '\nCreating and editing /etc/default/grub.d/hibernation.cfg.\n\n'; _UUID=$(findmnt / -o UUID -n); _OFFSET=$(sudo filefrag -v /swapfile | awk '$1=="0:" {print substr($4, 1, length($4)-2)}'); sudo mkdir -p /etc/default/grub.d; printf 'GRUB_CMDLINE_LINUX+=" resume=UUID=%s'"$_UUID"" resume_offset=%s""$_OFFSET"'"\n' | sudo tee /etc/default/grub.d/hibernation.cfg; printf '\nDone.\n\n'

After adding the kernel boot options continue with the following section on HOOKS.

Up-to-date UEFI systems only require the resume or systemd HOOKS.

Execute:

printf '\nCreating and editing /etc/mkinitcpio.conf.d/custom.conf.\n\n'; sudo mkdir -p /etc/mkinitcpio.conf.d && grep -E '^MODULES|^BINARIES|^FILES|^HOOKS' /etc/mkinitcpio.conf | sed 's/filesystems/& resume/' | sudo tee /etc/mkinitcpio.conf.d/custom.conf; printf '\nDone.\n\n'
printf '\nRebuilding initramfs and updating grub.\n\n'; sudo mkinitcpio -P && sudo grub-mkconfig -o /boot/grub/grub.cfg; printf '\nDone.\n\n'

More Information

ArchWiki hibernation page
Power management/Suspend and hibernate - ArchWiki

ArchWiki mkinitcpio page
mkinitcpio - ArchWiki

2 Likes