Swap
In the Linux/Unix world, the term swap is generally used as a synonym for memory paging. Swap refers to both the act of moving memory pages between memory and a secondary storage.
Linux can use a combination of swap areas - multiple swap devices and/or swap files together. It is also possible to assign different priorities to swap areas.
However, swap space may not be necessary at all depending on the requirements for the system in question. For example, a laptop that suspends to disk (hibernation) requires all pages in memory to be stored to disk, so swap is necessary in this case. Server systems equipped with large amount of memory running at a constant load might not require swap at all. For further details, see the dedicated Knowledge Base article.
Swap partition
As best practice, the Gentoo Handbook recommends, as part of the installation process, creating a swap partition with a size of twice the available system memory[1].
Swap partitions can be created and activated at any time as long as partitions are available and formatted correctly.
Nowadays, having systems with plenty of memory, it may be sufficient to create a swap partition smaller than the available memory. When using hibernation, storing a compressed RAM image inside the swap partition, it's a good idea having a swap partition with the size of the installed memory.
Creation
Presuming /dev/sda2 is the partition available to be used for swap:
root #
mkswap /dev/sda2 # Format the partition for swap.
root #
swapon /dev/sda2 # Activate the swap partition.
Review the activated swaps with the swapon command:
root #
swapon --show
To avoid manually activating the swap file across reboots, append a line (adjusting the path as necessary) to fstab:
/dev/sda2 none swap sw 0 0
Encrypted swap with hibernate option
Assuming the desired goal is a LUKS encrypted swap partition with the ability to still be able to perform hibernate (a.k.a. suspend to disk). The encrypted swap partition needs a known LUKS-key (keyfile, password, etc.). The user will be asked to enter the password from a very early phase of the boot process. The kernel then has to decide whether to regularly boot the system or to load a hibernated RAM image from SWAP – if if the system was hibernated in the previously power state.
The creation of a LUKS encrypted swap partition is not different to any other LUKS encrypted partition, described in creating an encrypted storage platform. Use mkswap instead of mkfs.* to the LUKS encrypted partition to create SWAP. The UUID (i.e. 01b37ea8-74a5-4526-85c7-9fdf6dad34cb
), created when formatting as swap, is needed for the next step:
Tell the bootloader (GRUB) where to resume from if hibernated:
GRUB_CMDLINE_LINUX_DEFAULT="resume=UUID=01b37ea8-74a5-4526-85c7-9fdf6dad34cb"
In addition (when using OpenRC with dracut, systemd is presumed to be now used for this section of the guide) dracut will need to be told the major and minor number of the associated LUKS device, so it can create an appropriate initrd:
root #
lsblk
.. └─sdb1 8:22 0 32G 0 part └─luks-cc166689-4246-41ae-86e8-84705b81ecc2 253:1 0 32G 0 crypt [SWAP]
root #
echo 253:1 > /sys/power/resume
The default value is
0:0
. echo this in again to deactivate hibernation.Ensure LUKS UUID (
cc166689-4246-41ae-86e8-84705b81ecc2
) and the SWAP UUID (01b37ea8-74a5-4526-85c7-9fdf6dad34cb
) are not confused!Finally, the initrd needs to be updated with this changes:
root #
dracut --hostonly --force
Do not forget the regular configuration of SWAP in /etc/fstab and restart the system afterwards.
# /dev/sdb1 (SWAP)
UUID=01b37ea8-74a5-4526-85c7-9fdf6dad34cb none swap sw 0 0
If a LUKS encrypted SWAP using dmcrypt is already setup by including a configuration in /etc/conf.d/dmcrypt, it will be obsolete, since this LUKS device will now be opened earlier with the help of the dracut generated initrd.
Using full disk encryption
When already using full disk encryption with LUKS, a decryption password prompt will appear twice when booting; once to enter the LUKS-key for the system's root partition (as before) and once to decrypt the SWAP partition. It is possible to just decrypt the root partition and then use a LUKS keyfile, stored on the just now decrypted root partition, to decrypt the SWAP partition automatically. Details and an easy example how to do this within /etc/default/grub, can be found on kernel.org.
Swap files
In order to work around the more ridged constraints of disk partitions, an alternative is to use swap as an on-disk file. Files have the ability to be located inside disk partitions. This allows the system administrator the flexibility to resize or move the swap space as necessary to meet the demands of the system without having to open a partitioning tool.
Creation
Begin by allocating a new file used for the backing store of the swapfile, the size of this file will be the size of the swap space. Standard utilities can be used for this purpose such as fallocate from sys-apps/util-linux:
root #
fallocate -l 12GiB swapfile # Create the file.
root #
chmod 600 swapfile # Restrict security on the file to root access only.
If the partition the swapfile is located on is using btrfs, swapon will fail unless the swap file is in its own subvolume and copy-on-write and compression are disabled for the swapfile[2]. Assuming a 4GB swap file, the steps would be as follows:
root #
btrfs subvolume create swap_vol
root #
chattr +C swap_vol
root #
fallocate -l 4G swap_vol/swapfile
root #
chmod 600 swap_vol/swapfile
Now initialize and turn the swapfile on:
root #
mkswap swapfile # Format the file swap.
root #
swapon swapfile # Activate the swap file.
It's also possible to review the system swaps with the swapon command:
root #
swapon --show
To avoid manually activating the swap file across reboots, append a line (adjusting the path as necessary) to fstab:
/swapfile none swap sw 0 0
Encrypted swap file
It is best practice to encrypt swap files.
Creation
To create a 2 GiB encrypted swap file in the /opt directory, run:
root #
cd /opt
root #
fallocate -l 2GiB swapfile
root #
chmod 600 swapfile
root #
cryptsetup --type plain -d /dev/urandom open swapfile cryptswap
root #
mkswap /dev/mapper/cryptswap
root #
swapon /dev/mapper/cryptswap
root #
swapon --show
/dev/mapper/cryptswap none swap sw 0 0
Activation (systemd)
Make sure systemd is compiled with cryptsetup support, otherwise /etc/crypttab will not be read.
cryptswap /opt/swapfile /dev/urandom swap
Activation (OpenRC)
The OpenRC dm-crypt daemon uses the
aes-cbc-plain
cipher by default, which is vulnerable [3] . Therefore, the options
must be specified to use the aes-cbc-essiv
cipher instead.
Use this command to check which cipher is being used:
root #
dmsetup table cryptswap
swap=cryptswap
source=/opt/swapfile
options='--type plain --key-file /dev/urandom'
Enable the dmcrypt service:
root #
rc-update add dmcrypt boot
If the dm-crypt daemon fails to create the swap at boot, for example, with the following error:
mkswap: unable to erase bootbits sectors
the swap can be created manually. Disable the dm-crypt daemon and revert the changes made to /etc/fstab and /etc/conf.d/dmcrypt. Create the /etc/local.d files:
cryptsetup --type plain -d /dev/urandom open /opt/swapfile cryptswap
mkswap /dev/mapper/cryptswap
swapon /dev/mapper/cryptswap
swapoff /dev/mapper/cryptswap
cryptsetup close cryptswap
And make the scripts executable:
root #
chmod +x /etc/local.d/swap.start
root #
chmod +x /etc/local.d/swap.stop
The swap will be created after a reboot.
OpenRC configuration
When using swap files which are not on the root filesystem, the service ordering in OpenRC should be changed via /etc/conf.d/swap:
# If you are only using local swap partitions, you should not change
# this file. Otherwise, you need to uncomment the below rc_before line
# followed by the appropriate rc_need line.
rc_before="!localmount"
#
# If you are using swap files stored on local file systems, uncomment
# this line.
rc_need="localmount"
#
# If you are using swap files stored on network file systems or swap
# partitions stored on network block devices such as iSCSI, uncomment
# this line.
#rc_need="netmount"
Performance tuning
Prioritization
It is possible to prioritize different swap areas by assigning priority (an integer from 0 to 32767). Higher-priority swap areas are used first. Lower-priority areas are used after exhausting the higher ones. Areas having the same priority are used in a round-robin fashion[4].
The priority can be used for systems using a combination of fast (ZRAM or NVMe-based devices) and slow swap areas (HDD-based devices) to prioritize the former before the latter ones.
For example, prioritizing a fast swap device /dev/nvme0n1 before a regular swap file /swapfile using /etc/fstab:
/dev/nvme0n1 none swap sw,pri=16383 0 0
/swapfile none swap sw,pri=1 0 0
Swappiness
Kernel allows tuning of the swap usage via sysctl parameters allowing to adapt the swapping for various workloads.
The vm.swappiness parameter controls the ratio between kernel willingness to reclaim file-backed ("memory cached" parts files) and anonymous memory pages (application heap and stack) back to their respective backing storage. The value range on recent kernels is 0-200, while the default is 60[5]. Values lower than the default represent a preference of keeping the application-related anonymous memory pages in memory at the expense of file-backed pages and vice versa.
The current value can be displayed by:
user $
sysctl vm.swappiness
vm.swappiness = 60
The desired swappiness value can be persistently set via:
vm.swappiness=20
See also
- Filesystem — a means to organize data to be retained after a program terminates.
- Zram — a Linux kernel feature and userspace tools for creating compressible RAM-based block devices.
- Zswap — a lightweight compressed cache for swap pages.
External resources
References
- ↑ Handbook:AMD64/Installation/Disks#What_about_swap_space.3F
- ↑ https://btrfs.readthedocs.io/en/latest/Swapfile.html
- ↑ https://gitlab.com/cryptsetup/cryptsetup/-/blob/main/FAQ.md
- ↑ swapon(2) - Linux man page, die.net. Retrieved on: October 23, 2022
- ↑ Documentation for /proc/sys/vm/ — The Linux Kernel documentation, kernel.org. Retrieved on October 23, 2022