Alpine, Arch Linux, Fedora, RHEL, NixOS Root on ZFS guide: add CI/CD tests

Remove unmaintained Arch Linux guides.

Signed-off-by: Maurice Zhou <yuchen@apvc.uk>
This commit is contained in:
Maurice Zhou
2023-04-05 12:46:27 +02:00
committed by George Melikov
parent a67d02b8ac
commit 4fb5fb694f
43 changed files with 3655 additions and 2519 deletions

View File

@@ -1,11 +0,0 @@
Fedora Root on ZFS
======================
Start from "Preparation".
Contents
--------
.. toctree::
:maxdepth: 2
:glob:
Root on ZFS/*

View File

@@ -0,0 +1,729 @@
.. highlight:: sh
.. ifconfig:: zfs_root_test
::
# For the CI/CD test run of this guide,
# Enable verbose logging of bash shell and fail immediately when
# a commmand fails.
set -vxeuf
distro=${1}
cp /etc/resolv.conf ./"rootfs-${distro}"/etc/resolv.conf
arch-chroot ./"rootfs-${distro}" sh <<-'ZFS_ROOT_GUIDE_TEST'
set -vxeuf
# install alpine setup scripts
apk update
apk add alpine-conf curl
.. In this document, there are three types of code-block markups:
``::`` are commands intended for both the vm test and the users
``.. ifconfig:: zfs_root_test`` are commands intended only for vm test
``.. code-block:: sh`` are commands intended only for users
Fedora Root on ZFS
=======================================
**Customization**
Unless stated otherwise, it is not recommended to customize system
configuration before reboot.
Preparation
---------------------------
#. Disable Secure Boot. ZFS modules can not be loaded if Secure Boot is enabled.
#. Because the kernel of latest Live CD might be incompatible with
ZFS, we will use Alpine Linux Extended, which ships with ZFS by
default.
Download latest extended variant of `Alpine Linux
live image
<https://dl-cdn.alpinelinux.org/alpine/v3.17/releases/x86_64/alpine-extended-3.17.3-x86_64.iso>`__,
verify `checksum <https://dl-cdn.alpinelinux.org/alpine/v3.17/releases/x86_64/alpine-extended-3.17.3-x86_64.iso.asc>`__
and boot from it.
.. code-block:: sh
gpg --auto-key-retrieve --keyserver hkps://keyserver.ubuntu.com --verify alpine-extended-*.asc
dd if=input-file of=output-file bs=1M
.. ifconfig:: zfs_root_test
# check whether the download page exists
# alpine version must be in sync with ci/cd test chroot tarball
#. Login as root user. There is no password.
#. Configure Internet
.. code-block:: sh
setup-interfaces -r
# You must use "-r" option to start networking services properly
# example:
network interface: wlan0
WiFi name: <ssid>
ip address: dhcp
<enter done to finish network config>
manual netconfig: n
#. If you are using wireless network and it is not shown, see `Alpine
Linux wiki
<https://wiki.alpinelinux.org/wiki/Wi-Fi#wpa_supplicant>`__ for
further details. ``wpa_supplicant`` can be installed with ``apk
add wpa_supplicant`` without internet connection.
#. Configure SSH server
.. code-block:: sh
setup-sshd
# example:
ssh server: openssh
allow root: "prohibit-password" or "yes"
ssh key: "none" or "<public key>"
#. Set root password or ``/root/.ssh/authorized_keys``.
#. Connect from another computer
.. code-block:: sh
ssh root@192.168.1.91
#. Configure NTP client for time synchronization
.. code-block:: sh
setup-ntp busybox
.. ifconfig:: zfs_root_test
# this step is unnecessary for chroot and returns 1 when executed
#. Set up apk-repo. A list of available mirrors is shown.
Press space bar to continue
.. code-block:: sh
setup-apkrepos
#. Throughout this guide, we use predictable disk names generated by
udev
.. code-block:: sh
apk update
apk add eudev
setup-devd udev
.. ifconfig:: zfs_root_test
# for some reason, udev is extremely slow in chroot
# it is not needed for chroot anyway. so, skip this step
#. Target disk
List available disks with
.. code-block:: sh
find /dev/disk/by-id/
If virtio is used as disk bus, power off the VM and set serial numbers for disk.
For QEMU, use ``-drive format=raw,file=disk2.img,serial=AaBb``.
For libvirt, edit domain XML. See `this page
<https://bugzilla.redhat.com/show_bug.cgi?id=1245013>`__ for examples.
Declare disk array
.. code-block:: sh
DISK='/dev/disk/by-id/ata-FOO /dev/disk/by-id/nvme-BAR'
For single disk installation, use
.. code-block:: sh
DISK='/dev/disk/by-id/disk1'
.. ifconfig:: zfs_root_test
# for github test run, use chroot and loop devices
DISK="$(losetup -a| grep fedora | cut -f1 -d: | xargs -t -I '{}' printf '{} ')"
#. Set a mount point
::
MNT=$(mktemp -d)
#. Set partition size:
Set swap size in GB, set to 1 if you don't want swap to
take up too much space
.. code-block:: sh
SWAPSIZE=4
.. ifconfig:: zfs_root_test
# For the test run, use 1GB swap space to avoid hitting CI/CD
# quota
SWAPSIZE=1
Set how much space should be left at the end of the disk, minimum 1GB
::
RESERVE=1
#. Install ZFS support from live media::
apk add zfs
#. Install partition tool
::
apk add parted e2fsprogs cryptsetup util-linux
System Installation
---------------------------
#. Partition the disks.
Note: you must clear all existing partition tables and data structures from the disks,
especially those with existing ZFS pools or mdraid and those that have been used as live media.
Those data structures may interfere with boot process.
For flash-based storage, this can be done by uncommenting the blkdiscard command below:
::
partition_disk () {
local disk="${1}"
#blkdiscard -f "${disk}"
parted --script --align=optimal "${disk}" -- \
mklabel gpt \
mkpart EFI 2MiB 1GiB \
mkpart bpool 1GiB 5GiB \
mkpart rpool 5GiB -$((SWAPSIZE + RESERVE))GiB \
mkpart swap -$((SWAPSIZE + RESERVE))GiB -"${RESERVE}"GiB \
mkpart BIOS 1MiB 2MiB \
set 1 esp on \
set 5 bios_grub on \
set 5 legacy_boot on
partprobe "${disk}"
}
for i in ${DISK}; do
partition_disk "${i}"
done
.. ifconfig:: zfs_root_test
::
# When working with GitHub chroot runners, we are using loop
# devices as installation target. However, the alias support for
# loop device was just introduced in March 2023. See
# https://github.com/systemd/systemd/pull/26693
# For now, we will create the aliases maunally as a workaround
looppart="1 2 3 4 5"
for i in ${DISK}; do
for j in ${looppart}; do
if test -e "${i}p${j}"; then
ln -s "${i}p${j}" "${i}-part${j}"
fi
done
done
#. Setup encrypted swap. This is useful if the available memory is
small::
for i in ${DISK}; do
cryptsetup open --type plain --key-file /dev/random "${i}"-part4 "${i##*/}"-part4
mkswap /dev/mapper/"${i##*/}"-part4
swapon /dev/mapper/"${i##*/}"-part4
done
#. Load ZFS kernel module
.. code-block:: sh
modprobe zfs
#. Create boot pool
::
# shellcheck disable=SC2046
zpool create -d \
-o feature@async_destroy=enabled \
-o feature@bookmarks=enabled \
-o feature@embedded_data=enabled \
-o feature@empty_bpobj=enabled \
-o feature@enabled_txg=enabled \
-o feature@extensible_dataset=enabled \
-o feature@filesystem_limits=enabled \
-o feature@hole_birth=enabled \
-o feature@large_blocks=enabled \
-o feature@lz4_compress=enabled \
-o feature@spacemap_histogram=enabled \
-o ashift=12 \
-o autotrim=on \
-O acltype=posixacl \
-O canmount=off \
-O compression=lz4 \
-O devices=off \
-O normalization=formD \
-O relatime=on \
-O xattr=sa \
-O mountpoint=/boot \
-R "${MNT}" \
bpool \
mirror \
$(for i in ${DISK}; do
printf '%s ' "${i}-part2";
done)
If not using a multi-disk setup, remove ``mirror``.
You should not need to customize any of the options for the boot pool.
GRUB does not support all of the zpool features. See ``spa_feature_names``
in `grub-core/fs/zfs/zfs.c
<http://git.savannah.gnu.org/cgit/grub.git/tree/grub-core/fs/zfs/zfs.c#n276>`__.
This step creates a separate boot pool for ``/boot`` with the features
limited to only those that GRUB supports, allowing the root pool to use
any/all features.
#. Create root pool
::
# shellcheck disable=SC2046
zpool create \
-o ashift=12 \
-o autotrim=on \
-R "${MNT}" \
-O acltype=posixacl \
-O canmount=off \
-O compression=zstd \
-O dnodesize=auto \
-O normalization=formD \
-O relatime=on \
-O xattr=sa \
-O mountpoint=/ \
rpool \
mirror \
$(for i in ${DISK}; do
printf '%s ' "${i}-part3";
done)
If not using a multi-disk setup, remove ``mirror``.
#. Create root system container:
- Unencrypted
::
zfs create \
-o canmount=off \
-o mountpoint=none \
rpool/fedora
- Encrypted:
Pick a strong password. Once compromised, changing password will not keep your
data safe. See ``zfs-change-key(8)`` for more info
.. code-block:: sh
zfs create \
-o canmount=off \
-o mountpoint=none \
-o encryption=on \
-o keylocation=prompt \
-o keyformat=passphrase \
rpool/fedora
You can automate this step (insecure) with: ``echo POOLPASS | zfs create ...``.
Create system datasets,
manage mountpoints with ``mountpoint=legacy``
::
zfs create -o canmount=noauto -o mountpoint=/ rpool/fedora/root
zfs mount rpool/fedora/root
zfs create -o mountpoint=legacy rpool/fedora/home
mkdir "${MNT}"/home
mount -t zfs rpool/fedora/home "${MNT}"/home
zfs create -o mountpoint=legacy rpool/fedora/var
zfs create -o mountpoint=legacy rpool/fedora/var/lib
zfs create -o mountpoint=legacy rpool/fedora/var/log
zfs create -o mountpoint=none bpool/fedora
zfs create -o mountpoint=legacy bpool/fedora/root
mkdir "${MNT}"/boot
mount -t zfs bpool/fedora/root "${MNT}"/boot
mkdir -p "${MNT}"/var/log
mkdir -p "${MNT}"/var/lib
mount -t zfs rpool/fedora/var/lib "${MNT}"/var/lib
mount -t zfs rpool/fedora/var/log "${MNT}"/var/log
#. Format and mount ESP
::
for i in ${DISK}; do
mkfs.vfat -n EFI "${i}"-part1
mkdir -p "${MNT}"/boot/efis/"${i##*/}"-part1
mount -t vfat -o iocharset=iso8859-1 "${i}"-part1 "${MNT}"/boot/efis/"${i##*/}"-part1
done
mkdir -p "${MNT}"/boot/efi
mount -t vfat -o iocharset=iso8859-1 "$(echo "${DISK}" | sed "s|^ *||" | cut -f1 -d' '|| true)"-part1 "${MNT}"/boot/efi
System Configuration
---------------------------
#. Download and extract minimal Fedora root filesystem::
apk add curl
curl --fail-early --fail -L \
https://dl.fedoraproject.org/pub/fedora/linux/releases/38/Container/x86_64/images/Fedora-Container-Base-38-1.6.x86_64.tar.xz \
-o rootfs.tar.gz
curl --fail-early --fail -L \
https://dl.fedoraproject.org/pub/fedora/linux/releases/38/Container/x86_64/images/Fedora-Container-38-1.6-x86_64-CHECKSUM \
-o checksum
# BusyBox sha256sum treats all lines in the checksum file
# as checksums and requires two spaces " "
# between filename and checksum
grep 'Container-Base' checksum \
| grep '^SHA256' \
| sed -E 's|.*= ([a-z0-9]*)$|\1 rootfs.tar.gz|' > ./sha256checksum
sha256sum -c ./sha256checksum
rootfs_tar=$(tar t -af rootfs.tar.gz | grep layer.tar)
rootfs_tar_dir=$(dirname "${rootfs_tar}")
tar x -af rootfs.tar.gz "${rootfs_tar}"
ln -s "${MNT}" "${MNT}"/"${rootfs_tar_dir}"
tar x -C "${MNT}" -af "${rootfs_tar}"
unlink "${MNT}"/"${rootfs_tar_dir}"
#. Enable community repo
.. code-block:: sh
sed -i '/edge/d' /etc/apk/repositories
sed -i -E 's/#(.*)community/\1community/' /etc/apk/repositories
#. Generate fstab::
apk add arch-install-scripts
genfstab -t PARTUUID "${MNT}" \
| grep -v swap \
| sed "s|vfat.*rw|vfat rw,x-systemd.idle-timeout=1min,x-systemd.automount,noauto,nofail|" \
> "${MNT}"/etc/fstab
#. Chroot
.. code-block:: sh
cp /etc/resolv.conf "${MNT}"/etc/resolv.conf
for i in /dev /proc /sys; do mkdir -p "${MNT}"/"${i}"; mount --rbind "${i}" "${MNT}"/"${i}"; done
chroot "${MNT}" /usr/bin/env DISK="${DISK}" bash
.. ifconfig:: zfs_root_test
cp /etc/resolv.conf "${MNT}"/etc/resolv.conf
for i in /dev /proc /sys; do mkdir -p "${MNT}"/"${i}"; mount --rbind "${i}" "${MNT}"/"${i}"; done
chroot "${MNT}" /usr/bin/env DISK="${DISK}" bash <<-'ZFS_ROOT_NESTED_CHROOT'
set -vxeuf
#. Unset all shell aliases, which can interfere with installation::
unalias -a
#. Install base packages
.. code-block:: sh
dnf -y install @core grub2-efi-x64 \
grub2-pc grub2-pc-modules grub2-efi-x64-modules shim-x64 \
efibootmgr kernel kernel-devel
.. ifconfig:: zfs_root_test
# no firmware for test
dnf -y install --setopt=install_weak_deps=False @core grub2-efi-x64 \
grub2-pc grub2-pc-modules grub2-efi-x64-modules shim-x64 \
efibootmgr
# kernel-core
#. Install ZFS packages
.. code-block:: sh
dnf -y install \
https://zfsonlinux.org/fedora/zfs-release-2-2$(rpm --eval "%{dist}").noarch.rpm
dnf -y install zfs zfs-dracut
.. ifconfig:: zfs_root_test
# this step will build zfs modules and fail
# no need to test building in chroot
#. Check whether ZFS modules are successfully built
.. code-block:: sh
tail -n10 /var/lib/dkms/zfs/**/build/make.log
# ERROR: modpost: GPL-incompatible module zfs.ko uses GPL-only symbol 'bio_start_io_acct'
# ERROR: modpost: GPL-incompatible module zfs.ko uses GPL-only symbol 'bio_end_io_acct_remapped'
# make[4]: [scripts/Makefile.modpost:138: /var/lib/dkms/zfs/2.1.9/build/module/Module.symvers] Error 1
# make[3]: [Makefile:1977: modpost] Error 2
# make[3]: Leaving directory '/usr/src/kernels/6.2.9-100.fc36.x86_64'
# make[2]: [Makefile:55: modules-Linux] Error 2
# make[2]: Leaving directory '/var/lib/dkms/zfs/2.1.9/build/module'
# make[1]: [Makefile:933: all-recursive] Error 1
# make[1]: Leaving directory '/var/lib/dkms/zfs/2.1.9/build'
# make: [Makefile:794: all] Error 2
If the build failed, you need to install an Long Term Support
kernel and its headers, then rebuild ZFS module
.. code-block:: sh
# this is a third-party repo!
# you have been warned.
#
# select a kernel from
# https://copr.fedorainfracloud.org/coprs/kwizart/
dnf copr enable -y kwizart/kernel-longterm-VERSION
dnf install -y kernel-longterm kernel-longterm-devel
dnf remove -y kernel-core
ZFS modules will be built as part of the kernel installation.
Check build log again with ``tail`` command.
#. Add zfs modules to dracut
.. code-block:: sh
echo 'add_dracutmodules+=" zfs "' >> /etc/dracut.conf.d/zfs.conf
echo 'force_drivers+=" zfs "' >> /etc/dracut.conf.d/zfs.conf
.. ifconfig:: zfs_root_test
# skip this in chroot, because we did not build zfs module
#. Add other drivers to dracut::
if grep mpt3sas /proc/modules; then
echo 'force_drivers+=" mpt3sas "' >> /etc/dracut.conf.d/zfs.conf
fi
if grep virtio_blk /proc/modules; then
echo 'filesystems+=" virtio_blk "' >> /etc/dracut.conf.d/fs.conf
fi
#. Build initrd
::
find -D exec /lib/modules -maxdepth 1 \
-mindepth 1 -type d \
-exec sh -vxc \
'if test -e "$1"/modules.dep;
then kernel=$(basename "$1");
dracut --verbose --force --kver "${kernel}";
fi' sh {} \;
#. For SELinux, relabel filesystem on reboot::
fixfiles -F onboot
#. Enable internet time synchronisation::
systemctl enable systemd-timesyncd
#. Generate host id
.. code-block:: sh
zgenhostid -f -o /etc/hostid
.. ifconfig:: zfs_root_test
# because zfs is not installed, skip this step
#. Install locale package, example for English locale::
dnf install -y glibc-minimal-langpack glibc-langpack-en
#. Set locale, keymap, timezone, hostname
::
rm -f /etc/localtime
systemd-firstboot \
--force \
--locale=en_US.UTF-8 \
--timezone=Etc/UTC \
--hostname=testhost \
--keymap=us
#. Set root passwd
::
printf 'root:yourpassword' | chpasswd
Bootloader
---------------------------
#. Apply GRUB workaround
::
echo 'export ZPOOL_VDEV_NAME_PATH=YES' >> /etc/profile.d/zpool_vdev_name_path.sh
# shellcheck disable=SC1091
. /etc/profile.d/zpool_vdev_name_path.sh
# GRUB fails to detect rpool name, hard code as "rpool"
sed -i "s|rpool=.*|rpool=rpool|" /etc/grub.d/10_linux
This workaround needs to be applied for every GRUB update, as the
update will overwrite the changes.
#. Fedora and RHEL uses Boot Loader Specification module for GRUB,
which does not support ZFS. Disable it::
echo 'GRUB_ENABLE_BLSCFG=false' >> /etc/default/grub
This means that you need to regenerate GRUB menu and mirror them
after every kernel update, otherwise computer will still boot old
kernel on reboot.
#. Install GRUB::
mkdir -p /boot/efi/fedora/grub-bootdir/i386-pc/
for i in ${DISK}; do
grub2-install --target=i386-pc --boot-directory \
/boot/efi/fedora/grub-bootdir/i386-pc/ "${i}"
done
dnf reinstall -y grub2-efi-x64 shim-x64
cp -r /usr/lib/grub/x86_64-efi/ /boot/efi/EFI/fedora/
#. Generate GRUB menu
.. code-block:: sh
mkdir -p /boot/grub2
grub2-mkconfig -o /boot/grub2/grub.cfg
cp /boot/grub2/grub.cfg \
/boot/efi/efi/fedora/grub.cfg
cp /boot/grub2/grub.cfg \
/boot/efi/fedora/grub-bootdir/i386-pc/grub2/grub.cfg
.. ifconfig:: zfs_root_test
# GRUB menu can not be generated in test due to missing zfs programs
#. For both legacy and EFI booting: mirror ESP content::
espdir=$(mktemp -d)
find /boot/efi/ -maxdepth 1 -mindepth 1 -type d -print0 \
| xargs -t -0I '{}' cp -r '{}' "${espdir}"
find "${espdir}" -maxdepth 1 -mindepth 1 -type d -print0 \
| xargs -t -0I '{}' sh -vxc "find /boot/efis/ -maxdepth 1 -mindepth 1 -type d -print0 | xargs -t -0I '[]' cp -r '{}' '[]'"
#. Exit chroot
.. code-block:: sh
exit
.. ifconfig:: zfs_root_test
# nested chroot ends here
ZFS_ROOT_NESTED_CHROOT
.. ifconfig:: zfs_root_test
::
# list contents of boot dir to confirm
# that the mirroring succeeded
find "${MNT}"/boot/efis/ -type d > list_of_efi_dirs
for i in ${DISK}; do
if ! grep "${i##*/}-part1/efi\|${i##*/}-part1/EFI" list_of_efi_dirs; then
echo "disk ${i} not found in efi system partition, installation error";
cat list_of_efi_dirs
exit 1
fi
done
#. Unmount filesystems and create initial system snapshot
You can later create a boot environment from this snapshot.
See `Root on ZFS maintenance page <../zfs_root_maintenance.html>`__.
::
umount -Rl "${MNT}"
zfs snapshot -r rpool@initial-installation
zfs snapshot -r bpool@initial-installation
#. Export all pools
.. code-block:: sh
zpool export -a
.. ifconfig:: zfs_root_test
# we are now inside a chroot, where the export will fail
# export pools when we are outside chroot
#. Reboot
.. code-block:: sh
reboot
#. For BIOS-legacy boot users only: the GRUB bootloader installed
might be unusable. In this case, see Bootloader Recovery section
in `Root on ZFS maintenance page <../zfs_root_maintenance.html>`__.
This issue is not related to Alpine Linux chroot, as Arch Linux
installed with this method does not have this issue.
UEFI bootloader is not affected by this issue.
.. ifconfig:: zfs_root_test
# chroot ends here
ZFS_ROOT_GUIDE_TEST
Post installaion
---------------------------
#. Install package groups
.. code-block:: sh
dnf group list --hidden -v # query package groups
dnf group install gnome-desktop
#. Add new user, configure swap.

