About this guide
I made this guide a few days after installing Arch Linux with ZFSBootMenu on my Laptop. However, always check the commands before entering them. You should be knowledgeable in both Linux and ZFS.
In this guide, I will go through an entire ZFS-on-Root installation process on Arch Linux, using ZFSBootMenu as the UEFI bootloader. It will basically be a mix of multiple guides, which I will link below.
In the following code blocks, every time you have to insert something into a command, I’ll use single guillemets:
command <insert something here>
Step 1 – Getting a bootable USB stick with the Arch LiveISO
I’m assuming that you are familiar with creating a bootable USB stick. If you’re not, then this guide might help you: Create the bootable media. Don’t forget to disable Secure Boot in your BIOS to boot the image.
There are two possible LiveISO images you could use:
- Using a normal LiveISO and installing ZFS on it afterwards
- Using a custom image with ZFS being preinstalled
Using a normal image – Recommended
First grab the latest image from the official Arch Linux Download site and put it on the USB Stick. Then boot from it (Don’t forget to disable Secure Boot in your BIOS beforehand) and prepare your live image. Afterwards run the script provided by eoli3n:
curl -s https://raw.githubusercontent.com/eoli3n/archiso-zfs/master/init | bash
Jump straight to Step 3.
Using a custom image
I won’t go into detail to how to make it, however the ArchWiki has a guide for it: Create an Archiso image with ZFS support. Please note that you need to have Arch Linux installed already on your system to use this method. Personally, I would recommend that you use the archzfs
user repository when creating your image.
Step 2 – Prepare your live image
If you didn’t already, you must now prepare your live image.
Set the keyboard layout
Now you need to set your keyboard layout (unless you’re using the US layout). You can get a list of all available layouts with:
ls /usr/share/kbd/keymaps/**/*.map.gz
For example for using the Swiss German layout use:
loadkeys de_CH-latin1
Connect to the Internet
Use any utility you want, I will use iwctl in the following part.
Start iwctl and list your devices:
iwctl
[iwd] device list
Scan for networks:
[iwd] station <device> scan
List all available networks:
[iwd] station <device> get-networks
Connect to a network:
[iwd] station <device> connect <SSID>
Enter your network password and you’re connected to the Internet.
Step 3 – Create the ZFS pool
Generate /etc/hostid
zgenhostid
Store your pool passphrase in a file
echo '<passphrase>' > /etc/zfs/zroot.key
chmod 000 /etc/zfs/zroot.key
Partition your disk
Create an EFI partition with a size of 512 MB and a second partition on which the zpool will be. You may want to add other partitions, for example a swap partition.
Please note that if you want to use swap, you can’t use a swap file, as there are limitations with it and ZFS. You should read the wiki page in the Arch Wiki before using swap.
List your disks
ls -la /dev/disk/by-id
Save your disk path in a variable
DISK=/dev/disk/by-id/<DISK>
Apply the partition scheme
You can use any utility you want, for example fdisk or gdisk. I will use gdisk in the following commands:
sgdisk --zap-all $DISK
sgdisk -n1:1M:+512M -t1:EF00 $DISK
sgdisk -n2:0:0 -t2:BF00 $DISK
Create zroot
You can name the pool as you want, I’ll call it zroot. I’ll use the lz4 compression, however you might want to use another compression algorithm like zstd or gzip. In most cases I recommend using compression as there are no big performance issues with that.
You might also want to change ashift
depending on your hard drive, as some modern SSDs perform better when using ashift=13
. Your ashift
value depends on the physical block size your disk uses. If it has 4k sectors, use ashift=12
, if it has 8k sectors, use ashift=13
, if it has smaller sectors, use a smaller ashift
. You might also want to set atime=off
, since you probably don’t need the file system to update the time you last accessed a file. If you want to really tune your system, I recommend reading this guide and this cheat sheet. However, if you only want a functioning file system, you can skip this tuning and use the following settings. You can change most of the settings later on (however, ashift
can’t be changed later, so it might be worth researching it a bit and looking up your block size).
zpool create -f -o ashift=12 \
-O compression=lz4 \
-O acltype=posixacl \
-O xattr=sa \
-O relatime=on \
-O encryption=aes-256-gcm \
-O keylocation=file:///etc/zfs/zroot.key \
-O keyformat=passphrase \
-o autotrim=on \
-m none zroot ${DISK}-part2
Create the datasets
Create a dataset for our root system under zroot/ROOT
and a dataset for /home
, because in that way you’re able to later add other root datasets (for example for other distributions) while still using the same /home
. Thanks to ZFSBootMenu you’ll be able to boot into the other root dataset with no problems.
Note: It’s important to set the canmount=noauto
property on all file systems with mountpoint=/
, because else it will try to boot all systems at /
, which will prevent the system from booting.
zfs create -o mountpoint=none zroot/ROOT
zfs create -o mountpoint=/ -o canmount=noauto zroot/ROOT/arch
zfs create -o mountpoint=/home zroot/home
Test the pool by exporting and importing it
zpool export zroot
zpool import -N -R /mnt zroot
zfs load-key -L prompt zroot # Enter your pool passphrase after that command
zfs mount zroot/ROOT/arch
zfs mount zroot/home
Check whether the pool is mounted correctly
mount | grep mnt
This should return something like that:
zroot/ROOT/arch on /mnt type zfs (rw,relatime,xattr,posixacl)
zroot/home on /mnt/home type zfs (rw,relatime,xattr,posixacl)
Create and mount the EFI partition
mkfs.vfat -F 32 -n EFI $DISK-part1
mkdir /mnt/efi
mount $DISK-part1 /mnt/efi
Step 4 – Install Arch Linux
Install the packages with pacstrap
In the following steps you’ll install the first packages with pacstrap.
Install base packages
The following packages are absolutely needed. However, you’ll most likely want to install more packages, for example man
for manual pages or networkmanager
for the ability to easily connect to Wi-Fi. However, I would only install a few packages in this step and all desktop environments like gnome
, browsers like firefox
etc. after the full installation is done.
You may also want to choose another kernel than linux-lts
, for example linux
if you don’t want the Long Term Support kernel or linux-zen
for the Zen kernel. when doing so, you must also install the respective -headers
package, so change linux-lts-headers
to <kernel name>-headers
.
Personally, I recommend using the Long Term Support kernel:
pacstrap /mnt base linux-lts linux-firmware linux-lts-headers wget nano efibootmgr
Install the zfs module
You have multiple ways to choose from when installing the zfs module. One way is to install zfs-linux-lts
(or zfs-linux
for the non-LTS kernel or zfs-linux-zen
for the Zen kernel). However, I recommend to use the DKMS variant, as it will automatically rebuild the module each time the kernel gets an update, so you won’t have to wait until the zfs-linux-lts
package is updated. Additionally, you can use this package for any chosen kernel. Therefore I’ll install this one:
pacstrap /mnt zfs-dkms
Copy the files to the new system
In this step you’ll copy all important files to the new system.
cp /etc/hostid /mnt/etc
cp /etc/resolv.conf /mnt/etc
mkdir /mnt/etc/zfs # it may already exist, but this isn't a problem
cp /etc/zfs/zroot.key /mnt/etc/zfs
cp /etc/pacman.conf /mnt/etc/pacman.conf
Generate /etc/fstab
Now you’ll generate /etc/fstab
:
genfstab /mnt > /mnt/etc/fstab
However, you’ll have to modify it as zfs doesn’t need an entry in /etc/fstab
:
nano /mnt/etc/fstab
And delete all lines but the one containing /efi
.
Chroot into the new system
arch-chroot /mnt
Set the time zone
ln -sf /usr/share/zoneinfo/<Region>/<City> /etc/localtime
Additionally run this to generate /etc/adjtime
:
hwclock --systohc
Generate your locales
Edit /etc/locale.gen
:
nano /etc/locale.gen
Uncomment all locales you need, for example en_US.UTF-8 UTF-8
.
Afterwards run this to generate the locales:
locale-gen
Then set the LANG
variable accordingly by writing LANG=<Your local>
to /etc/locale.conf
, for example LANG=en_US.UTF-8
:
echo 'LANG=en_US.UTF-8' > /etc/locale.conf
You may also want to set the keyboard layout by setting KEYMAP
according to the keyboard layout you chose earlier by writing KEYMAP=<Keyboard layout>
to /etc/vconsole.conf
, for example KEYMAP=de_CH-latin1
:
echo 'KEYMAP=de_CH-latin1' > /etc/vconsole.conf
Network configuration
Set your hostname by writing it to /etc/hostname
:
echo '<hostname>' > /etc/hostname
Then edit /etc/hosts
, where <hostname>
is your previously chosen hostname:
127.0.0.1 localhost
::1 localhost
127.0.1.1 <hostname>
Generate your initramfs
Then edit /etc/mkinitcpio.conf
:
nano /etc/mkinitcpio.conf
Change the FILES
line to:
FILES=(/etc/zfs/zroot.key)
This will save the key file in the initramfs, because else we’d have to type in the key two times each time we boot.
And change the HOOKS
line to:
HOOKS=(base udev autodetect modconf block keyboard zfs filesystems)
This will load the zfs
module, which you need to use ZFS.
Afterwards generate a new initramfs:
mkinitcpio -P
Set a root password
passwd
Set a cachefile for zfs
Set a cachefile
for ZFS to boot from:
zpool set cachefile=/etc/zfs/zpool.cache zroot
Set your bootfs
Set your bootfs
for ZFS, so that ZFSBootMenu knows which dataset to boot from:
zpool set bootfs=zroot/ROOT/arch zroot
Enable all needed daemons
systemctl enable zfs-import-cache zfs-import.target zfs-mount zfs-zed zfs.target
Step 5 – Install ZFSBootMenu
Install ZFSBootMenu by getting the pre-built binary from their release page.
Create an efi subfolder
mkdir -p /efi/EFI/zbm
Get the latest release
wget https://get.zfsbootmenu.org/latest.EFI -O /efi/EFI/zbm/zfsbootmenu.EFI
Add an entry to your boot menu
Use efibootmgr – Recommended
In the following comment <disk>
is the disk you installed the EFI partition on earlier.
efibootmgr --disk <disk> --part 1 --create --label "ZFSBootMenu" --loader '\EFI\zbm\zfsbootmenu.EFI' --unicode "spl_hostid=$(hostid) zbm.timeout=3 zbm.prefer=zroot zbm.import_policy=hostid" --verbose
Use the BIOS
Some manufacturers offer the possibility to add a boot entry graphically in the BIOS. However you must check your manufacturer’s manual to see whether it’s possible and how to do it.
Use another bootloader
You could use another bootloader like rEFInd or GRUB to boot into ZFSBootMenu. This is especially useful when you want to dual boot with Windows or MacOS (if you want to dual boot with another Linux distribution you will most likely be able to do it through ZFSBootMenu by putting the distribution root directory on another dataset in zroot
).
Set the kernel parameters
zfs set org.zfsbootmenu:commandline="noresume init_on_alloc=0 rw spl.spl_hostid=$(hostid)" zroot/ROOT
Step 6 – Reboot and enjoy
Exit the chroot
exit
Unmount the EFI partition
umount /mnt/efi
Export the zpool and reboot
zpool export zroot
reboot
Log in and continue with further installation steps
Now you should boot first info ZFSBootMenu and afterwards into Arch Linux. If everything works, you should continue with the General recommendations after installing.
Notes
Moving to another system
If you move your ZFS disks to another system and they aren’t detected as bootable, you may try to reinstall ZFSBootMenu, regenerate the hostid and copying the new /etc/hostid to your disk. Thanks to Johannes in the comments for this note!
Debugging
If you have to debug the system for any reason, be it immediately after installing it or some time later, you have to import zroot
the following way (See also Step 3):
zpool import -N -R /mnt zroot
The reason is that the normal mountpoint
for zroot/ROOT/arch
is /
(as set in Step 3), and for it to mount to /mnt
we have to set a temporary mountpoint
, which we do with the -R
flag.
References
Full Guides
- Installation guide – wiki.archlinux.org
- Arch auf ZFS – wiki.archlinux.de (German)
- Void Linux Single disk UEFI – github.com/zbm-dev/zfsbootmenu/wiki
- User:Kayvlim/Install UEFI and BIOS compatible Arch Linux with Encrypted ZFS and ZFSBootMenu – wiki.archlinux.org
Other References
List of updates to this article
List of Updates
Update - 2024-02-07
Added some information about moving the ZFS disks to another system.
Update - 2024-02-03
Added some new information in the section Create zroot about some tuning options.
Update - 2024-01-14
Changed the recommended kernel from linux
to linux-lts
as it will give you less problems when updating your kernel. For more information click here.
Update – 2022-10-27
In an earlier version I forgot to mention that you must copy /etc/pacman.conf
from the live system to the newly installed system or else the new system won’t upgrade the zfs modules. I’m sorry for the inconvenience.
If you installed it without copying the file, you can fix this by adding the following to the end of /etc/pacman.conf
:
[archzfs]
Server = http://archzfs.com/$repo/x86_64
SigLevel = Optional TrustAll
Just run sudo pacman -Syu
afterwards.