Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ManuelSchmitzberger/4e284069f225cdc8f001c0c5ded695a4 to your computer and use it in GitHub Desktop.
Save ManuelSchmitzberger/4e284069f225cdc8f001c0c5ded695a4 to your computer and use it in GitHub Desktop.
ZFSRoot installation over a dm-crypt volume for Arch Linux (UEFI)

Install Arch Linux on root ZFS filesystem

Pre-installation

Download Arch linux

https://archlinux.org

Create bootable USB (don't add partition number!)

# dd bs=4M if=/path/to/archlinux.iso of=/dev/sdx status=progress && sync

Reboot into newly created Arch USB

Installation

Connect to the internet (if not using wired cable)

# wifi-menu

SSH connection

# useradd -M -G wheel -s /usr/bin/zsh ssh_user
# echo "ssh_user:ssh_user-password"|chpasswd
# echo "root:root-password"|chpasswd
# systemctl start sshd.service

Increase cowspace

# mount -o remount,size=10G /run/archiso/cowspace

Add the ZFS repo to pacman configuration OR skip if it's already in the iso

# vim /etc/pacman.conf
----------------------
[archzfs]
Server = http://archzfs.com/$repo/$arch

Add the ZFS repo gpg keys to pacman's keyring

# pacman-key -r F75D9D76
# pacman-key --lsign-key F75D9D76

Install the zfs-linux packages inside archiso environment

# pacman -Sy linux-headers zfs-linux zfs-utils

Load the ZFS kernel module and create empty ZFS pool cache file

# modprobe zfs
# touch /etc/zfs/zpool.cache

Partition the disk

# wipefs -a /dev/sdx
# parted /dev/sdx
-----------------
(parted) mklabel gpt
(parted) mkpart ESP fat32 1MiB 1GiB
(parted) name 1 boot
(parted) set 1 boot on
(parted) mkpart primary ext4 1GiB 99%
(parted) name 2 root

Create and open encrypted container on system partition

# cryptsetup luksFormat --type luks2 -v -s 512 /dev/sdx2
# cryptsetup open /dev/sdx2 cryptroot

Create the ZFS pool and base datasets onto encrypted container

canmount=off makes it so actual data is stored inside the parent dataset; but the hierarchical structure exists for possible children.

Double check before you run any of these; not all are necessarily required either

# zpool create -o ashift=12 -o cachefile=/etc/zfs/zpool.cache -m none -R /mnt zroot /dev/mapper/cryptroot
# zfs create -o mountpoint=none -o compression=lz4 zroot/ROOT
# zfs create -o mountpoint=/ zroot/ROOT/default
# zfs create -o mountpoint=/root zroot/home/root
# zfs create -o mountpoint=/home/<username> zroot/home/<username>
# zpool set bootfs=zroot zroot
# zfs set relatime=on zroot
# zfs set compression=lz4 zroot

Create swap zvol

# zfs create -V 16G -b 4096 -o logbias=throughput -o sync=always -o primarycache=metadata -o com.sun:auto-snapshot=false zroot/swap
# mkswap -f /dev/zvol/zroot/swap

Export and import (and mount) the new ZFS filesystem into /mnt

# zpool export zroot
# zpool import -R /mnt zroot

Mount /boot into /mnt/boot

# mkdir /mnt/boot
# mount /dev/sdx1 /mnt/boot

Install base Arch Linux system into /mnt

# pacstrap -i /mnt base base-devel

Generate /boot mount options and pipe them into fstab

# genfstab -U -p /mnt | grep boot >> /mnt/etc/fstab

Add the swap volume to fstab

# vim /mnt/etc/fstab
--------------------
/dev/zvol/zroot/swap none swap discard 0 0

Chroot into the Arch installation on /mnt

# arch-chroot /mnt /bin/bash

Set locale

# vi /etc/locale.gen
--------------------
Uncomment en_US.UTF-8 UTF-8

# locale-gen

# vi /etc/locale.conf
---------------------
LANG=en_US.UTF-8

Install vim

# pacman -S vim

Set console font

# pacman -S terminus-font

Add the ZFS repository to pacman configuration in the actual install too

# vim /etc/pacman.conf
----------------------
[archzfs]
Server = http://archzfs.com/$repo/$arch
SigLevel = Never

Add the ZFS repository gpg keys to pacman's keyring

# pacman-key -r F75D9D76
# pacman-key --lsign-key F75D9D76

Install ZFS into new install

# pacman -Sy linux-headers zfs-linux zfs-utils

Enable the ZFS system services

# systemctl enable zfs.target
# systemctl enable zfs-import-cache
# systemctl enable zfs-mount

Set max ZFS arc memory usage to 2GB

# vim /etc/modprobe.d/zfs.conf
------------------------------
options scsi_mod scan=sync
# ARC
#options zfs zfs_arc_max=4294967296
# 6 gb
#options zfs zfs_arc_max=6442450944
# 10 gb
options zfs zfs_arc_max=10737418240

# metadata limit
# 5 gb
options zfs zfs_arc_meta_limit=5368709120

Update mkinitcpio hooks to include LUKS disk encryption and ZFS

# vim /etc/mkinitcpio.conf
--------------------------
HOOKS=(base udev autodetect modconf block filesystems keyboard fsck consolefont keymap encrypt zfs)

Regenerate kernel image with the new hooks

# mkinitcpio -p linux

Set root user password

# passwd

Set machine hostname

# vim /etc/hostname
-------------------
<hostname>

Install bootloader

# bootctl --path=/boot install

# vim /boot/loader/loader.conf
------------------------------
default arch
timeout 4
editor 0

Temporarily save system partition UUID into a file for easy copying in vim

# blkid /dev/sdx2 > partitionid.txt

Create the main boot entry (add UUID from partitionid.txt)

# vim /boot/loader/entries/arch.conf
------------------------------------
title Arch Linux
linux /vmlinuz-linux
initrd /initramfs-linux.img
options cryptdevice=UUID=<UUID>:cryptroot:allow-discards zfs=zroot/ROOT/default rw pcie_aspm=force

Create fallback boot entry (add UUID from partitionid.txt)

# vim /boot/loader/entries/arch-fallback.conf
---------------------------------------------
title Arch Linux Fallback
linux /vmlinuz-linux
initrd /initramfs-linux-fallback.img
options cryptdevice=UUID=<UUID>:cryptroot:allow-discards zfs=zroot/ROOT/default rw

Install some other necessary packages for network, etc, and enable their services

# pacman -S openssh tlp smartmontools ethtool x86_energy_perf_policy wpa_supplicant inetutils netctl iwd wireless-regdb dialog netctl iwd dhcpcd util-linux device-mapper cryptsetup

Leave chroot environment

# exit

Copy the ZFS cache file into system

# cp /etc/zfs/zpool.cache /mnt/etc/zfs/

Unmount /boot and export the ZFS filesystem

# umount /mnt/boot
# zpool export zroot

Reboot into new install

# reboot

Post-installation

Set up NetworkManager wifi connection

# nmcli d wifi list
# nmcli dev wifi connect <SSID> password <password>
# ping google.com

Install zsh (optional) and create user account

# pacman -S zsh
# useradd -m -G wheel -s /bin/zsh <username>
# zfs allow <username> create,mount,mountpoint,snapshot zroot/home/<username>
# chown -R <username> /home/<username>

Set password for new user

# passwd <username>

Allow users in wheel group to use sudo

# visudo
--------
Uncomment %wheel ALL=(ALL) ALL

Install xorg and other useful packages

# pacman -S rsync xorg-server xf86-video-intel xorg-xinit xorg-xrandr i3 pulseaudio pavucontrol termite conky git libyaml gcc6 imagemagick xorg-xbacklight mpv notify-osd ttf-inconsolata ttf-bitstream-vera ttf-dejavu ttf-droid ttf-fira-mono ttf-fira-sans ttf-freefont ttf-liberation ttf-roboto ttf-ubuntu-font-family

Log out as root and log back in as user

# exit

Copy system xinitrc to home directory and run i3 instead

$ cp /etc/X11/xinit/xinitrc .xinitrc

$ vim .xinitrc
--------------
exec i3

Fix HiDPI scaling

$ gsettings set org.gnome.desktop.interface scaling-factor 2

$ vim .Xresources
-----------------
Xft.dpi: 166
Xft.autohint: false
Xft.hintstyle: hintslight
Xft.lcdfilter: lcddefault
Xft.hinting: true
Xft.antialias: true
Xft.rgba: rgb

Start X11

$ startx

Start a terminal with Alt+Enter

Set keyboard layout

$ setxkbmap be

etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment