28

Modern Ubuntu versions are using a swap file instead of a swap partition by default.

Before the 5.0 Linux kernel it was not possible to place a swap file on a btrfs partition, btrfs file system could be damaged.

Now kernels support swap files on btrfs partitions. Can I use a swap file on Ubuntu installed on btrfs and what are possible problems?

Pilot6
  • 92,041

7 Answers7

34

It is possible to use a swap file on btrfs, but there are some considerations that need taking care of.

btrfs filesystem doesn't let to create snapshots if there is a working swap file on the subvolume. That means that it is highly recommended to place a swap file on a separate subvolume.

Let's assume that the current swap is already off, the / is on /dev/sda1 and Ubuntu is installed with / on @ subvolume and /home is on @home subvolume.

  1. Mount /dev/sda1 to /mnt.

    sudo mount /dev/sda1 /mnt
    

    If you run ls /mnt, you'll see @, @home and other subvolumes that may be there.

  2. Create a new @swap subvolume.

    sudo btrfs sub create /mnt/@swap
    
  3. Unmount /dev/sda1 from /mnt.

    sudo umount /mnt
    
  4. Create /swap directory where we plan to mount the @swap subvolume.

    sudo mkdir /swap
    
  5. Mount the @swap subvolume to /swap.

    sudo mount -o subvol=@swap /dev/sda1 /swap
    
  6. Create the swap file.

    sudo touch /swap/swapfile
    
  7. Set 600 permissions to the file.

    sudo chmod 600 /swap/swapfile
    
  8. Disable COW for this file.

    sudo chattr +C /swap/swapfile
    
  9. Set size of the swap file to 4G as an example.

    sudo dd if=/dev/zero of=/swap/swapfile bs=1M count=4096
    
  10. Format the swapfile.

    sudo mkswap /swap/swapfile
    
  11. Turn the swap file on.

    sudo swapon /swap/swapfile
    

Now the new swap should be working.

You also need to update /etc/fstab to mount all this on boot. Add there two lines:

UUID=XXXXXXXXXXXXXXX /swap btrfs subvol=@swap 0 0
/swap/swapfile none swap sw 0 0

The UUID is the one of your /dev/sda1.

Swap file can't be located on a btrfs raid of any sort.

Comments and suggestions are welcome.

Pilot6
  • 92,041
3

Note that for modern systems/laptops with NVME SSDs, you have /dev/nvme0n1p2 instead of /dev/sda1 and you should ignore /dev/nvme0n1p1 because that is your efi boot disk that your OS created when you installed it.

In addition it should be recommended to add two mount options 'defaults' and 'noatime'. Defaults will automatically load the mount options for the drive (SSD, HDD). Noatime will prevent files being written if only opened:

UUID=XXXXXXXXXXXXXXX /swap btrfs defaults,noatime,subvol=@swap 0 0
/swap/swapfile none swap sw 0 0
zilexa
  • 171
3

If your partition is encrypted (LUKS), the mount point is on /dev/mapper for example:

/dev/mapper/nvme0n1p5_crypt /swap btrfs defaults,noatime,subvol=@swap 0 0
/swap/swapfile none swap sw 0 0 here

To get the uuids run the blkid command:

/dev/mapper/nvme0n1p5_crypt: UUID="06c8c73c-1cc4-477b-a687-6c21697d645d"   UUID_SUB="7f884b26-d76e-49db-9959-311fa2a5dd20" TYPE="btrfs"
/dev/nvme0n1p1: UUID="8090a824-63fa-4087-a948-89cca1a369cd" TYPE="ext2" PARTUUID="887ff27b-01"
/dev/nvme0n1p5: UUID="46405308-2ed1-40f3-a86b-906f1118970b" TYPE="crypto_LUKS" PARTUUID="887ff27b-05"

And then replace the mapper location with the specific uuid

UUID=06c8c73c-1cc4-477b-a687-6c21697d645d /swap btrfs   defaults,noatime,subvol=@swap 0 0 
/swap/swapfile none swap sw 0 0
3

You can have a swap on btrfs, if you take care what the btrfs doku tell about this:

filesystem - must be only single device
filesystem - must have only single data profile
swapfile - the containing subvolume cannot be snapshotted
swapfile - must be preallocated (i.e. no holes)
swapfile - must be NODATACOW (i.e. also NODATASUM, no compression)

For more information see the source:

Alfred.37
  • 159
2

The popular answer is correct except that you should not use fallocate(1) to allocate space to the swapfile. It can create file-system 'holes' which are incompatible with swapfile usage (swap needs 100% contiguous space since a filesystem is not used within the swap space). You should use 'dd if=/dev/zero ...' instead. See the answer on this thread: fallocate vs dd for swapfile? The mkswap(8) and swapon(8) manpages both explicitly discourage the use of fallocate(1) to instantiate a swapfile on the filesystem.

2

The best answer didn't work for me. I got error:

$ sudo swapon -v --show /swap/swapfile

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

for me work solution was from https://btrfs.readthedocs.io/en/latest/btrfs-man5.html#swapfile-support

# cd /swap
# truncate -s 0 swapfile
# chattr +C swapfile
# fallocate -l 2G swapfile
# chmod 0600 swapfile
# mkswap swapfile
# swapon swapfile

/etc/fstab:

/swap/swapfile              none            swap    sw              0       0
Grigory
  • 121
2

Since version 6.1 it’s possible to create the swapfile in a single command.

I will try to test the implications of the following (like should a btrfs swapfile be mounted in a swapfile subvolume so that the snapshots can still be performed on the parent volume?)

Note snapshot is not supported on subvolumes containing swapfiles because the following snapshot requirement

subvolume - cannot be snapshotted if it contains any active swapfiles

Use a default value of 8G but if it's already set then use what was set

btr_swap_size=${btr_swap_size:=8G}
btrfs subvolume create SWAP
btrfs filesystem mkswapfile --size btr_swap_size /SWAP/swapfile
swapon /swapfile

a mini script

btr_swap_size=${btr_swap_size:=8G}
btr_swap_subvolume=${btr_swap_subvolume:="/SWAP"}
btr_swap_file=${btr_swap_subvolume}/SWAP-"${btr_swap_size}".img
swapon -s|grep -q "$btr_swap_file" /etc/fstab
if [ $? -ne 0 ]; then
# if not then create it
    echo '$btr_swap_file not found in fstab. Adding as Swapfile.'
btrfs subvolume create /${btr_swap_subvolume}
btrfs filesystem mkswapfile --size "${btr_swap_size}" "${btr_swap_file}"
swapon "/${btr_swap_file}"
echo "/$btr_swap_file none swap defaults 0 0" >> /etc/fstab

else echo '/$btr_swap_file found. No changes made.' fi

kkron
  • 151