Btrfs/Native System Root Guide

Converting to a "Native" btrfs Based System
This exercise is an update to the original example for re-basing a gentoo installation's root filesystem to use btrfs found here. In this case, the existing system is a mirror set using two 2tb drives at /dev/sda and /dev/sdb. Two fresh 2tb drives have been added at /dev/sdc and /dev/sdd. In the original exercise, the mdadm array was kept to mirror the /boot partitions on the two drives, while the rest of the partitions were converted to btrfs subvolumes.

This second exercise explores the use of grub2 to fully convert the mirror set to use the multi-volume functionality of btrfs, implementing /boot as a mirrored btrfs filesystem and forgoing the need to use an initramfs file on /boot to provide early userspace mounting of the root subvolume. We also will be using the gptfdisk ebuild tools to make a GPT based partition table on the new mirror set in place of a legacy MBR table.

One of the lessons learned here is that grub2 ( 2.00_p5107-r2 here) and the current kernel (3.10.25 here) are not quite up to the job of directly booting a filesystem in a btrfs subvolume, at least, not one in a multi-disc set. However it is able to find a simple filesystem on the default volume of a multi-disc set.

Partitioning
Emerge gptfdisk if you don't already have it. It provides the gdisk, sgdisk and cgdisk utilities for manipulating GPT partitions. These correspond to the legacy fdisk, sfdisk and cfdisk utilities for MBR tables.

We followed the writeup on grub2 here to put together the following GPT scheme that GRUB2 can use and got it working after a false start or two.

The grub2biosboot partition was what got missed on the first round and thus got added later.


 * 1007.0KiB free space - Will eventually get the boot record and leave enough of a gap for grub2 to park its bios.
 * biosboot - The partition type 0xEF02 (BIOS boot partition) must be set in order for grub2 to find it and use it. Some web pages suggest using EF00 (EFI System), but this will not work with the current version of grub2.  The bare minimum for this size is 1mb, but some pages suggest using at least 2mb.  We err on the side of caution and future bloat.
 * boot - GRUB2 will take about 32mb more of /boot than you may be used to so the usual suggestion of 200mb in days past is now more like 300mb - 500mb depending on how many kernels and initramfs filesystems you like to keep around. Set the partition type to the default which is 0x8300 for Linux.
 * root - We took the default for size to allocate the rest of the drive to the root partition. Once again the type is set to 0x8300.

The resulting table looks like the following in gdisk:

Repeat the same partitioning on /dev/sdd. Similar to sfdisk, the sgdisk utility has the ability to dump the GPT table to a file and then reload that. However the output is binary, so we just went ahead and used cgdisk to create the same layout on /dev/sdd.

Filesystem Creation
Since this is a two disk simple mirror, we specify raid1 for both metadata and data when making the two filesystems. If you have more than two drives, the current stable versions of kernel (3.10.25) and btrfs-progs (3.12-r1) now also make raid5 and raid6 available for options alongside raid1 and raid10.

We mount the default volume for the root partition on /mnt/newmirror but will be putting the actual contents into subvolumes with different btrfs features enabled or disabled.

The new root filesystem will go onto a btroot subvolume which is created on the mirror and then mounted to /mnt/newroot

We mount the existing root filesystem to /mnt/rawroot and use tar to transfer things over while avoiding the dynamic stuff.

At this point /mnt/newroot/boot and the mountpoints for the other subvolumes we will be creating are already in place from the tar. We keep the mount options simple for /mnt/newroot/boot.