ZFS/rootfs
For those looking to find general information on using ZFS on Linux then please see the ZFS page instead.
This article is focused on using ZFS as the rootfs on Gentoo and designed to be used with the Handbook. Over time more advanced setups will be added so please check the TODO section to see if there is something that can be added to improve this article.
Live Media
Currently only Admin CD and LiveGUI USB image include the ZFS tools required to setup as root.
Partitions
Layout
Follow the Handbook section on Preparing the disks returning at the creating file systems section.
This guide will be using the example below however it should be simple enough to adapt this to the user's needs.
/dev/sda1 | 1024 MiB | EFI System Partition | /efi /dev/sda2 | 2048 MiB | swap | swap /dev/sda3 | Rest of Disk | ZFS Partition | /, /boot, /home, ...
Boot
Create a 1GB FAT32 filesystem:
root #
mkfs.vfat -F 32 /dev/sda1
Swap
Swap performance on a ZFS partition is known to be poor and using a swapfile is not supported, instead it is recommended to use its own partition.
root #
mkswap /dev/sda2
root #
swapon /dev/sda2
Alternatively, zram could be used on systems with a large amount of RAM but do note ZFS will cache data to RAM for speed.
ZFS Setup
Generate host ID
Randomly generate host ID into /etc/hostid
allowing output overwrite.
root #
zgenhostid -f
Alternatively, set a specific host ID, 0x00bab10c
in this example.
root #
zgenhostid -f 0x00bab10c
Create a ZFS pool
Load ZFS kernel module and create a ZFS pool tank
on /dev/sda3
.
root #
modprobe zfs
root #
zpool create -f \
-o ashift=12 \
-o autotrim=on \
-o compatibility=openzfs-2.1-linux \
-O acltype=posixacl \
-O xattr=sa \
-O relatime=on \
-O compression=lz4 \
-m none tank /dev/sda3
The option
-o compatibility=openzfs-2.1-linux
makes sure that the pool is created only with feature flags supported by the current binary release of ZFSBootMenu (v2.2.0 at the time of writing). Future releases of ZFSBootMenu may support newer feature sets, check release notes prior to updating compatibility options and upgrading your pool. If ZFSBootMenu is not used, this parameter can be omitted or changed depending on the setup.Alternative: Create a ZFS pool with native encryption
Native ZFS encryption can also be used by adding additional options when creating our zpool.
root #
zpool create -f \
-o ashift=12 \
-o autotrim=on \
-o compatibility=openzfs-2.1-linux \
-O acltype=posixacl \
-O xattr=sa \
-O relatime=on \
-O compression=lz4 \
-O encryption=aes-256-gcm \
-O keylocation=prompt \
-O keyformat=passphrase \
-m none tank /dev/sda3
It's also possible to set the keylocation property to point to a file, which is useful when using ZFSBootMenu as a bootloader, or when trying to reduce the number of passphrase prompts during boot. See the ZFSBootMenu documentation for more info on how it handles encrypted filesystems.
Create ZFS file systems
This guide will be only creating root and home file systems. However, the user is free to create additional file systems if desired.
root #
zfs create -o mountpoint=none tank/os
root #
zfs create -o mountpoint=/ -o canmount=noauto tank/os/gentoo
root #
zfs create -o mountpoint=/home tank/home
The property
canmount=noauto
should be set on any file systems with the root mountpoint. Omitting it can result in OS trying to automatically mount several file systems at /
and failing.
/usr
, /etc
or any other system-critical folder on a different dataset, note that it has to be a child of the root dataset (e.g. tank/os/gentoo/usr
), with canmount=on
to be properly mounted by dracut-generated initramfsSet the preferred boot file system of the pool.
root #
zpool set bootfs=tank/os/gentoo tank
Export and re-import a pool, mount file systems
To export and re-import a pool with a specified mountpoint and without automatically mounting the file systems, run the following commands.
root #
zpool export tank
root #
zpool import -N -R /mnt/gentoo tank
It is then possible to mount root and home file systems.
root #
zfs mount tank/os/gentoo
root #
zfs mount tank/home
After mounting the file systems, it is advisable to verify mountpoints by checking the output of the command below.
root #
mount -t zfs
Here is an example of the command output in case of successful mounting of file systems.
tank/os/gentoo /mnt/gentoo type zfs (rw,relatime,xattr,posixacl) tank/home on /mnt/gentoo/home type zfs (rw,relatime,xattr,posixacl)
Update device symbolic links:
root #
udevadm trigger
Return to the Handbook - Installing the Gentoo installation files and return just before entering chroot
command.
Copy host ID file
root #
cp /etc/hostid /mnt/gentoo/etc
Return to Handbook - Installing Gentoo base system and return here at Kernel configuration and compilation.
Kernel
The user can choose between manually configured kernel or the distribution kernel.
Distribution kernel
Enabling USE flag
If using the distribution kernel then the dist-kernel
USE flag will need to be enabled:
USE="dist-kernel"
Installing distribution kernel
root #
emerge -av sys-kernel/gentoo-kernel
Or, if you prefer using the pre-compiled binary,
root #
emerge -av sys-kernel/gentoo-kernel-bin
ZFS userland utilities and kernel module
The sys-fs/zfs and sys-fs/zfs-kmod packages are necessary to allow your system to interact with and manage your ZFS pools.
root #
emerge -av sys-fs/zfs sys-fs/zfs-kmod
Initramfs
Configure Dracut
Create a directory for Dracut configuration files if it does not exist.
root #
mkdir -p /etc/dracut.conf.d
Then, create a file zol.conf
with the following content in this directory:
root #
nano /etc/dracut.conf.d/zol.conf
nofsck="yes"
add_dracutmodules+=" zfs "
Build the initramfs for the distribution kernel
root #
emerge --config sys-kernel/gentoo-kernel
Or, if the binary version was installed,
root #
emerge --config sys-kernel/gentoo-kernel-bin
You can return to the Handbook - Configuring the system and return here at Configuring the bootloader for anything other than sys-boot/grub.
Bootloader
ZFSBootMenu (prebuilt)
Setting kernel command-line
root #
zfs set org.zfsbootmenu:commandline="quiet loglevel=4" tank/os
ZFS properties are inherited, therefore all children datasets of
tank/os
will inherit the command-line arguments. If necessary, the property can be overridden in specific child datasets.Mounting the EFI System Partition
The ZFSBootMenu documentation states that the kernel and initramfs must be located in the /boot directory of the ZFS root. However, the systemd installkernel will attempt to locate the mountpoint of your EFI partition and install the kernel-initramfs pair there instead, which in our case, is /efi Therefore, the
-systemd
USE flag must be added to sys-kernel/installkernel to prevent that from happening.If the ESP was not mounted previously, it is necessary to do it now:
root #
mkdir -p /efi
root #
mount /dev/sda1 /efi
Installing ZFSBootMenu (prebuilt)
Create a directory for the bootloader and download the EFI binary into it.
root #
mkdir -p /efi/EFI/BOOT
root #
curl -L https://get.zfsbootmenu.org/efi -o /efi/EFI/BOOT/BOOTX64.EFI
Creating an EFI boot entry
Install the package sys-boot/efibootmgr.
root #
emerge -av sys-boot/efibootmgr
Then, an EFI boot entry can be created with the following command.
root #
efibootmgr -c -d /dev/sda -p 1 -L "ZFSBootMenu" -l \\EFI\\BOOT\\BOOTX64.EFI
Optional: Native Encryption
If you've opted for native encryption when you set up your zpool as described in Alternative: Create a ZFS pool with native encryption, it is possible to set up ZFSBootMenu to prompt for the passphrase once and have dracut have access to encryption keys at boot, or alternatively by setting the org.zfsbootmenu:keysource
attribute and storing encryption keys on a separate dataset.
See the ZFSBootMenu documentation for info on how to properly set this up.
Rebooting the system
Exit the chrooted environment and unmount all mounted partitions, do not forget to export the pool. After that, the system can be rebooted.
root #
exit
root #
cd
root #
umount -l /mnt/gentoo/dev{/shm,/pts,}
root #
umount -n -R /mnt/gentoo
root #
zpool export tank
root #
reboot
TODO
Sections needed to be added for a more complete guide
- Using sys-kernel/gentoo-sources to manual kernel users
- Add LUKS encryption
- Add instructions for alternative bootloaders
- Add instructions for ZFSBootMenu installation via
generate-zbm
(likely requires using GURU)