The following tutorial will show the steps to create an Arch Linux system booting from the Btrfs file system. Btrfs is quite different from the Linux standard Ext3/4, and much closer to the UNIX focused ZFS in design and features. The Wikipedia article is a good introduction for those unfamiliar with how Btrfs is different.

The main difference from a configuration perspective is that the concept of partitions has changed. Known as sub-volumes in Btrfs, they are not linked to a block device as would be the case in a (for example) normal Ext4 setup. Instead they exist as a part of a single storage pool sharing the available physical device space.

One of the most useful features of Btrfs is the ability to create snapshots of the file system which then allow instant roll-back of file system changes. A snapshot is simply a duplicated sub-volume, creating a full copy of the sub- volume at the point in time the command was executed. Obviously this is very helpful during any system or application changes, such as installing updates or testing new packages.

Also please note that a legacy BIOS configuration with GRUB as a bootloader was used to complete this setup. Booting Btrfs with UEFI bootloader currently causes a lot of headaches. A good source of EFI boot loader information is here http://www.rodsbooks.com/efi-bootloaders/index.html.

Download some stuff

Gparted Live CD http://sourceforge.net/projects/gparted/ (or Parted Magic which is now behind a small paywall)
Arch Linux (not "Netboot") http://www.archlinux.org/download/
dd for Windows http://www.chrysocome.net/dd
syslinux (version 5.x) http://www.kernel.org/pub/linux/utils/boot/syslinux

Prepare a USB stick

This will be used to boot the ISO images, an actual CD will work just as well of course, i did this on Windows 7 as it is my main desktop.

Double check the drive letter for the USB, then wipe partition table. This may not be needed for a new USB stick, however it will make sure the MBR on the device is wiped.

dd --list
dd if=/dev/zero of=\\\?\Device\HarddiskVolume[VOLUME_NUM] bs=512 count=1

Now format the drive as FAT32 in Windows and copy the following files from the Syslinux 5.x download to a folder named \Boot\Settings on the USB drive.

  • vesamenu.c32 (in com32\menu folder)
  • menu.c32 (com32\menu)
  • memdisk (memdisk)
  • libutil.c32 (com32\libutil)
  • syslinux.cfg

The contents of syslinux.cfg should be similar to the bellow:

UI menu.c32
PROMPT 0
MENU TITLE Boot Menu
TIMEOUT 60
DEFAULT arch_iso

LABEL arch_iso
MENU LABEL Arch Linux Setup
LINUX memdisk
INITRD /Boot/ISOs/archlinux.iso
APPEND iso

LABEL parted_iso
MENU LABEL Parted Magic
LINUX memdisk
INITRD /Boot/ISOs/pmagic.iso
APPEND iso

Now copy the ISO images required to the folder \Boot\ISOs, and use syslinux.exe (in win32 folder) install the boot loader onto the USB stick.

syslinux -ima -d /Boot/Settings [DRIVE_LETTER]:

See these links for information on what syslinux is doing: http://www.syslinux.org/wiki/index.php/MEMDISK#ISO_images and http://www.syslinux.org/wiki/index.php/SYSLINUX#Options

Partition your HDD

Boot into Gparted and partition the drive, a small (128Mib or 256Mib should be fine) swap partition and a single Btrfs partition are all that is required. A swap file cannot be hosted on a Btrfs file system currently, so as a precaution some space is allocated now https://btrfs.wiki.kernel.org/index.php/FAQ#Does_btrfs_support_swap_files.3F.

Arch Linux setup from the Live CD

The default hard drive device name used in the follwing commands will be /dev/sda[2] and /dev/sdb[2], with the mount commands assiming an SSD is in use. If you are using a different device name please ensure you edit the commands as appropriate. Any data loss is your responibility!

Boot into the Arch Live CD and find the current ip address, load a keymap and start sshd. Setup can now continue via SSH with the abilty to copy and paste commands.

ip addr
loadkeys uk
passwd
systemctl start sshd

