Booting Btrfs root partition on Raspberri Pi

This article stems from two different sources:

https://feldspaten.org/2019/07/05/raspbian-and-btrfs/

and

https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=319427

and I decided to summarize the process here, after extensively testing on a Raspberry Pi 4 with 8GB of RAM, and a 64bit OS; I might extend this guide to include setting up a Raid1 with a second disk.

WARNING
I suggest testing this procedure on a pendrive where you flashed the image of a raspberry pi os distribution, WITHOUT using apt update & full-upgrade for two reasons:

  1. nothing bad will happen if things go wrong, since it’s not a production environment
  2. you’ll be able to test the kernel update automation AFTER you completed all the steps, by running the apt update && full-upgrade commands

Install requirements and edit needed modules:

sudo apt install initramfs-tools btrfs-tools
sudo nano /etc/initramfs-tools/modules

Add the following lines to the file and save:

btrfs
xor
zlib_deflate
raid6_pq

Create the initramfs in /boot partition and edit config.txt:

sudo mkinitramfs -o /boot/initramfs-btrfs.gz
sudo nano /boot/config.txt

adding the following line up top and save:

# For more options and informations see
# http://rpf.io/configtxt
# Some settings may impact device functionality. See link above for details

initramfs initramfs-btrfs.gz

For good measure, check if rebooting the system is succesful. Then sudo poweroff and place the disk (SD, SSD, pendrive) on a linux PC, and, let’s say the device is recognized as /dev/sdb:

sudo fsck.ext4 /dev/sdb2
sudo btrfs-convert /dev/sdb2                 
sudo mkdir /mnt/rootfs
sudo mount /dev/sdb2 /mnt/rootfs

We’ve just checked if the existing ext4 rootfs is clean, then we converted it to btrfs (it will take quite some time to create the ext2 image to make rollback possible), then created a mountpoint and mounted to it the just converted btrfs root partition.

We now need to update the fstab in this partition so the system will correctly mount at boot:

sudo nano /mnt/rootfs/etc/fstab

Correct the root line (/) by replacing ext4 with btrfs, and make it sure it ends with two 0‘s to disable fsck on it (btrfs has its own builtin filesystem checks, and fsck might return unwarranted errors).

Also, correct /boot/cmdline.txt in the boot partition by replacing, again, ext4 with btrfs, and fsck.repair=yes with fsck.repair=no.

At this point, placing the drive back on the Pi and booting will take you in a btrfs rootfs.

BEWARE navigators: this was my major problem, without anything else added to the procedure, a kernel update will be followed by a useless system at the next reboot, because the initramfs won’t be recreated.

User dickon on raspberrypi forums was a great help in the following procedure.

You need to create a script to automatically update initramfs in /boot after a kernel update, so here it is.

sudo nano /etc/kernel/postinst.d/btrfs-update

Insert this code in the script (this will work with a 64bit OS, make sure kernel8.img is the correct filename, you can check against the existing file in /boot, otherwise change accordingly):

#!/bin/bash
if [ "x$2" != "x/boot/kernel8.img" ]; then
	exit 0
fi

echo ============ UPDATE INITRAMFS ==============
mkinitramfs -o /boot/initramfs-btrfs.gz $1
echo ============ UPDATE COMPLETED ==============

then make sure it is executable, and has the same permissions of the other files in the same folder:

sudo chmod 755 /etc/kernel/postinst.d/btrfs-update

At this point, the system will (should) update the relevant initramfs right after each kernel update, freeing you of the hassle of remembering to do it by hand, or risk having a useless system after the next reboot.

It is a good idea to disable swap, since btrfs won’t be able to host a swap file anyway:

sudo systemctl disable dphys-swapfile.service

Leave a Reply

Your email address will not be published. Required fields are marked *