Skip to content

ZFS

Preamble

ZFS Primer

ZFS Schema

Basic Strategy

ZFS is not included in the linux kernel due to licensing. So the solution is to add the zfs kernel modules and zfs utilities to the base arch linux installation. These are maintained in the archzfs repo. This can be done by creating a custom .iso or by a script from eoli3n with a standard .iso - which is easier. Use the OpenZFS for Arch Linux as a guide.
The next steps are to create the zfs pool and datasets. The main difference here is the pool and datasets will try to automount on creation so the -o mountpoint=none or -o mountpoint=noauto is used to prevent issues. Then just install arch linux as per normal, remembering that on the new installation the archzfs repo and the archzfs-linux package need to be installed again.
For booting, I decided to go with zfsbootmenu - basically an .efi app that can boot from a kernel + initramfs pair found in /boot on any zfs dataset. zfsbootmenu also works nicely with rEFINd.

Starting Out

Using the archzfs script (preferred)

curl -s https://eoli3n.github.io/archzfs/init | bash
Run this after booting standard .iso - it will load zfs kernel modules and utilities to allow making zpool etc. To make sure no errors run modprobe zfs

2. Making a custom archiso (optional)

Need zfs kernel modules and zfs utils from the archzfs repoi. archzfs is not always up to date with latest kernal so check on https://archzfs.com/archzfs/x86_64.
Add keys and edit pacman.conf to include the archzfs repo. Then add linux-headers and archzfs-linux to the package list (these are the kernel modules and zfs utilites).
Use the arch archive how to determine dates for pacman - match to date of most recent archzfs. Then run mkarchiso -v

Installation

Partitioning

sgdisk/gdisk which are interactive/transactional but do the same thing

