FreeBSD 13 root-on-ZFS installation with custom zroot partition size

The default FreeBSD “Guided Root-on-ZFS” installation allocates all the space for “zroot” storage pool. However, if you’d like to have a smaller zroot, you can modify the partitioning script or partition manually.

This article assumes that you’re trying to install FreeBSD using mirrored mode, on disk ada0 and ada1

Option 1: modify partitioning script “zfsboot”

Find a machine running FreeBSD, mount the installation memsitck, and modify /usr/libexec/bsdinstall/zfsboot on memstick

--- usr/libexec/bsdinstall/zfsboot
+++ usr/libexec/bsdinstall/zfsboot
@@ -943,8 +943,8 @@
 		#
 		# 4. Add freebsd-zfs partition labeled `zfs#' for zroot
 		#
-		f_eval_catch $funcname gpart "$GPART_ADD_ALIGN_LABEL" \
-		             "$align_big" zfs$index freebsd-zfs $disk ||
+		f_eval_catch $funcname gpart "$GPART_ADD_ALIGN_LABEL_WITH_SIZE" \
+		             "$align_big" zfs$index freebsd-zfs 16g $disk ||
 		             return $FAILURE
 		f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \
 		                /dev/$disk$targetpart

Unmount memstick, and and boot from the memstick on the machine that you’d like to install FreeBSD.

Option 2: Open a shell and partition by hand

During the “partitioning – How would you like to partition your disk?” dialogue, select “Shell – Open a shell and partition by hand”

# Destroy existing zroot, not required if it's a new disk with only 0x00.
zpool destroy zroot

# Force 4K sectors (2^12 == 4096)
sysctl vfs.zfs.min_auto_ashift=12

# Cleanup ada0, not required if it's a new disk with only 0x00.
# It is okay to ignore errors in this section
gpart destroy -F ada0
graid delete ada0
zpool labelclear -f /dev/ada0
gpart create -s gpt ada0
gpart destroy -F ada0

# Partition ada0
gpart create -s gpt ada0
gpart add -a 4k -l gptboot0 -t freebsd-boot -s 512k ada0
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
gpart add -a 1m -l swap0 -t freebsd-swap -s 2g ada0  # use your preferred size here
zpool labelclear -f /dev/ada0p2  # please ignore error
gpart add -a 1m -l zfs0 -t freebsd-zfs -s 16g ada0  # use your preferred size here
zpool labelclear -f /dev/ada0p3  # please ignore error

# Cleanup ada1, not required if it's a new disk with only 0x00.
# It is okay to ignore errors in this section
gpart destroy -F ada1
graid delete ada1
zpool labelclear -f /dev/ada1
gpart create -s gpt ada1
gpart destroy -F ada1

# Partition ada1
gpart create -s gpt ada1
gpart add -a 4k -l gptboot1 -t freebsd-boot -s 512k ada1
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1
gpart add -a 1m -l swap1 -t freebsd-swap -s 2g ada1  # use your preferred size here
zpool labelclear -f /dev/ada1p2  # please ignore error
gpart add -a 1m -l zfs1 -t freebsd-zfs -s 16g ada1  # use your preferred size here
zpool labelclear -f /dev/ada1p3  # please ignore error

# fstab
:> /tmp/bsdinstall_etc/fstab
printf "%s\t\t%s\t%s\t%s\t\t%s\t%s\n" "# Device" Mountpoint FStype Options Dump Pass# >> /tmp/bsdinstall_etc/fstab
printf "%s\t\t%s\t%s\t%s\t\t%s\t%s\n" /dev/ada0p2 none swap sw 0 0 >> /tmp/bsdinstall_etc/fstab
printf "%s\t\t%s\t%s\t%s\t\t%s\t%s\n" /dev/ada1p2 none swap sw 0 0 >> /tmp/bsdinstall_etc/fstab

# Create storage pool and dataset
zpool create -o altroot=/mnt -O compress=lz4 -O atime=off -m none -f zroot mirror ada0p3 ada1p3
zfs create -o mountpoint=none zroot/ROOT
zfs create -o mountpoint=/ zroot/ROOT/default
zfs create -o mountpoint=/tmp -o exec=on -o setuid=off zroot/tmp
zfs create -o mountpoint=/usr -o canmount=off zroot/usr
zfs create  zroot/usr/home
zfs create -o setuid=off zroot/usr/ports
zfs create  zroot/usr/src
zfs create -o mountpoint=/var -o canmount=off zroot/var
zfs create -o exec=off -o setuid=off zroot/var/audit
zfs create -o exec=off -o setuid=off zroot/var/crash
zfs create -o exec=off -o setuid=off zroot/var/log
zfs create -o atime=on zroot/var/mail
zfs create -o setuid=off zroot/var/tmp

zfs set mountpoint=/zroot zroot
mkdir -p /mnt/tmp
chmod 1777 /mnt/tmp
mkdir -p /mnt/var/tmp
chmod 1777 /mnt/var/tmp

zpool set bootfs=zroot/ROOT/default zroot
mkdir -p /mnt/boot/zfs
zpool set cachefile=/mnt/boot/zfs/zpool.cache zroot
zfs set canmount=noauto zroot/ROOT/default

echo zfs_enable=\"YES\" >> /tmp/bsdinstall_etc/rc.conf.zfs
echo kern.geom.label.disk_ident.enable=\"0\" >> /tmp/bsdinstall_boot/loader.conf.zfs
echo kern.geom.label.gptid.enable=\"0\" >> /tmp/bsdinstall_boot/loader.conf.zfs
echo vfs.zfs.min_auto_ashift=12 >> /tmp/bsdinstall_etc/sysctl.conf.zfs

exit  # installation will start

For implementation detail, check /usr/libexec/bsdinstall/zfsboot
or observing the log at /tmp/bsdinstall_log after guided root-on-ZFS installation.

Leave a Reply

Your email address will not be published. Required fields are marked *