Zfs configurations: Zfs on Root (Archlinux)

From wikinotes

Install

For instructions on adding ZFS to a customized Archlinux ISO (recovery, zfs-on-root, etc) see ArchISO zfs.

#### /etc/pacman.conf
#
# Enable ZFS repository
#
[archzfs]
Server = http://archzfs.com/$repo/x86_64
## I'm not sure if this is a failure on the maintainer's part, or
## if this is normal when using custom repositories - but I needed
## to force-trust jesus-alvarez's key
## source: http://archzfs.com/    (his website)
sudo pacman-key -r 0EE7A126
sudo pacman-key --lsign-key 0EE7A126
sudo pacman -S zfs-linux-git

## enable zfs 
systemctl enable zfs.target
systemctl start  zfs.target


WARNING:

occasionally archzfs will be out of date with the current kernel when you are attempting to set up a new system. If this occurs, you can use the abs system to download an old version of a the linux package, and compile it yourself. See Arch_ABS.

Prepare Disk

For additional info, see: Partition + Format.

## cfdisk
1   2M    BIOS boot partition
2 100M    EFI system
3 235M    Solaris Root
4 3.5M    Free Space    ## make sure to leave a bit of additional space at the end of the drive, so
                        ## new disks of the same advertised size, but slightly different capacities
                        ## can be swapped in painlessly
## Format EFI partition 
## (leave the other two alone - they will be managed by zfs)

mkfs.msdos -F 32 /dev/sda2

Creating ZPool

modprobe zfs

zpool create -f zroot /dev/disk/by-id/ata-Samsung_SSD_850_PRO_256GB_S1SNUWBF203326-part3   ## create zpool using disk-id (ALWAYS disk-id)

Creating FS Mounts

Aaah back in familiar territory now. The official Arch recommendations use a slightly different setup than FreeBSD that:

