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 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.

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 biosboot partition was what got missed on the first round and thus got added later. To recreate this setup in cgdisk, use the following values:


 * biosboot - start at sector 2048 and do a minimum size of 2048 sectors to create at least a 1mb partition for GRUB2 to park its core.img file when doing grub2-install. Set the partition type to 0xEF02 and set the label to something meaningful like biosboot.  We had simply done a 4mb freespace originally before putting in the boot partition so went back and made it start at 2048 and size of 6144 sectors to make the 3mb result.
 * 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.

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.