Running the BTRFS file system with ARM64 kernel on the Raspberry Pi and backup with btrbk
BTRFS is one of the contenders for the successor to EXT4, which has already been around for a few years. Today I will show you how to configure BTRFS on a Raspberry Pi 64 bit system in the kernel and how to create an automated backup solution with btrbk.
Advantages of BTRFS
- Advanced features: BTRFS offers advanced features such as snapshots, dynamic inode allocation, built-in RAID support, and data integrity checks.
- Snapshot and rollback capability: BTRFS allows you to create snapshots of your data, which can be useful for data backup and recovery.
- Bit-red self-healing: BTRFS can detect damaged data and, if configured in a RAID setup, automatically repair it.
- Efficient Copy-on-Write (CoW): This enables efficient backup and cloning processes.
Advantages of btrbk
- btrbk is tailor-made for backups, adept at transferring snapshots to locations like external drives or remote servers, key for off-site backup.
- Advanced Retention Policies: Offers detailed retention settings, allowing customization of snapshot preservation across different time frames (hourly to yearly).
- Automates snapshot creation, transfer, and cleanup based on retention policies, streamlining regular backup operations.
You'll need
- a Raspberry Pi which has already been converted to 64 bit. Please note that Internet solutions that only show how to convert the kernel to 64 bit offer no real advantages because the user space is not converted. A complete conversion requires a new basic installation of all software on your system.
- backup hardware, e.g. a NAS.
- A device for mounting the flash drive.
Before you start
Create a complete backup of your Raspberry Pi, e.g. with dd. There is always something that can go wrong.
These instructions refer to kernel version 6.1.21-v8. You can check your kernel version with the command uname -a
.
Debian 12 bookworm was used as the OS. You can see your OS version under /etc/os-release:
There should be enough free space on your Raspberry Pi file system. As a rule of thumb, about 50 percent. However, the convert process can also be successful with much less. In my case, for example, less than 10 percent disk space was still free.
Preparing Raspberry Pi
If not already available, install intiramfs-tools, btrfs and btrbk:
apt install initramfs-tools btrfs-progs btrbk
Add the btrfs module via initramfs modules in /etc/initramfs-tools/modules
by simply adding btrfs
at the end of the file:
If you run the mkinitramfs command you get strange errors like "Missing /boot/config-[kernel_version]" and that zstd or gzip is not supported by the current kernel.mkinitramfs
has not yet (as of January 2024) been configured for the RaspberryPi 64Bit, so we have to make a change in the setup file.
In /usr/sbin/mkinitramfs
add the following lines below the existing shebang #!/bin/sh
:
and create a new initramfs:
mkinitramfs -o /boot/initramfs-btrfs.gz
Beware: From here, your Raspberry Pi will be switched to BTRFS after restarting. Without changing the file system afterwards, your Raspberry Pi will no longer start.
Now change to directory /boot/ and replace ext4 with btrfs in /boot/cmdline.txt
manually with any editor such as nano or vim.
root=<mountpoint root> rootflags=subvol=@root rootfstype=btrfs
Load the new kernel configuration at each boot with the following entry at the end of the configuration in /boot/config.txt
:
The last change is made in the /etc/fstab
. Change the file system for the root partition (not for boot) to btrfs manually with any editor such as vim.
Now shutdown your Raspberry Pi remove your flash drive and plug it into a separate system.
shutdown now
Convert your EXT4 filesystem to BTRFS
Your flash drive must not be mounted and btrfs-progs must be installed on your system.
Check for your drive with lsblk
.
By default, your Raspberry Pi uses two partitions. We want to convert rootfs. bootfs remains untouched. Check carefully if this is really the right partition you want to convert to btrfs. In the example, sdd2 is the correct partition. That doesn't have to be the case for you.
First check the partition for possible errors. This step is not absolutely necessary.
e2fsck -fvy /dev/sdd2
Then you can use the btrfs-convert function.
btrfs-convert /dev/sdd2
create btrfs filesystem:
blocksize: 4096
nodesize: 16384
features: extref, skinny-metadata (default)
checksum: crc32c
free space report:
total: 128048168960
free: 8599547904 (6.72%)
This process can take a very long time. It is a process consisting of three steps:
- creating ext2 image file
- creating btrfs metadata
- copy inodes
The critical process is the first, because it could fail due to insufficient disk space.
As soon as the process is complete, you will receive the message 'conversion complete'.
If you convert your file system using btrfs-convert, you create a BTRFS filesystem with a two subvolume for ext2_saved and another for rootfs without UUID. It is not possible to create snapshots of subvolumes without UUIDs with btrbk.
Mount your devices locally again and check if everything is ok (it should be).
mount /dev/sdd2 /mnt
Go to your mountpoint /mnt
and create a new subvolume for your root device.
btrfs subvolume create @root
Btrfs subvolumes behave like normal directories in Linux. All operations such as rm
or ls
also work here. We use this fact to migrate the data from root to the new subvolume. By naming convention, subvolumes are preceded by an @ character.
Check if the subvolume creation has worked:
btrfs subvolume show /mnt/@root/
@root
Name: @root
UUID: 16197b0e-0000-a24e-0000-9b09c6fbae1b
Parent UUID: -
Received UUID: -
Creation time: 2024-01-11 00:28:42 +0100
Subvolume ID: 396
Generation: 3795
Gen at creation: 3794
Parent ID: 5
Top level ID: 5
Flags: -
Snapshot(s):
:
We now need to move the files from / to the new subvolume. Many tutorials on the Internet specify a rsync command for reasons I don't understand. However, a pure mv
command is sufficient and much faster.
This command will move all directories on your mounted drive to @root subvolume except @root itself.:
This will take a very long time, depending on storage consumption but is still faster than rsync.
Boot up Raspberry Pi
Reconnect your flash drive to your raspberry pi and let it boot up.
Test if everything is ok and delete the subvolume ext2_saved since it takes up a lot of space:
btrfs subvolume show /
Name: <FS_TREE>
UUID: -
Parent UUID: -
Received UUID: -
Creation time: -
Subvolume ID: 5
Generation: 2032
Gen at creation: 0
Parent ID: 0
Top level ID: 0
Flags: -
Send transid: 0
Send time: -
Receive transid: 0
Receive time: -
Snapshot(s):
As you can see, there is no snapshot yet. Create the first snapshot with the command:
btrfs subvolume snapshot / snapshots
This creates a snapshot in the /snaphosts directory which hardly takes up any disk space.
Avoid the BTRFS swapfile problem
If you are using a swap file, you will need to make additional changes. The steps are described very well in the official documentation but despite these measures it is not possible to create snapshots without first deactivating the swap. You get the error message:
ERROR: cannot snapshot '/': Text file busy
Theoretically, this could be avoided by creating a separate subvolume for the swap file.
Another way is to use zram as an alternative to swapfile. zram allocates swap in RAM. A small positive side effect is the performance gain.
The configuration is simple.
apt install zram-tools
Comment out the line PERCENT=50
in the file /etc/default/zramswap
and enable the service:
systemctl enable --now zramswap.service
Backup with btrbk
Create a new file /etc/btrbk/btrbk.conf
and add the following to it:
We now need a snapshot directory. In the configuration above I called this SNAPSHOT. btrbk does not create this directory, so we have to do that:
mkdir /SNAPSHOTS
Now we can test the configuration:
btrbk -c /etc/btrbk/btrbk.conf run
A successful test should show the following:
--------------------------------------------------------------------------------
Backup Summary (btrbk command line client, version 0.32.5)
Date: Thu Jan 11 00:21:08 2024
Config: /etc/btrbk/btrbk.conf
Legend:
=== up-to-date subvolume (source snapshot)
+++ created subvolume (source snapshot)
--- deleted subvolume
*** received subvolume (non-incremental)
>>> received subvolume (incremental)
--------------------------------------------------------------------------------
/
+++ /SNAPSHOTS/ROOT.20240111
The /etc/btrbk directory also contains a more detailed example configuration.
It is also possible, for example, to perform both pull and push backups remotely with btrbk via SSH.
The file is called btrbk.conf.example and is well commented.
The current configuration will create 7 backups with a daily time span.
However, we also need to trigger the backup process. To do this, we create a SystemD unit configuration file in /etc/systemd/system
In the example, a snapshot is taken every night at 23:55.
Restore the snapshot
sudo btrfs subvolume delete /mnt/@root
sudo btrfs subvolume snapshot /mnt/path/to/btrbk/snapshots/@root.20210101 /mnt/@root
What you need to bear in mind
As long as BTRFS is not in the kernel by default, you will have to make the adjustments to initramfs again with every kernel update (mkinitramfs step). However, this will become faster and faster over time.