Arch Linux install on ZFS
Important
Please refer to the Arch Wiki for the official guide on how to install Arch Linux. These are my notes adapted from the Arch ZFS wiki
Download the latest archiso and boot to it.
Install the ZFS kernel modules
curl -s https://eoli3n.github.io/archzfs/init | sed 's- &>/dev/null--' | bash
Setup disk partitions
Note
In this guide we will be installing Arch Linux onto a root ZFS filesystem. To save some headache we won’t be using ZFS on our boot partition. We’ll be using GPT and UEFI as opposed to MBR. For the differences, please see this article
Using the parted
utility let’s create our partitions
parted /dev/sda
(parted) mklabel gpt
(parted) mkpart non-fs 0% 200
(parted) mkpart parimary 200 100%
(parted) set 1 esp on
(parted) set 1 boot on
Or we can run this all as one command using the --script
option
parted --script /dev/sda mklabel gpt mkpart non-fs 0% 200 mkpart primary 200 100% set 1 esp on set 1 boot on
Format our boot partition
mkfs.fat -F32 /dev/sda1
Create our zpool
Find the disk ID we’re going to be using for ZFS. You can find it by running ls /dev/disk/by-id
Warning
I’m using vmware and I couldn’t find anything listed in /dev/disk/by-id. I had to edit the settings of the VM to support it. In Edit Settings -> VM Options -> Advanced -> Edit Configuration add disk.EnableUUID TRUE
zpool create -f -o ashift=9 \
-O acltype=posixacl \
-O canmount=off \
-O compression=lz4 \
-O devices=off \
-O dnodesize=legacy \
-O mountpoint=none \
-O normalization=formD \
-O relatime=on \
-O xattr=sa \
-R /mnt \
zroot /dev/disk/by-id/scsi-36000c29168cfcdb14fb4e851f81025cf-part2
Create our data sets
zfs create -o mountpoint=none zroot/ROOT
zfs create -o mountpoint=/ -o canmount=noauto zroot/ROOT/default
zfs create -o mountpoint=none zroot/data
zfs create -o mountpoint=/home zroot/data/home
zfs create -o mountpoint=/root zroot/data/home/root
zfs create -o mountpoint=/var zroot/data/var
zfs create -o mountpoint=/var/log zroot/data/var/log
zfs create -o mountpoint=/tmp zroot/data/tmp
Export/import your datasets
To validate your configurations, export then reimport all your zpools.
Warning
Do not skip this, otherwise you will be required to use -f when importing your pools. This unloads the imported pool.
zpool export zroot; zpool import -d /dev/disk/by-id -R /mnt zroot -N
Remount your datasets:
zfs mount zroot/ROOT/default; zfs mount -a
Configure the root filesystem
Set the bootfs property on the descendant root filesystem so the boot loader knows where to find the operating system.
mkdir -p /mnt/etc/zfs; zpool set cachefile=/etc/zfs/zpool.cache zroot; cp /etc/zfs/zpool.cache /mnt/etc/zfs/zpool.cache
Mount the the boot partition inside /mnt/boot
mkdir /mnt/boot; mount /dev/sda1 /mnt/boot
genfstab -U -p /mnt >> /mnt/etc/fstab.zfs
Bootstrap your arch system
pacstrap /mnt base zfs-linux-lts vim
Create/enter the chroot
arch-chroot /mnt
Add the ZFS repo to pacman
cat << EOF >> /etc/pacman.conf
[archzfs]
Server = http://archzfs.com/archzfs/x86_64
Server = http://mirror.sum7.eu/archlinux/archzfs/archzfs/x86_64
Server = https://mirror.biocrafting.net/archlinux/archzfs/archzfs/x86_64
EOF
Some basic arch configs
Set local timezone and create /etc/adjtime
ln -sf /usr/share/zoneinfo/America/Los_Angeles /etc/localtime
hwclock --systohc
set and generate locale
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
locale-gen
echo "LANG=en_US.UTF-8" > /etc/locale.conf
Set the host name
hostnamectl set-hostname <hostname>
Adjust the hosts file
cat << EOF >> /etc/hosts
127.0.0.1 localhost.localdomain localhost
::1 localhost6.localdomain localhost6
192.168.1.250 $myhostname.$mydomain $myhostname
2001:470:8050:1::250 $myhostname.$mydomain $myhostname
EOF
Enable NTP daemon
timedatectl set-ntp true
Configure networking
DHCP
cat << EOF > /etc/systemd/network/eth0.network
[Match]
Name=eth0
[Network]
DHCP=yes
EOF
Static
cat << EOF > /etc/systemd/network/eth0.network
[Match]
Name=eth0
[Network]
Address=192.168.1.250/24
Gateway=192.168.1.1
DNS=192.168.1.53
Address=2001:470:8050:1::250/64
Gateway=2001:470:8050:1::1
DNS=2001:470:8050:1::53
EOF
Then enable networking at startup
systemctl enable systemd-networkd
systemctl enable systemd-resolved
Set the root password
passwd
Configure systemd-boot
mkdir -p /boot/loader/entries
cat << EOF > /boot/loader/loader.conf
default arch
console-mode max
timeout 5
EOF
cat << EOF > /boot/loader/entries/arch.conf
title Arch Linux
linux /vmlinuz-linux-lts
initrd /initramfs-linux-lts.img
options net.ifnames=0 zfs=zroot/ROOT/default rw
EOF
bootctl --path=/boot install
Configure systemd ZFS mounts
zpool set cachefile=/etc/zfs/zpool.cache zroot
systemctl enable zfs.target
systemctl enable zfs-import-cache
systemctl enable zfs-mount
systemctl enable zfs-import.target
rm /etc/hostid && zgenhostid $(hostid)
Update /etc/mkinitcpio.conf
and regen the initrd
sed -i 's|^HOOKS.*|HOOKS=\"base udev autodetect modconf block keyboard zfs filesystems\"|g' /etc/mkinitcpio.conf
mkinitcpio -p linux-lts
Got swap?
zfs create -V 2G -b $(getconf PAGESIZE) \
-o compression=lz4 \
-o logbias=throughput \
-o sync=always \
-o primarycache=metadata \
-o secondarycache=none \
-o com.sun:auto-snapshot=false \
zroot/swap
mkswap /dev/zvol/zroot/swap
swapon /dev/zvol/zroot/swap
echo "/dev/zvol/zroot/swap none swap discard 0 0" >> /etc/fstab
Lose the swap
swapoff /dev/zvol/zroot/swap
zfs destroy zroot/swap