View File

@@ -1,71 +0,0 @@
.. highlight:: sh
Preparation
======================
.. contents:: Table of Contents
:local:
#. Disable Secure Boot. ZFS modules can not be loaded if
Secure Boot is enabled.
#. Download live Fedora media, such as this `LXQt spin
<https://spins.fedoraproject.org/lxqt/download/index.html>`__.
The installed system is the same regardless of live
media used.
#. Connect to the Internet.
#. Set root password or ``/root/.ssh/authorized_keys``.
#. Start SSH server::
echo PermitRootLogin yes >> /etc/ssh/sshd_config
systemctl restart sshd
#. Connect from another computer::
ssh root@192.168.1.19
#. Target disk
List available disks with::
find /dev/disk/by-id/
If using virtio as disk bus, use ``/dev/disk/by-path/``.
Declare disk array::
DISK='/dev/disk/by-id/ata-FOO /dev/disk/by-id/nvme-BAR'
For single disk installation, use::
DISK='/dev/disk/by-id/disk1'
#. Set partition size:
Set swap size, set to 1 if you don't want swap to
take up too much space::
INST_PARTSIZE_SWAP=4
Root pool size, use all remaining disk space if not set::
INST_PARTSIZE_RPOOL=
#. Temporarily set SELinux to permissive in live environment::
setenforce 0
SELinux will be enabled on the installed system.
#. Add ZFS repo and install ZFS inside live system::
dnf install -y https://zfsonlinux.org/fedora/zfs-release-2-2$(rpm --eval "%{dist}").noarch.rpm
rpm -e --nodeps zfs-fuse || true
source /etc/os-release
export VERSION_ID
dnf install -y https://dl.fedoraproject.org/pub/fedora/linux/releases/${VERSION_ID}/Everything/x86_64/os/Packages/k/kernel-devel-$(uname -r).rpm
dnf install -y zfs
modprobe zfs
#. Install partition tool and arch-install-scripts::
dnf install -y gdisk dosfstools arch-install-scripts