Check the partitions and format the data partition to Btrfs for a single drive.

parted /dev/sda print
mkfs.btrfs -f -L "arch_linux" /dev/sda2
btrfs filesystem show

Or if you wish, format data partition to Btrfs for multiple drives.

mkfs.btrfs -f -d raid1 -L "arch_linux" /dev/sda2 /dev/sdb2

Some details on using multiple devices https://btrfs.wiki.kernel.org/index.php/Using_Btrfs_with_Multiple_Devices#Multiple_devices and how to mount the file system with a missing disk should one fail https://www.mail-archive.com/[email protected]/msg30090.html.

Now mount the new Btrfs file system to a temporary location. Traditionally this would be the system root, but to allow snapshots to be created more easily there will be a folder structure bellow root.

mkdir /mnt/btrfs
mount -o defaults,relatime,discard,ssd /dev/sda2 /mnt/btrfs

Create a snapshot folder and the sub-volumes. __snapshots will be used to as a destination for any snapshots created and __active will contain sub-volumes that will be running the system root.

cd /mnt/btrfs
mkdir __snapshot

__active doesn't really need to be a sub-volume, but in case a snapshot of root and home are needed together setting it up as one doesn't hurt.

btrfs subvolume create __active
cd __active
btrfs subvolume create root
btrfs subvolume create home

Enable compression for root only.

chattr +c root
lsattr

Compression can currently be enabled on an entire file system using mount options, or to parts of a file system with file attributes. Compression will have positive effects in general and will reduce the amount of writes which is good for SSD life. However it is not enabled under home as often larger files that do not benefit from compression will be stored there (media, vhd images etc.).

Now the created sub-volumes can be listed. There should be 3 in total, __active, with root and home inside the __active sub-volume.

cd /mnt/btrfs
btrfs subvolume list .

Make a root sub-volume mount point which will become the install target for the base system.

mkdir /mnt/btrfs-root
mount -o defaults,relatime,discard,ssd,nodev,subvol=__active/root /dev/sda2 /mnt/btrfs-root

Also mount the home sub-volume.

mkdir /mnt/btrfs-root/home
mount -o defaults,relatime,discard,ssd,nodev,nosuid,subvol=__active/home /dev/sda2 /mnt/btrfs-root/home

Uncomment a server or servers in the nearest region.

nano /etc/pacman.d/mirrorlist

Install the base system.

pacstrap /mnt/btrfs-root base base-devel

Generate an fstab file and then add a mount point to the whole Btrfs file system under /run. This will provide access to the __active sub-volume and __snapshot directory, which would otherwise be unavailable when booting into the new system.

genfstab -U -p /mnt/btrfs-root >> /mnt/btrfs-root/etc/fstab
nano /mnt/btrfs-root/etc/fstab

It should look similar to the bellow.

#
# /etc/fstab: static file system information
#
# <file system> <dir>   <type> <options>       <dump>  <pass>
# /dev/sda2 LABEL=arch_linux
UUID=[YOUR_UUID]       /               btrfs           rw,nodev,relatime,ssd,discard,space_cache,subvol=__active/root  0 0

# /dev/sda2 LABEL=arch_linux
UUID=[YOUR_UUID]       /home           btrfs           rw,nosuid,nodev,relatime,ssd,discard,space_cache,subvol=__active/home   0 0

# /dev/sda2 LABEL=arch_linux
UUID=[YOUR_UUID]       /run/btrfs-root btrfs           rw,nosuid,nodev,relatime,ssd,discard,space_cache 0 2

The UUID of the file system can be found with blkid, although genfstab will also populate this. The UUID abstracts away from the physical device, so if the second drive in a mirrored pair is used as the boot device, the file system will still mount without a change to the fstab, see https://wiki.archlinux.org/index.php/persistent_block_device_naming#by-uuid.

Intial system setup via chroot

Enter the chroot environment and install grub and btrfs-progs.

