Installing Void on a ZFS Root
Because the Void installer does not support ZFS, it is necessary to install via chroot. Aside from a few caveats regarding bootloader and initramfs support, installing Void on a ZFS root filesystem is not significantly different from any other advanced installation. ZFSBootMenu is a bootloader designed from the ground up to support booting Linux distributions directly from a ZFS pool. However, it is also possible to use traditional bootloaders with a ZFS root.
ZFSBootMenu
Although it will boot (and can be run atop) a wide variety of distributions, ZFSBootMenu officially considers Void a first-class distribution. ZFSBootMenu supports native ZFS encryption, offers a convenient recovery environment that can be used to clone prior snapshots or perform advanced manipulation in a pre-boot environment, and will support booting from any pool that is importable by modern ZFS drivers. The ZFSBootMenu documentation offers, among other content, several step-by-step guides for installing a Void system from scratch. The UEFI guide describes the procedure of bootstrapping a Void system for modern systems. For legacy BIOS systems, the syslinux guide provides comparable instructions.
Traditional bootloaders
For those that wish to forego ZFSBootMenu, it is possible to bootstrap a Void
system with another bootloader. To avoid unnecessary complexity, systems that
use bootloaders other than ZFSBootMenu should plan to use a separate /boot
that is located on an ext4 or xfs filesystem.
Installation media
Installing Void to a ZFS root requires an installation medium with ZFS drivers.
It is possible to build a custom image from the official
void-mklive repository by providing
the command-line option -p zfs
to the mklive.sh
script. However, for
x86_64
systems, it may be more convenient to fetch a pre-built
hrmpf image. These images,
maintained by a Void team member, are extensions of the standard Void live
images that include pre-compiled ZFS modules in addition to other useful tools.
Partition disks
After booting a live image with ZFS support, partition your disks. The considerations in the partitioning guide apply to ZFS installations as well, except that
- The boot partition should be considered necessary unless you intend to use
gummiboot
, which expects that your EFI system partition will be mounted at/boot
. (This alternative configuration will not be discussed here.) - Aside from any EFI system partition, GRUB BIOS boot partition, swap or boot
partitions, the remainder of the disk should typically be a single partition
with type code
BF00
that will be dedicated to a single ZFS pool. There is no benefit to creating separate ZFS pools on a single disk.
As needed, format the EFI system partition using mkfs.vfat(8) and the the boot partition using mke2fs(8) or mkfs.xfs(8). Initialize any swap space using mkswap(8).
It is possible to put Linux swap space on a ZFS zvol, although there may be a risk of deadlocking the kernel when under high memory pressure. This guide takes no position on the matter of swap space on a zvol. However, if you wish to use suspension-to-disk (hibernation), note that the kernel is not capable of resuming from memory images stored on a zvol. You will need a dedicated swap partition to use hibernation. Apart from this caveat, there are no special considerations required to resume a suspended image when using a ZFS root.
Create a ZFS pool
Create a ZFS pool on the partition created for it using
zpool(8). For example, to create a pool on
/dev/disk/by-id/wwn-0x5000c500deadbeef-part3
:
# zpool create -f -o ashift=12 \
-O compression=lz4 \
-O acltype=posixacl \
-O xattr=sa \
-O relatime=on \
-o autotrim=on \
-m none zroot /dev/disk/by-id/wwn-0x5000c500deadbeef-part3
Adjust the pool (-o
) and filesystem (-O
) options as desired, and replace the
partition identifier wwn-0x5000c500deadbeef-part3
with that of the actual
partition to be used.
When adding disks or partitions to ZFS pools, it is generally advisable to refer to them by the symbolic links created in
/dev/disk/by-id
or (on UEFI systems)/dev/disk/by-partuuid
so that ZFS will identify the right partitions even if disk naming should change at some point. Using traditional device nodes like/dev/sda3
may cause intermittent import failures.
Next, export and re-import the pool with a temporary, alternate root path:
# zpool export zroot
# zpool import -N -R /mnt zroot
Create initial filesystems
The filesystem layout on your ZFS pool is flexible. However, it is customary to
put operating system root filesystems ("boot environments") under a ROOT
parent:
# zfs create -o mountpoint=none zroot/ROOT
# zfs create -o mountpoint=/ -o canmount=noauto zroot/ROOT/void
Setting canmount=noauto
on filesystems with mountpoint=/
is useful because
it permits the creation of multiple boot environments (which may be clones of a
common Void installation or contain completely separate distributions) without
fear that ZFS auto-mounting will attempt to mount one over another.
To separate user data from the operating system, create a filesystem to store home directories:
# zfs create -o mountpoint=/home zroot/home
Other filesystems may be created as desired.
Mount the ZFS hierarchy
All ZFS filesystems should be mounted under the /mnt
alternate root
established by the earlier re-import. Mount the manual-only root filesystem
before allowing ZFS to automatically mount everything else:
# zfs mount zroot/ROOT/void
# zfs mount -a
At this point, the entire ZFS hierarchy should be mounted and ready for installation. To improve boot-time import speed, it is useful to record the current pool configuration in a cache file that Void will use to avoid walking the entire device hierarchy to identify importable pools:
# mkdir -p /mnt/etc/zfs
# zpool set cachefile=/mnt/etc/zfs/zpool.cache zroot
Mount non-ZFS filesystems at the appropriate places. For example, if /dev/sda2
holds an ext4 filesystem that should be mounted at /boot
and /dev/sda1
is
the EFI system partition:
# mkdir -p /mnt/boot
# mount /dev/sda2 /mnt/boot
# mkdir -p /mnt/boot/efi
# mount /dev/sda1 /mnnt/boot/efi
Installation
At this point, ordinary installation can proceed from the "Base Installation"
section. of the standard chroot installation
guide. However, before following the "Finalization"
instructions, make sure that the zfs
package has
been installed and dracut
is configured to identify a ZFS root filesystem:
[xchroot /mnt] # mkdir -p /etc/dracut.conf.d
[xchroot /mnt] # cat > /etc/dracut.conf.d/zol.conf <<EOF
nofsck="yes"
add_dracutmodules+=" zfs "
omit_dracutmodules+=" btrfs resume "
EOF
[xchroot /mnt] # xbps-install zfs
Finally, follow the "Finalization" instructions and reboot into your new system.