View File

@@ -1,151 +0,0 @@
.. highlight:: sh
System Installation
======================
.. contents:: Table of Contents
:local:
#. Partition the disks::
for i in ${DISK}; do
# wipe flash-based storage device to improve
# performance.
# ALL DATA WILL BE LOST
# blkdiscard -f $i
sgdisk --zap-all $i
sgdisk -n1:1M:+1G -t1:EF00 $i
sgdisk -n2:0:+4G -t2:BE00 $i
sgdisk -n4:0:+${INST_PARTSIZE_SWAP}G -t4:8200 $i
if test -z $INST_PARTSIZE_RPOOL; then
sgdisk -n3:0:0 -t3:BF00 $i
else
sgdisk -n3:0:+${INST_PARTSIZE_RPOOL}G -t3:BF00 $i
fi
sgdisk -a1 -n5:24K:+1000K -t5:EF02 $i
sync && udevadm settle && sleep 3
cryptsetup open --type plain --key-file /dev/random $i-part4 ${i##*/}-part4
mkswap /dev/mapper/${i##*/}-part4
swapon /dev/mapper/${i##*/}-part4
done
#. Create boot pool::
zpool create \
-o compatibility=grub2 \
-o ashift=12 \
-o autotrim=on \
-O acltype=posixacl \
-O canmount=off \
-O compression=lz4 \
-O devices=off \
-O normalization=formD \
-O relatime=on \
-O xattr=sa \
-O mountpoint=/boot \
-R /mnt \
bpool \
mirror \
$(for i in ${DISK}; do
printf "$i-part2 ";
done)
If not using a multi-disk setup, remove ``mirror``.
You should not need to customize any of the options for the boot pool.
GRUB does not support all of the zpool features. See ``spa_feature_names``
in `grub-core/fs/zfs/zfs.c
<http://git.savannah.gnu.org/cgit/grub.git/tree/grub-core/fs/zfs/zfs.c#n276>`__.
This step creates a separate boot pool for ``/boot`` with the features
limited to only those that GRUB supports, allowing the root pool to use
any/all features.
Features enabled with ``-o compatibility=grub2`` can be seen
`here <https://github.com/openzfs/zfs/blob/master/cmd/zpool/compatibility.d/grub2>`__.
#. Create root pool::
zpool create \
-o ashift=12 \
-o autotrim=on \
-R /mnt \
-O acltype=posixacl \
-O canmount=off \
-O compression=zstd \
-O dnodesize=auto \
-O normalization=formD \
-O relatime=on \
-O xattr=sa \
-O mountpoint=/ \
rpool \
mirror \
$(for i in ${DISK}; do
printf "$i-part3 ";
done)
If not using a multi-disk setup, remove ``mirror``.
#. Create root system container:
- Unencrypted::
zfs create \
-o canmount=off \
-o mountpoint=none \
rpool/fedora
- Encrypted:
Pick a strong password. Once compromised, changing password will not keep your
data safe. See ``zfs-change-key(8)`` for more info::
zfs create \
-o canmount=off \
-o mountpoint=none \
-o encryption=on \
-o keylocation=prompt \
-o keyformat=passphrase \
rpool/fedora
You can automate this step (insecure) with: ``echo POOLPASS | zfs create ...``.
Create system datasets, let Fedora declaratively
manage mountpoints with ``mountpoint=legacy``::
zfs create -o mountpoint=/ -o canmount=noauto rpool/fedora/root
zfs mount rpool/fedora/root
zfs create -o mountpoint=legacy rpool/fedora/home
mkdir /mnt/home
mount -t zfs rpool/fedora/home /mnt/home
zfs create -o mountpoint=legacy rpool/fedora/var
zfs create -o mountpoint=legacy rpool/fedora/var/lib
zfs create -o mountpoint=legacy rpool/fedora/var/log
zfs create -o mountpoint=none bpool/fedora
zfs create -o mountpoint=legacy bpool/fedora/root
mkdir /mnt/boot
mount -t zfs bpool/fedora/root /mnt/boot
mkdir -p /mnt/var/log
mkdir -p /mnt/var/lib
mount -t zfs rpool/fedora/var/lib /mnt/var/lib
mount -t zfs rpool/fedora/var/log /mnt/var/log
#. Format and mount ESP::
for i in ${DISK}; do
mkfs.vfat -n EFI ${i}-part1
mkdir -p /mnt/boot/efis/${i##*/}-part1
mount -t vfat ${i}-part1 /mnt/boot/efis/${i##*/}-part1
done
mkdir -p /mnt/boot/efi
mount -t vfat $(echo $DISK | cut -f1 -d' ')-part1 /mnt/boot/efi

View File

@@ -1,88 +0,0 @@
.. highlight:: sh
System Configuration
======================
.. contents:: Table of Contents
:local:
#. Generate fstab::
mkdir -p /mnt/etc/
genfstab -t PARTUUID /mnt | grep -v swap > /mnt/etc/fstab
sed -i "s|vfat.*rw|vfat rw,x-systemd.idle-timeout=1min,x-systemd.automount,noauto,nofail|" /mnt/etc/fstab
#. Install basic system packages::
dnf --installroot=/mnt \
--releasever=$VERSION_ID -y install \
@core grub2-efi-x64 \
grub2-pc-modules grub2-efi-x64-modules \
shim-x64 efibootmgr \
kernel kernel-devel
dnf --installroot=/mnt \
--releasever=$VERSION_ID -y install \
https://zfsonlinux.org/fedora/zfs-release-2-2$(rpm --eval "%{dist}").noarch.rpm
dnf --installroot=/mnt --releasever=$VERSION_ID \
-y install zfs zfs-dracut
#. Configure dracut::
echo 'add_dracutmodules+=" zfs "' >> /mnt/etc/dracut.conf.d/zfs.conf
echo 'forced_drivers+=" zfs "' >> /mnt/etc/dracut.conf.d/zfs.conf
if grep mpt3sas /proc/modules; then
echo 'forced_drivers+=" mpt3sas "' >> /mnt/etc/dracut.conf.d/zfs.conf
fi
if grep virtio_blk /proc/modules; then
echo 'filesystems+=" virtio_blk "' >> /mnt/etc/dracut.conf.d/fs.conf
fi
#. Generate host id::
zgenhostid -f -o /mnt/etc/hostid
#. Install locale package, example for English locale::
dnf --installroot=/mnt install -y glibc-minimal-langpack glibc-langpack-en
#. By default SSH server is enabled, allowing root login by password,
disable SSH server::
systemctl disable sshd --root=/mnt
systemctl enable firewalld --root=/mnt
#. Chroot::
history -w /mnt/home/sys-install-pre-chroot.txt
arch-chroot /mnt /usr/bin/env DISK="$DISK" bash --login
#. For SELinux, relabel filesystem on reboot::
fixfiles -F onboot
#. Build ZFS modules::
for directory in /lib/modules/*; do
kernel_version=$(basename $directory)
dkms autoinstall -k $kernel_version
done
#. Generate initrd::
for directory in /lib/modules/*; do
kernel_version=$(basename $directory)
dracut --force --kver $kernel_version
done
#. Set locale, keymap, timezone, hostname and root password::
rm -f /etc/localtime
systemd-firstboot --prompt --root-password=PASSWORD --force
#. Set root password, the password set earlier does not work due to SELinux::
passwd

View File

@@ -1,81 +0,0 @@
.. highlight:: sh
Bootloader
======================
.. contents:: Table of Contents
:local:
#. Apply GRUB workaround::
echo 'export ZPOOL_VDEV_NAME_PATH=YES' >> /etc/profile.d/zpool_vdev_name_path.sh
source /etc/profile.d/zpool_vdev_name_path.sh
# GRUB fails to detect rpool name, hard code as "rpool"
sed -i "s|rpool=.*|rpool=rpool|" /etc/grub.d/10_linux
This ``sed`` workaround needs to be applied for every
GRUB update, as the update will overwrite the
changes.
#. Install GRUB::
echo 'GRUB_ENABLE_BLSCFG=false' >> /etc/default/grub
mkdir -p /boot/efi/fedora/grub-bootdir/i386-pc/
mkdir -p /boot/efi/fedora/grub-bootdir/x86_64-efi/
for i in ${DISK}; do
grub2-install --target=i386-pc --boot-directory \
/boot/efi/fedora/grub-bootdir/i386-pc/ $i
done
cp -r /usr/lib/grub/x86_64-efi/ /boot/efi/EFI/fedora/
grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg
grub2-mkconfig -o /boot/efi/fedora/grub-bootdir/i386-pc/grub2/grub.cfg
mkdir -p /boot/grub2
grub2-mkconfig -o /boot/grub2/grub.cfg
#. For both legacy and EFI booting: mirror ESP content::
unalias -a
ESP_MIRROR=$(mktemp -d)
cp -r /boot/efi/EFI $ESP_MIRROR
for i in /boot/efis/*; do
cp -r $ESP_MIRROR/EFI $i
done
rm -rf $ESP_MIRROR
#. Note: you need to regenerate GRUB menu after kernel
updates, otherwise computer will still boot old
kernel on reboot::
grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg
grub2-mkconfig -o /boot/efi/fedora/grub-bootdir/i386-pc/grub2/grub.cfg
grub2-mkconfig -o /boot/grub2/grub.cfg
Finish Installation
~~~~~~~~~~~~~~~~~~~~
#. Exit chroot::
exit
#. Export pools::
umount -Rl /mnt
zpool export -a
#. Reboot::
reboot
Post installaion
~~~~~~~~~~~~~~~~
#. Install package groups::
dnf group list --hidden -v # query package groups
dnf group install gnome-desktop
#. Add new user, configure swap.
#. You can create a snapshot of the newly installed
system for later rollback,
see `this page <https://openzfs.github.io/openzfs-docs/Getting%20Started/Arch%20Linux/Root%20on%20ZFS/6-create-boot-environment.html>`__.

View File

@@ -57,16 +57,6 @@ see below.
modprobe zfs
It might be necessary to rebuild ZFS module::
for directory in /lib/modules/*; do
kernel_version=$(basename $directory)
dkms autoinstall -k $kernel_version
done
If for some reason, ZFS kernel module is not successfully built,
you can also run the above command to debug the problem.
#. By default ZFS kernel modules are loaded upon detecting a pool.
To always load the modules at boot::
@@ -87,13 +77,8 @@ These packages
Root on ZFS
-----------
ZFS can be used as root file system for Fedora.
An installation guide is available.
Start from "Preparation".
.. toctree::
:maxdepth: 1
:glob:
:maxdepth: 1
:glob:
Root on ZFS/*
*