a) keeps your fs-root in a separate dataset than your home partition (nice for backups!)
b) uses separate mounts under zroot/ROOT/* so you can switch out different fs-roots (nice!!)

zfs create -o mountpoint=none   zroot/data
zfs create -o mountpoint=none   zroot/ROOT
zfs create -o mountpoint=/      zroot/ROOT/default
zfs create -o mountpoint=/home  zroot/data/home
## I'm not sure why we are once-again setting these options,
## could it be mounting zfs now?

zfs unmount -a	    ## unmount everything, and remount

zfs set mountpoint=/        zroot/ROOT/default
zfs set mountpoint=legacy   zroot/data/home
#### /etc/fstab
# fstab mounts happen before zfs is mounted.
# use zfs for all of your mounts.
#
zroot/ROOT/default  /      zfs defaults,noatime  0 0
zroot/data/home     /home  zfs  defaults,noatime 0 0
zpool  set    bootfs=zroot/ROOT/default   zroot			## tell ZFS where to find the operating system

zpool  export zroot
zpool  import -d /dev/disk/by-id   -R   /mnt   zroot	## !!! this is the by-id folder, not the disk itself
cp   /etc/zfs/zpool.cache  /mnt/etc/zfs/zpool.cache

Install Arch

At this stage, you should be able to perform a mostly-normal archlinux install into /mnt. Use the following instructions, and then I'll tell you where you can continue with the normal instructions:

## wireless internet
systemctl stop dhcpcd@enp0s25.service
wifi-menu -o wlp3s0

## ensure clock is correct (certs valid)
timedatectl set-ntp true

## install archlinux-base
pacstrap -i /mnt   base base-devel


## generate an fstab
genfstab -U -p /mnt >> /mnt/etc/fstab

chroot into system

arch-chroot /mnt

sudo pacman -S vim




You can now continue with the normal base-install from Define Locale. Only make sure that you ignore:

  • fstab setup
  • modifications to mkinitcpio/initramfs
  • Bootloader setup

Return here and continue (while still chrooted in) once normal setup is complete.


Install ZFS into new system

#### /mnt/etc/pacman.conf
#
# (while you're here, also uncomment multilib repo)
#

[archzfs]
Server = http://archzfs.com/$repo/x86_64
## import jesus-alvarez's gpg key into pacman keyring
sudo pacman-key -r 0EE7A126
sudo pacman-key --lsign-key 0EE7A126

## install archzfs-group
sudo pacman -S archzfs-linux-git

initramfs

#### /etc/mkinitcpio.conf
#
# modify your HOOKS= line to obey the following rules:
#    * zfs before filesystems
#    * keyboard before zfs
#    * if there are no ext3/4 filesystems (entirely zfs), remove fsck

# ex:
HOOKS="base udev autodetect modconf block keyboard zfs filesystems"


Now regenerate initramfs

mkinitcpio -p linux


Bootloader (UEFI)
Your options for bootloaders are more limited at the moment with the UEFI/zfs combo under linux. I'm going to be using systemd-boot (formerly gummiboot), because the recommended alternative looks like trash, and is not as configurable as I like.

The important changes are:

  • /etc/fstab: add mount for EFI partition
  • /boot/loader/entries/archlinux.conf: options zfs=<zfspoolname> rw


#### /etc/fstab
#
# mount EFI partition into /boot     (use `blkid` to get partition partuid's)
#
#
# NOTE: I'm a little confused about the order things are executed here,
#
#       The Arch documentation specifically says that fstab entries are
#       applied *BEFORE* zfs is mounted, so without waiting for zfs.service
#       to be enabled, your mount will happen 'underneath' the zfs mount.
#
#       However, we need this mount for the bootloader to work. it's possible
#       it is being mounted before zpool, and triggerig the loading of the zpool...

PARTUUID=098120808940981209380981247 /boot vfat defaults,discard 0 1


## (from the arch usb)

#!  make sure your main filesystem is mounted to /mnt  !#
#!  using the zpool export/import method listed above  !#

#! it is possible that /mnt/boot is already mounted by !#
#! the zfs option 'legacy'. I mounted the partition    !#
#! directly, I guess we'll see how this goes.          !#

mount /dev/sda2 /mnt/boot               # mount your EFI partition to /boot


arch-chroot /mnt                        # chroot into filesystem
 
pacman -S efivar efibootmgr dosfstools  # install dependencies
pacman -S linux linux-headers           # re-install linux now that EFI partition is mounted to /boot.
                                        #  ( you'll need the kernel in /boot to be able to boot )
 
bootctl --path=/boot install            # install bootloader
#### /boot/loader/loader.conf           # gummiboot loader configuration
default		archlinux
timeout		5
#### /boot/loader/entries/archlinux.conf # a sample gummiboot entry:
title   Arch Linux
linux   /vmlinuz-linux
initrd  /initramfs-linux.img
options zfs=bootfs rw          # references zroot's `set bootfs=/zroot/ROOT/default`

Unmounting Zpool (!!IMPORTANT!!)

This section is extremely important, because without performing this you can render your system un-bootable.

umount  /mnt/boot
zfs     umount -a
zpool export zroot

After First Boot

Upgrades

Upgrading zfs on linux can be frustrating because it generally only supports slightly out of date kernel versions. This is my workaround:

Ignore Kernel updates in /etc/pacman.conf when doing normal upgrades.

[options]
IgnorePkg = zfs-linux spl-linux spl-utils spl-utils-common zfs-utils-common linux linux-headers

When upgrading zfs:

# ===========================================
# comment out /etc/pacman.conf IgnorePkg line
# ===========================================

# may error because of kernel version.
sudo pacman -Syy
sudo pacaur -S zfs-linux spl-linux

# find url to package
firefox https://archive.archlinux.org/packages      

# install linux version ignoring conflicting packages (it will partially fail)
pacman -d -U \
    https://archive.archlinux.org/packages/l/linux/linux-4.15.3-2-x86_64.pkg.tar.xz \
    https://archive.archlinux.org/packages/l/linux-headers/linux-headers-4.15.3-2-x86_64.pkg.tar.xz

# now install the zfs packages
pacaur -S zfs-linux spl-linux

# ============================================
# replace your /etc/pacman.conf IgnorePkg line
# ============================================

sudo pacman -Syu