sgdisk --zap-all /dev/disk/by-id/<disk0>
sgdisk -n1:0:+512M -t1:ef00 /dev/disk/by-id/<disk0>
sgdisk -n2:0:+210G -t2:bf00 /dev/disk/by-id/<disk0>
### sgdisk -n2:0:+8G -t2:8200 /dev/disk/by-id/<disk0>
### Not using a swap parition but could consider ZRAM in future ?
### The EFI partition will just be for EFI applications and will be mounted to /boot/efi - the kernel will be in /boot
mkfs.vfat /dev/xxx1
I have also created another zpool: bakpool with data set archzfs on a seperate internal ssd to test stuff. This should mount at /mnt/backpool/archzfs
Create the zpool
zpool create -f -o ashift=12 \
-O acltype=posixacl \
-O relatime=on \
-O xattr=sa \
-O dnodesize=legacy \
-O normalization=formD \
-O mountpoint=none \
-O canmount=off
-O compression=lz4 \
-O devices=off \
-R /mnt \
zroot /dev/disk/by-id/id-to-partition-partx
\### Use the /dev/disk/by-id/id for this found by ls /dev/disk/by-id/
Create the datasets
zfs create -o canmount=off -o mountpoint=none rpool/ROOT
zfs create -o mountpoint=/ -o canmount=noauto rpool/ROOT/default
zfs create -o mountpoint=none rpool/DATA
zfs create -o mountpoint=/home rpool/DATA/home
zfs create -o mountpoint=/root rpool/DATA/home/root
zfs create -o mountpoint=/local rpool/DATA/local
zfs create -o mountpoint=none rpool/DATA/var
zfs create -o mountpoint=/var/log rpool/DATA/var/log # after a rollback, systemd-journal blocks at reboot without this dataset
\### give the dataset you want to boot from a boot flag
zpool set bootfs=rpool/ROOT/default rpool
Sanity check zpool before proceeding
\### If no errors then able to proceed to install arch in zpool
zfs umount -a
rm -rf /mnt/*
zpool export rpool
zpool import -d /dev/disk/by-id -R /mnt rpool -N
\### The root pool should be mounted first, then the rest
zfs mount rpool/ROOT/default /mnt
zfs mount -a
\### Mount the EFI partition to /boot/efi (NOT to /boot)
mkdir /mnt/boot/efi
mount /dev/xxx1 /mnt/boot/efi
Prepare the new system
mkdir /mnt/etc
genfstab -U /mnt >> /mnt/etc/fstab
pacstrap /mnt base base-devel linux linux-firmware vim
arch-chroot /mnt
In chroot
Remove all lines in /etc/fstab leaving just efi partition mount to /boot/efi
\### add the archzfs repor to /etc/pacman.conf
[archzfs]
Server = http://archzfs.com/$repo/x86_64
\### Add GPG Keys
curl -O https://archzfs.com/archzfs.gpg
pacman-key -a archzfs.gpg
pacman-key --lsign-key DDF7DB817396A49B2A2723F7403BD972F75D9D76
pacman -Syy
\### Timezone
ln -sf /usr/share/zoneinfo/Region/City /etc/localtime
hwclock --systohc
\### Generate locale
sed -i 's/#\(en_US\.UTF-8\)/\1/' /etc/locale.gen
locale-gen
echo "LANG=en_US.UTF-8" > /etc/locale.conf
\### Set root password
passwd
\### Install important stuff, esp. archzfs-linux!!!
pacman -Syu archzfs-linux amd-ucode sudo openssh git neovim
\### Generate hostid
zgenidhost $(hostid)
\### Generate cache file - Important!
zfs set cachefile=/etc/zfs/zpool.cache zroot
\### edit /etc/mkinitcpio.conf and make sure zfs is added
HOOKS=(base udev autodetect modconf block keyboard zfs filesystems)
\##**regenerate**{: .hash} initramfs
mkinitcpio -p linux
Enable services
\### ZFS specific services
systemctl enable zfs.target
systemctl enable zfs-import-cache
systemctl enable zfs-mount
systemctl enable zfs-import.target
\### create an entry for wired ethernet in /etc/systemd/network/20-wired.network
[Match]
Name=enp6s0
[Network]
DHCP=yes
\### Network and other services
systemctl enable systemd-networkd
systemctl enable systemd-resolved
systemctl enable sshd
Create a user
useradd -m -G wheel,adm -s /bin/bash username
\### -m creates /home/username but need to change permissions
chown -R username:group /home/username && chmod 700 /home/username
passwd username
EDITOR=vim visudo
\### uncommment wheel line
\### su and install paru as a normal user
sudo pacman -S --needed base-devel
git clone https://aur.archlinux.org/paru.git
cd paru
makepkg -si
Bootloader
Switch back to root - su and see # prompt
Mount your ESP to /boot/efi
Install zfsbootmenuAUR and efibootmgr
Configure ZFSBootMenu
\### /etc/zfsbootmenu/config.yaml
Global:
ManageImages: true
BootMountPoint: path_to_your_ESP
DracutConfDir: /etc/zfsbootmenu/dracut.conf.d
PreHooksDir: /etc/zfsbootmenu/generate-zbm.pre.d
PostHooksDir: /etc/zfsbootmenu/generate-zbm.post.d
InitCPIO: true
InitCPIOConfig: /etc/zfsbootmenu/mkinitcpio.conf
Components:
ImageDir: path_to_your_ESP/EFI/zbm
Versions: 3
Enabled: false
syslinux:
Config: /boot/syslinux/syslinux.cfg
Enabled: false
EFI:
ImageDir: path_to_your_ESP/EFI/zbm
Versions: false
Enabled: true
Kernel:
CommandLine: ro quiet loglevel=0
Generate a ZFSBootMenu image
generate-zbm
Configure zfs boot commandline arguments
zfs set org.zfsbootmenu:commandline="rw" zroot/ROOT/default
Add a ZFSBootMenu entry to EFI boot manager
efibootmgr -c -d your_esp_disk -p your_esp_partition_number -L "ZFSBootMenu" -l '\EFI\zbm\vmlinuz-linux.EFI'
Exit and reboot
exit
zfs umount -a
umount -R /mnt
zpool export rpool
\### cross fingers and reboot
reboot