Linux swap over loopback devices
Some Linux filesystems do not natively support swapfiles as they do not implement the required kernel calls or are unable to do so. Notable amongst this list of filesystem is btrfs, whose snapshot functionality I use to streamline my backup system.
Unfortunately, some systems I maintain have a chronic lack of RAM and require a swapfile to complete some long running operations. As a workaround it is possible to create a loopback device from a file, which one can then pass to the kernel as a swap device.
This option comes with a performance impact, but is functionally identical for our purposes.
To create a swap device we create a swap image, pass it to losetup for device creation, and then enable the swap as follows:
path="/swap"
fallocate --length $((1*1024*1024*1024)) "$path"
mkswap "$path"
dev=$(losetup --find "$path" --show)
swapon "$dev"
To clean up we perform the reverse of the above operations:
swapoff "$dev"
losetup --detach "$dev"
rm "$path"
NOTE: An earlier version of this post used truncate
to create the file. This is quite likely to result in a sparse file which Linux cannot use for swap. fallocate
should allow for efficient allocation given we don’t actually care about the contents, but if you get stuck then dd if=/dev/zero of="$path"
should also work.
I also used an error prone mult-step method to allocate the loopback device. Directly supplying losetup -f
with a path is the correct approach.
Thanks to Antonio Petricca for reporting these issues. My apologies for losing their comments in the blog reshuffle.