Introduction
Imagine a situation where you have a laptop with two or more drives. Since it’s laptop you consider encrypting your drives so nobody can read your data when the device gets stolen. The typical approach would look something like this:

The RootFS would be located on Drive0. Additional data could be stored inside the /mnt/data directory which is the mount point for Drive1. Of course this graphic is a simplified version of the actual partition layout.
This approach however has a significant disadvantage. You, the user, have to decide what goes on which drive. And also have to remember where you saved your stuff. This can be a tedious process.
But wait, there is a modern solution to this problem. Additionally, this solution has advantages like snapshots. This solution is courtesy of Brtfs. In this article I will describe how we can create something like this:

Now both drives look like a single one. As a user, you can safe your files wherever you want and the system takes care of balancing the load between both drives. So let us take a look on how this is setup. The article was tested with Arch Linux, but should work with every Linux distribution imaginable, because the used software is available to all of them.
Format the drives
Of course there are a few commands to execute before you start with the formatting process. However there are great resources online on what to do. This guide then starts with the formatting process.
I assume that you are running a EFI System so this chapter reflects that assumption. If you are using a BIOS there are only slight modifications to make (e.g use fdisk
instead of gdisk
). Go ahead an run lsblk
to get the names of your drives. They could be nvme1n
x or sd
x.
Now that we know the name of the drives we can go ahead and partition them using gdisk
. Rungdisk /dev/<drivename>
If the internal command “p” returns a partition table, delete all partition by using the “d” command. Note that this step will “delete” all your data on this drive.
On the first drive (from now on /dev/nvme0n1
) create a new partition (“n”) with the first sector at 0 and the last sector at +512M and a hex code of 0xef00. This will hold the efi partition. Optionally create another partition for swap with the first sector starting after the efi partition and the last sector being at least the size of ram behind the start. In case of 16GB RAM use at least +16GB as last sector. Select 0x82 as the type. Because the other partitions are encrypted it is not possible the use a swapfile. So if you want swap, please create a partition now. Then add a final partition spanning the rest of the disk with the default type 0x83.
On the second drive (from now on /dev/nvme1n1
) you only create a single partition spanning the hole disk. Use the default type of 0x83
Before continuing with the cryptsetup let’s format the efi partition.
mkfs.fat -F32 /dev/nvme0n1p1
Cryptsetup
The next step is to initialize the cryptographic layer (dm-crypt) inside the partitions. It’s worth noting this setup only encrypts the two large partitions (/dev/nvme0n1p3
and /dev/nvme1n1p1
). The Swap and efi partitions can not be encrypted (as easily).
cryptsetup -v luksFormat /dev/nvme0n1p3
cryptsetup open /dev/nvme0n1p3 archlinux0
mkfs.btrfs -L "btrfs_pool" /dev/mapper/archlinux0
cryptsetup -v luksFormat /dev/nvme1n1p1
cryptsetup open /dev/nvme0n1p1 archlinux1
mkfs.btrfs -L "btrfs_pool" /dev/mapper/archlinux1
Afterwards the filesystem can be mounted and the subvolumes can the created to your liking. A great resource is this website. Sadly however the english version is not as good.
Making it bootable
Next up we need to tell the system our partition layout in several places. Otherwise it will not start.
Starting with the most obvious; the /etc/fstab
file:
# /dev/mapper/archlinux0
LABEL=btrfs_pool / btrfs rw,noatime,compress=zstd:3,ssd,space_cache=v2,subvolid=256,subvol=/arch,x-systemd.automount,x-systemd.mount-timeout=60,x-systemd.idle-timeout=1min 0 0
# /dev/nvme0n1p1
LABEL=BOOT /boot vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 2
# /mnt/dev/nvme0n1p2
LABEL=SWAP none swap defaults 0 0
This block can mostly be copy pasted however. Please adapt the subvolid
, subvol
and LABEL
of the first entry to your specific settings.
The next obvious thing to change is the mkinitcpio at /etc/mkinitcpio.conf
. Find the line HOOKS and replace it with:
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block btrfs plymouth sd-encrypt filesystems fsck)
Again, do not blindly copy over what I have posted. It is however important to change the initramfs from busybox-based to systemd-based. This is mainly done by the keyword systemd
. It is also important to add btrfs and sd-encrypt. A more detailed list of options is available here. Also note that some suggested options from above require certain packages to be installed. After saving the file, regenerate your initramfs using the following command.
mkinitcpio -P
Next up is the configuration of the bootloader. In my case it’s systemd-boot. Its however also a possibility to use something different. A Entry (e.g /boot/loader/entries/arch.conf
) can look like this :
title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options root=LABEL=btrfs_pool rootflags=subvol=arch resume=LABEL=SWAP rw quiet splash
And now the part that took me the longest to figure out. And why I’m writing this post. Before the system is able to boot from the initramfs into the actual system both encrypted partitions need to be decrypted. Therefor the initramfs needs to know how to decrypt the partitions. This is done in the /etc/crypttab.initramfs
file. Take a look at the example file:
# Configuration for encrypted block devices.
# See crypttab(5) for details.
# NOTE: Do not list your root (/) partition here, it must be set up
# beforehand by the initramfs (/etc/mkinitcpio.conf).
# <name> <device> <password> <options>
archlinux0 UUID=38c5dc7b-ba23-47c1-9f24-6c06b3199635 none luks,ssd,discard,initramfs
archlinux1 UUID=6e19404a-62d1-482a-9df0-3c050e7b6512 none luks,ssd,discard,initramfs
The contents are similar to /etc/crypttab
. However the .initramfs file gets copied into the initramfs and handles the decryption (see this link). Be aware that the above mentioned UUID will not match yours. Please replace them accordingly. It is required to regenerate the initramfs like above.
Additional Info
When you type in your decryption password during startup the system tries to unlock the second partition with the same password. Technically it is possible to set different password for both partitions. I however find it very convenient if I only have to remember one secure password. To achieve this just set the same password for both luks containers.
I know that this is not a full guide on how to set this up. There are a lot of great resources to fill the gaps of this guide. The reason why this guide exists in the first place is, that it was very difficult to find out that a /etc/crypttab.initramfs
file and switch the to systemd-based boot are required to make it happen.
And with that you should have a single btrfs pool to boot from. Signing off.