System Configuration

  1. Generate fstab:

    genfstab -U /mnt | sed 's;zfs[[:space:]]*;zfs zfsutil,;g' | grep "zfs zfsutil" >> /mnt/etc/fstab
    for i in ${DISK}; do
       echo UUID=$(blkid -s UUID -o value ${i}-part1) /boot/efis/${i##*/}-part1 vfat \
       x-systemd.idle-timeout=1min,x-systemd.automount,noauto,umask=0022,fmask=0022,dmask=0022 0 1 >> /mnt/etc/fstab
    done
    echo UUID=$(blkid -s UUID -o value ${INST_PRIMARY_DISK}-part1) /boot/efi vfat \
    x-systemd.idle-timeout=1min,x-systemd.automount,noauto,umask=0022,fmask=0022,dmask=0022 0 1 >> /mnt/etc/fstab
    if [ "${INST_PARTSIZE_SWAP}" != "" ]; then
     for i in ${DISK}; do
      echo ${i##*/}-part4-swap ${i}-part4 /dev/urandom swap,cipher=aes-cbc-essiv:sha256,size=256,discard >> /mnt/etc/crypttab
      echo /dev/mapper/${i##*/}-part4-swap none swap x-systemd.requires=cryptsetup.target,defaults 0 0 >> /mnt/etc/fstab
     done
    fi
    

    By default, systemd will halt boot process if any entry in /etc/fstab fails to mount. This is unnecessary for mirrored EFI boot partitions. With the above mount options, systemd will skip mounting them at boot, only mount them on demand when accessed.

  2. Configure dracut:

    echo 'add_dracutmodules+=" zfs "' > /mnt/etc/dracut.conf.d/zfs.conf
    
  3. Interactively set locale, keymap, timezone, hostname and root password:

    rm -f /mnt/etc/localtime
    systemd-firstboot --root=/mnt --prompt --root-password=PASSWORD
    

    This can be non-interactive, see man page for details:

    rm -f /mnt/etc/localtime
    systemd-firstboot --root=/mnt \
     --locale="en_US.UTF-8" --locale-messages="en_US.UTF-8" \
     --keymap=us --timezone="Europe/Berlin" --hostname=myHost \
     --root-password=PASSWORD
    

    systemd-firstboot have bugs, root password is set below.

  4. Generate host id:

    zgenhostid -f -o /mnt/etc/hostid
    
  5. Install locale package, example for English locale:

    dnf --installroot=/mnt install -y glibc-minimal-langpack glibc-langpack-en
    

    Program will show errors if not installed.

  6. Enable ZFS services:

    systemctl enable zfs-import-scan.service zfs-import.target zfs-zed zfs.target --root=/mnt
    systemctl disable zfs-mount --root=/mnt
    

    At boot, datasets on rpool are mounted with /etc/fstab, which can control the mounting process more precisely than zfs-mount.service.

  7. By default SSH server is enabled, allowing root login by password, disable SSH server:

    systemctl disable sshd --root=/mnt
    systemctl enable firewalld --root=/mnt
    
  8. Chroot:

    echo "INST_PRIMARY_DISK=$INST_PRIMARY_DISK
    INST_LINVAR=$INST_LINVAR
    INST_UUID=$INST_UUID
    INST_ID=$INST_ID
    unalias -a
    TERM=xterm
    INST_VDEV=$INST_VDEV
    INST_VDEV=$INST_VDEV
    DISK=$DISK" > /mnt/root/chroot
    arch-chroot /mnt bash --login
    
  9. Source variables:

    source /root/chroot
    
  10. For SELinux, relabel filesystem on reboot:

    fixfiles -F onboot
    
  11. Set root password:

    passwd
    
  12. Build ZFS modules:

    ls -1 /lib/modules \
    | while read kernel_version; do
      dkms autoinstall -k $kernel_version
      done