Hello,
I’ve been collecting the steps to using a swap file with BTRFS. Basically, some things have changed recently, so:
-
Apparently the compression attribute is no longer needed: Can't create swap file: swapon failed: Invalid argument - #7 by dalto
-
Does this script still work with a minor adjustment? How to enable Hibernation to Swapfile on BTRFS? - #2 by joekamprad
-
Since the attribute need not be set, does that mean that in fact BTFS now allows you to have a compressed swap file?
So far, I have created a @swap
subvolume and followed the steps in the script manually (set the copy-on-write attribute and allocated 16G on disk which matches my RAM size). I updated my /etc/fstab
to use that and currently htop
confirms that swap is active on the file so I’m happy with that. Out of fear about compression I use comrpess=none
option as follows:
# grep swap /etc/fstab
UUID=10840302-2838-4187-842a-eee8f883ed50 /swap btrfs subvol=/@swap,defaults,noatime,compress=none 0 0
/swap/swapfile none swap defaults 0 0
So I am happy that swap actually works and the first part of the script should recreate my current state.
Now, the last part of the script edits grub to set the resume UUID and the resume offset. It downloads and compiles a small C program which I hope still works (Another question; does it work only when compress=none
or does it also work when you actually allow BTRFS to compress the file?). Here is that part:
# :: btrfs_map_physical :: #
wget https://raw.githubusercontent.com/osandov/osandov-linux/master/scripts/btrfs_map_physical.c
gcc -O2 -o btrfs_map_physical btrfs_map_physical.c
# :: edit grub :: #
offset=$(./btrfs_map_physical /swap/swapfile)
offset_arr=($(echo ${offset}))
offset_pagesize=($(getconf PAGESIZE))
offset=$((offset_arr[25] / offset_pagesize))
btrfsroot=`findmnt / -no UUID`
Running these manually yielded for me:
# echo $btrfsroot
10840302-2838-4187-842a-eee8f883ed50
# echo $offset
7611648
I made a copy of /etc/default/grub
and ran the next commands on that:
sed -i "s#loglevel=3#resume=UUID=$btrfsroot loglevel=3#" /etc/default/grub.copy
sed -i "s/loglevel=3/resume_offset=$offset loglevelbtrfs property set /swap/swapfile compression none=3/" /etc/default/grub.copy
This actually errored out with:
+ sed -i 's/loglevel=3/resume_offset=7611648 loglevelbtrfs property set /swap/swapfile compression none=3/' /etc/default/grub.copy
sed: -e expression #1, char 64: unknown option to `s'
I think I just need to escape the /
character in ‘/swap/swapfile’ as sed
applies it to the s///
command. So I went with;
sed -i "s#loglevel=3#resume=UUID=$btrfsroot loglevel=3#" /etc/default/grub.copy
sed -i "s/loglevel=3/resume_offset=$offset loglevelbtrfs property set \/swap\/swapfile compression none=3/" /etc/default/grub.copy
This yielded:
# diff /etc/default/grub /etc/default/grub.copy
6c6
< GRUB_CMDLINE_LINUX_DEFAULT="quiet resume=UUID=46a0d838-1f5e-4e1b-87c5-914aad2cd98c loglevel=3 nowatchdog nvme_load=YES"
---
> GRUB_CMDLINE_LINUX_DEFAULT="quiet resume=UUID=46a0d838-1f5e-4e1b-87c5-914aad2cd98c resume=UUID=10840302-2838-4187-842a-eee8f883ed50 resume_offset=7611648 loglevelbtrfs property set /swap/swapfile compression none=3 nowatchdog nvme_load=YES"
Now this seems a bit garbled to me. Clearly I need to remove resume=UUID=46a0d838-1f5e-4e1b-87c5-914aad2cd98c
which is the old UUID and go with the second resume entry which is the new one. But loglevelbtrfs property set /swap/swapfile compression none=3
seems like it should be btrfs property set /swap/swapfile compression none loglevel=3
instead?