Many guides already exist for configuring a raspberry pi root partition to use btrfs, however there were a few circumstances that basically invalidated all of them:
- I wanted the raspberry pi to run Ubuntu 18.04, both for the 64-bit OS and default btrfs implementation,
- The ubuntu image for the pi4 has completely changed the default /boot volume, and..
- I had to do this all on my Windows laptop, or the pi itself through ssh.
If for some crazy reason your situation mirrors my own, I hope you find this documentation useful. Feel free to comment below if you have suggestions or improvements to the way I did things 😊
Formatting the SD card
- I used balenaEtcher to flash the latest pi4-compatible Ubuntu 20.04 64-bit image onto the card. Or, if you’d prefer an older release: Ubuntu 18.04 and older (for a good description of hard vs. soft float, see Raspberry Pi Forums. In short, the hard float image will increase your performance by using the pi’s native hardware abilities.)
- Etcher automatically unmounts the card after it’s finished, so re-mount and use Disk Management (Windows search bar:
diskmgmt.msc
, choose “Run as Administrator”) to create two partitions. The first should be the current root partition size (unexpanded) + whatever space you’d like to add. The second must be formatted without Quick Format, and use all remaining space on the volume. This will take a while. - Once you’ve created both partitions, delete the first so that the space shows “unallocated”. This will let the pi expand it’s root partition up to your second placeholder partition. When done, it should look as below:
- Before ejecting the SD card, create a blank file named “ssh” in the boot partition (the only one that will mount on Windows), and remove the extension. This allows us to ssh into the pi on first boot.
Starting up the pi
- Login to the new raspberry pi. I usually check the router to see what DHCP address it was assigned, do as you like. SSH with
ubuntu@X.X.X.X
, password is alsoubuntu
and will need to be changed. - ENABLE SSH SERVICE, or get locked out the first time you mess up:
sudo systemctl enable ssh
- Check that the your btrfs kernel module is enabled:
sudo lsmod | grep "^btrfs"
, if you get nothing back thensudo modprobe btrfs
. - If need be, run a
sudo apt update && sudo apt install btrfs-tools
, but you should already have them on the system. If you run the command anyways, you’ll change the package to manually installed.
Configure Partitions
sudo fdisk /dev/mmcblk0
, then enter “p” to print the existing partitions. If you’ve followed everything up to now, you should see something similar to what’s below:
Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 * 2048 526335 524288 256M c W95 FAT32 (LBA)
/dev/mmcblk0p2 526336 10508287 9981952 4.8G 83 Linux
/dev/mmcblk0p3 10508288 62521343 52013056 24.8G f W95 Ext'd (LBA)
/dev/mmcblk0p5 10510336 62521343 52011008 24.8G 7 HPFS/NTFS/exFAT
- Take note of the start block for the root partition (mmcblk0p2), because we’re about to delete and re-create everything except the boot. This should be fine as long as the starting sector remains unchanged.
- continue to delete (“d” is the command) until only partition 1 (mmcblk0p1) is left.
- Create two new partitions with the “n” command. Select “p” for primary, and make sure the first starts at the exact same sector as it did before, but for size let’s increase to slightly less than 1/2 of the space left. Do this by entering
+14G
, where the 14 is roughly your total space in Gigabytes divided by two minus one. It will ask if you want to delete the ext4 signature, select “N”. - Create a second partition the same way, using defaults and starting at the sector just after your second partition. Ensure they are exactly the same size (i.e. +14G and +14G, or whatever you chose)
- Check that all your commands executed as expected with “p” again, and you should now have this:
Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 * 2048 526335 524288 256M c W95 FAT32 (LBA)
/dev/mmcblk0p2 526336 29886463 29360128 14G 83 Linux
/dev/mmcblk0p3 29886464 59246591 29360128 14G 83 Linux
- Write your changes and exit with “w”.
BTRFS Setup
Enter the following commands in order:
sudo mkfs.btrfs /dev/mmcblk0p3
sudo mkdir /mnt/p3
sudo mount /dev/mmcblk0p3 /mnt/p3
sudo rsync -qaHAXS --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found","boot/firmware/*"} / /mnt/p3
(you may want to run this command inscreen
, in case you get disconnected)sudo lsblk -f
- take from this the UUID of mmcblk0p3, this is what you will use in the below commands instead of my value.sudo nano /boot/firmware/nobtcmd.txt
(orcmdline.txt
, depending on your version), then edit these two values to match:root=UUID=520bcef5-5b86-4e6e-a0e7-e271db19a88d rootfstype=btrfs
sudo nano /etc/fstab
, again changing the following line:UUID=520bcef5-5b86-4e6e-a0e7-e271db19a88d / btrfs defaults,noatime
- Perform one last
rsync
exactly like in step 4, to capture the above changes. sudo reboot
- your device will close connection here, if you completed all the steps correctly you should be able to ssh back in within ~2 mins.sudo lsblk -f
sudo btrfs device add -f /dev/mmcblk0p2 /
sudo lsblk -f
sudo btrfs balance start -mconvert=raid1 /
sudo btrfs balance start -dconvert=raid1 /
Long-Term Stability Clone and install btrfs maintenance.
💡Quick tip: do NOT use a swap file on root!!!