arch-chroot /mnt/btrfs-root /bin/bash
pacman -S grub btrfs-progs

Now generate the initial ram disk image used by GRUB in the bootstrap process by first modifying the config as bellow.

nano /etc/mkinitcpio.conf

At the HOOKS line remove fsck.

The fsck hook is not needed for Btrfs https://bbs.archlinux.org/viewtopic.php?pid=1209831#p1209831. The btrfs hook is also not needed as udev is in use https://wiki.archlinux.org/index.php/mkinitcpio#Common_hooks.

Currently there is an open bug when running two or more devices. An update to systemd has caused issues with loading the btrfs module under Arch. In this case the MODULES line requires btrfs to be added to allow a multi-device system to boot. The bug is open here https://bugs.archlinux.org/task/42884.

mkinitcpio -p linux

Install GRUB (on all devices in a multi-device set up). GRUB has the best support for Btrfs currently, it is also recommended to use legacy BIOS rather than UEFI. The UEFI and Btrfs combination is tricky for Linux boot loaders currently.

grub-mkconfig -o /boot/grub/grub.cfg
grub-install --target=i386-pc --recheck /dev/sda

Set your keymap and add a user for use with SSH later.

loadkeys uk
useradd -m -g users -G wheel -s /bin/bash [USER NAME]
chfn [USER NAME]
passwd [USER NAME]

See https://wiki.archlinux.org/index.php/Users_and_Groups#User_management for details on creating users.

Install OpenSSH.

pacman -S openssh
systemctl enable sshd
nano /etc/ssh/sshd_config

Add the line AllowUsers [YOUR USER] to sshd_config.

See this link for more detail on the setup https://wiki.archlinux.org/index.php/Secure_Shell#Installing_OpenSSH.

Reboot into the new system.

exit
umount /mnt/btrfs-root/home
umount /mnt/btrfs-root
umount /mnt/btrfs
reboot

Installed system configuration and snapshots

Login as the root user and set a password, then setup the network, dhcp is good enough for now.

passwd
dhcpcd [YOUR NIC]

Now SSH can be used again to continue the setup (logging in with the user created previously), for a shell that is the same as the Live CD use https://grml.org/zsh/. Initial configuration for ZSH can be found here https://wiki.archlinux.org/index.php/zsh#Initial_configuration.

pacman -S zsh grml-zsh-config

The wiki has a good list of configuration to complete after you have the base system up and running. See this link https://wiki.archlinux.org/index.php/Beginners%27_Guide#Chroot_and_configure_the_base_system

After the base system is configured as required this is a good time to take an initial snapshot. This is essentially a single command which -- in this case -- will create a read-only snapshot in the __snapshot folder with a date and time appended.

btrfs subvolume snapshot -r /run/btrfs-root/__active/root /run/btrfs-root/__snapshot/root__`date "+%Y-%m-%d_%H%M"`
btrfs subvolume list /run/btrfs-root

To restore a to a previously generated snapshot is equally easy. Rename the active root snapshot, this can be done while the system is running.

mv /run/btrfs-root/__active/root /run/btrfs-root/__active/root-stale

Then create a new root snapshot from a previous read-only snapshot. This will "snapshot the snapshot" making a copy of it.

btrfs subvolume snapshot /run/btrfs-root/__snapshot/YOUR_SNAPSHOT /run/btrfs-root/__active/root
reboot

After rebooting the root-stale sub-volume can be deleted as required.

btrfs subvolume delete /run/btrfs-root/__active/root-stale

If the system happened to lose power during the renaming of the root sub-volume and creating the replacement, then the GRUB boot options can be modified to point the subvol= option to the renamed location (root-stale in this case).

Finished

Thanks goes to the author of the following blog post who completed a very similar setup http://blog.fabio.mancinelli.me/2012/12/28/Arch_Linux_on_BTRFS.html. As Arch is a moving target some of the steps are now out of date, my setup is very similar, with some simplifications and any problems i found resolved.


Comments

comments powered by Disqus