## Installing Manjaro on ZFS root using systemd-boot \[UEFI only\] References:\[ [manjaro-cli-install](https://forum.manjaro.org/t/howto-install-manjaro-using-cli-only/108203) | [john_ransden-arch on ZFS](https://ramsdenj.com/2016/06/23/arch-linux-on-zfs-part-2-installation.html#efi-bootloader) | [arch-systemd-boot-wiki](https://wiki.archlinux.org/index.php/Systemd-boot) \] - Start from manjaro architect \[ [download](https://manjaro.org/download/official/architect/) \] - login as `manjaro` password `manjaro` - Install necessary packages: ``` sudo -i # become root systemctl enable --now systemd-timesyncd # sync time using NTP pacman -Sy pacman -S --noconfirm openssh # edit /etc/ssh/sshd_config to have 'PermitRootLogin yes` line # sed -i -E 's/^#PermitRootLogin.*$/PermitRootLogin yes/g' /etc/ssh/sshd_config # echo "root:any" | chpasswd # change root password to 'any' systemctl start sshd ; systemctl status sshd ip addr show # note ip address ``` - You can now ssh into the box. Login as `manjaro` password `manjaro`: - Become root: ``` sudo -i ``` - Setup pacman: ``` pacman-mirrors --country-list # list all pacman mirror countries pacman-mirrors --api --set-branch stable --country United_States,Singapore,Canada pacman -Sy ``` - Install keysrings and create trust database and refresh keys ``` pacman -S --noconfirm pacman archlinux-keyring manjaro-keyring ntp pacman-key --init pacman-key --populate archlinux manjaro pacman-key --refresh-keys ``` - Install zfs ``` pacman -S --noconfirm linux54-zfs # install ZFS modprobe zfs # load zfs module lsmod | grep zfs # see zfs module loaded zfs --version # check version ``` - Set `DISK1` and `DISK2` variables and erase them - `ls -lF /dev/disk/by-id` and set the UUID of your own hard disks ``` DISK1=/dev/disk/by-id/ata-VBOX_HARDDISK_VB18c0305d-4e63e5c6 # use your own DISK2=/dev/disk/by-id/ata-VBOX_HARDDISK_VB0a4a9fa5-eb40797e # use your own pacman -S --noconfirm gptfdisk sgdisk --zap-all $DISK1 sgdisk --zap-all $DISK2 udevadm settle; sleep 1 ``` - create UEFI partition for booting: ``` sgdisk -n1:1M:+512M -t1:EF00 $DISK1 sgdisk -n1:1M:+512M -t1:EF00 $DISK2 udevadm settle; sleep 1 mkfs.fat -F 32 -n EFI ${DISK1}-part1 mkfs.fat -F 32 -n EFI ${DISK2}-part1 ``` - create ZFS partitions for root: ``` sgdisk -n2:0:0 -t2:BF00 $DISK1 sgdisk -n2:0:0 -t2:BF00 $DISK2 sleep 1 ``` - create zpool (use `ashift=13` for Samsung SSD): ``` ZROOT=zroot zpool create -o ashift=12 \ -O acltype=posixacl -O canmount=off -O compression=lz4 \ -O dnodesize=auto -O normalization=formD -O relatime=on -O xattr=sa \ -O mountpoint=none \ -f $ZROOT mirror ${DISK1}-part2 ${DISK2}-part2 ``` - create datasets ``` zfs create -o mountpoint=none $ZROOT/ROOT zfs create -o mountpoint=none $ZROOT/ROOT/manjaro zfs create -o mountpoint=none $ZROOT/data zfs create -o mountpoint=/mnt $ZROOT/ROOT/manjaro/root zfs create -o mountpoint=/mnt/home $ZROOT/data/home zfs create -o mountpoint=/mnt/home/root $ZROOT/data/root zfs create -o mountpoint=/mnt/var/cache/pacman $ZROOT/ROOT/manjaro/paccache ``` - unmount all zfs filesystems and set new mountpoints: ``` zfs unmount -a # unmount all zfs filesystems zfs set mountpoint=/ $ZROOT/ROOT/manjaro/root zfs set mountpoint=/home $ZROOT/data/home zfs set mountpoint=/root $ZROOT/data/root zfs set mountpoint=/var/cache/pacman $ZROOT/ROOT/manjaro/paccache ``` - edit `/etc/fstab` to include the above 4 datasets: ``` echo "# generated fstab # <file system> <dir> <type> <options> <dump> <pass> $ZROOT/ROOT/manjaro/root / zfs defaults,noatime 0 0 $ZROOT/ROOT/manjaro/paccache /var/cache/pacman zfs defaults,noatime 0 0 $ZROOT/data/root /root zfs defaults,noatime 0 0 $ZROOT/data/home /home zfs defaults,noatime 0 0" \ > /etc/fstab ``` - Set the bootfs property on the root filesystem. This command will only be successful when `dnodesize` property on `$ZROOT/ROOT/manjaro/root` is set to `legacy` \[ [ref](https://github.com/zfsonlinux/zfs/issues/8538) \] ``` zfs set dnodesize=legacy $ZROOT/ROOT/manjaro/root zpool set bootfs=$ZROOT/ROOT/manjaro/root $ZROOT ``` - Export & re-import pool: ``` zpool export $ZROOT zpool import -d /dev/disk/by-id -R /mnt $ZROOT # mount -t zfs $ZROOT/ROOT/manjaro/paccache /mnt/var/cache/pacman # must use "mount" for legacy zfs datasets # mount -t zfs $ZROOT/data/home /mnt/home # must use "mount" for legacy zfs datasets ``` - check the work: ``` findmnt | grep /mnt # check that /mnt, /mnt/root, /mnt/home, /mnt/var/cache/pacman are mounted ``` - use `basestrap` to install base set of packages into `/mnt` ``` basestrap /mnt base linux54-zfs intel-ucode systemd-boot-manager mkinitcpio \ gptfdisk dosfstools zfs-utils \ dhcpcd networkmanager openssh ntp \ vi nano sudo man which bash-completion pv # removed - grub efibootmgr ``` - edit `/mnt/etc/mkinitcpio.conf` and change `HOOKS` line to be: `HOOKS=(base udev autodetect modconf block keyboard zfs filesystems)` ``` sed -i.bak -E 's/^(HOOKS=.*)$/#\1\nHOOKS=\(base udev autodetect modconf block keyboard zfs filesystems\)/g' /mnt/etc/mkinitcpio.conf cat /mnt/etc/mkinitcpio.conf # verify it ``` - copy `/etc/fstab` to new installation: ``` cp /etc/fstab /mnt/etc/fstab.old # keep old fstab fstabgen -U /mnt >> /mnt/etc/fstab # generate new fstab ``` - since we mounted `/var/cache/pacman`, `/home`, and `/root` via ZFS (non-legacy), we need to remove these entries from the new `/mnt/etc/fstab` ``` sed -i -E 's/^('"$ZROOT"'\/data.*)$/#\1/g; s/^('"$ZROOT"'\/ROOT\/manjaro\/paccache.*)/#\1/g' /mnt/etc/fstab ``` - chroot into new installation: ``` manjaro-chroot /mnt /usr/bin/env DISK1=$DISK1 DISK2=$DISK2 ZROOT=$ZROOT /bin/bash ``` - set timezone: ``` rm -rf /etc/localtime ln -sf /usr/share/zoneinfo/Asia/Bangkok /etc/localtime hwclock --systohc --utc # generate /etc/adjtime and set HW RTC to UTC ``` - generate locales: ``` sed -iE 's/^#en_US.UTF-8/en_US.UTF-8/g' /etc/locale.gen # uncomment en_US.UTF-8 locale-gen echo LANG=en_US.UTF-8 > /etc/locale.conf export LANG=en_US.UTF-8 ``` - set hostname and edit `/etc/hosts` file: ``` # call it whatever you want HOSTNAME=manjaz echo $HOSTNAME > /etc/hostname echo "# setup 127.0.0.1 localhost ::1 localhost 127.0.1.1 $HOSTNAME" >> /etc/hosts ``` - Allow members of `wheel` group to admin machine: `EDITOR=nano visudo` and choose 1. or 2. 1. Uncomment `%wheel ALL=(ALL) ALL` -- `sudo` would require a password **or** 2. Uncomment `%wheel ALL=(ALL) NOPASSWD: ALL` -- `sudo` does not require a password - enable dhcp client and NTP client: ``` systemctl enable dhcpcd systemctl enable systemd-timesyncd ``` - set root password: ``` echo "root:abc" | chpasswd # change root password to `abc` ``` #### systemd-boot Bootloader - make initramfs: ``` mkinitcpio -P # mkinitcpio -p linux54 ``` - create EFI paritions mount points and add them to `/etc/fstab`: ``` mkdir -p /boot1 mkdir -p /boot2 echo PARTUUID=$(blkid -s PARTUUID -o value ${DISK1}-part1) \ /boot1 vfat nofail,x-systemd.device-timeout=1 0 1 >> /etc/fstab echo PARTUUID=$(blkid -s PARTUUID -o value ${DISK2}-part1) \ /boot2 vfat nofail,x-systemd.device-timeout=1 0 1 >> /etc/fstab ``` - mount `/boot1` and `/boot2`: ``` mount /boot1 mount /boot2 ``` - install systemd-boot ``` cp -r /boot/* /boot1 cp -r /boot/* /boot2 bootctl --path=/boot1 install bootctl --path=/boot2 install ``` - patch sdboot-manage and create manjaro entries ``` cp /usr/bin/sdboot-manage ~/sdboot-manage # patch sdboot-manage so it works with directories other than /boot or /efi sed -i -E 's/^(bootctl=)(.*)$/\[\[ ! -z \$2 \]\] \&\& \[\[ ! \$2 =~ --esp-path=\.\+ \]\] \&\& exit 1\n\1"\2 ""\$2"/g' ~/sdboot-manage sed -i -E 's/^(.+[^$/])bootctl(.*)$/\1\$bootctl\2/g' ~/sdboot-manage ~/sdboot-manage gen --esp-path=/boot1 # create manjaro entries on /boot1 ~/sdboot-manage gen --esp-path=/boot2 # create manjaro entries on /boot2 ``` - check `sdboot-manage` work: ``` bootctl --path=/boot1 bootctl --path=/boot2 ``` - start sshd and enable root login (add `PermitRootLogin yes` to `/etc/ssh/sshd_config`): ``` sed -i -E 's/^(#PermitRootLogin.*)$/PermitRootLogin yes\n\1/g' /etc/ssh/sshd_config systemctl enable sshd ``` - Exit chroot and unmount filesystem ``` exit umount -R /mnt zfs umount -a ``` - set ZFS pool cachefile and export it: ``` zpool set cachefile=/etc/zfs/zpool.cache $ZROOT # <-- zroot here is our $ZROOT zpool export $ZROOT ``` - remove live media ``` ### remove the live media reboot # or "poweroff" ``` - reboot - after reboot, login as *root* - edit `/etc/pacman.conf` and scroll to `#IgnorePkg` and add: ``` IgnorePkg = linux54-zfs # so this package won't be updated ``` - add more packages: ``` pacman -S --noconfirm bash-completion pv ```