Install FreeBSD on ZFS Root

It seems FreeBSD has better ZFS support than Linux. ZFS module is included in FreeBSD base system, no extra package is required. Installation steps are as below.

Harware environment
Asus N73SV Notebook
CPU:Intel Core i7 2630QM
12GB DDR3 RAM
750GB HDD

Installation media
FreeBSD-9.1-RELEASE-amd64-memstick.img

Installation media preparation
Download FreeBSD-9.1-RELEASE-amd64-memstick.img, and burn it into your USB flash disk.

Boot FreeBSD 9.1 from USB flash disk.

Enter LiveCD mode
Choose “LiveCD” instead of install
Login name is root without password, then you could enter LiveCD environment.

Create a ramdisk, and mount it at /tmp to store zpool.cache (optional)

1
2
# umount /dev/md1
# mdmfs -s 512M md1 /tmp

Create GPT+ZFS partition
Find out your HDD device name, usually, the first AHCI HDD should be /dev/ada0 (FreeBSD-9.x has AHCI support builtin).

1
# ls /dev/ad*

Check if there are partitions already in the HDD.

1
# gpart show ada0

If there are, use gpart to clean them.

Since your HDD partition layout is different from mine, please man gpart to learn about gpart delete and gpart erase by yourself.

After the partitions are clean, we can now create GPT.

1
# gpart create -s gpt ada0

Create a small parition for FreeBSD to boot from GPT. Attention, if your HDD is AF (Advanced Format) with 4KB sector size, please append “-a 4K” parameter to make sure your partition is correctly aligned.

1
# gpart add -s 64k -t freebsd-boot ada0

Leave other free space for ZFS. Attention, if your HDD is AF (Advanced Format) with 4KB sector size, please append “-a 4K” parameter to make sure your partition is correctly aligned.

1
# gpart add -t freebsd-zfs ada0

Write FreeBSD GPT+ZFS bootcode into first partition.

1
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0

Create ZFS as single pool mode in second parition, and name it with “tank”.

1
2
3
# zpool create tank /dev/ada0p2
# zpool set bootfs=tank tank
# zfs set checksum=fletcher4 tank

Use zfs create command to create swap volume in ZFS volume group.

1
2
3
# zfs create -V 8G tank/swap
# zfs set checksum=off tank/swap
# zfs set org.freebsd:swap=on tank/swap

Use zfs create command to create system layout.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# zfs set mountpoint=/mnt tank
# zfs create tank/usr
# zfs create tank/usr/home
# zfs create tank/var
# zfs create -o compression=on -o exec=on -o setuid=off tank/tmp
# zfs create -o compression=lzjb -o setuid=off tank/usr/ports
# zfs create -o compression=off -o exec=off -o setuid=off tank/usr/ports/distfiles
# zfs create -o compression=off -o exec=off -o setuid=off tank/usr/ports/packages
# zfs create -o compression=lzjb -o exec=off -o setuid=off tank/usr/src
# zfs create -o compression=lzjb -o exec=off -o setuid=off tank/var/crash
# zfs create -o exec=off -o setuid=off tank/var/db
# zfs create -o compression=lzjb -o exec=on -o setuid=off tank/var/db/pkg
# zfs create -o exec=off -o setuid=off tank/var/empty
# zfs create -o compression=lzjb -o exec=off -o setuid=off tank/var/log
# zfs create -o compression=gzip -o exec=off -o setuid=off tank/var/mail
# zfs create -o exec=off -o setuid=off tank/var/run
# zfs create -o compression=lzjb -o exec=on -o setuid=off tank/var/tmp

Mount ZFS under /mnt through zpool export and zpool import for installation.

1
2
# zpool export tank
# zpool import -o cachefile=/tmp/zpool.cache tank

Now, your ZFS is mounted under /mnt, you can see there would be /mnt/usr, /mnt/var and /mnt/tmp directories. Please type below commands.

1
2
# chmod 1777 /mnt/tmp
# chmod 1777 /mnt/var/tmp

Let’s install FreeBSD 9.x into ZFS under /mnt. It is better to change your shell to sh. Please note the line starting with “for”, since it is too long, so it’s better to use \ to split it.

1
2
3
4
# sh
# cd /usr/freebsd-dist
# export DESTDIR=/mnt
# for file in base.txz lib32.txz kernel.txz doc.txz games.txz ports.txz src.txz; \ do (cat $file | tar --unlink -xpJf - -C ${DESTDIR:-/}); done

Congratulations! You have installed FreeBSD base system into /mnt. Remember to do the following steps, or your system will fail to boot. Copy zpool.cache to your new system.

1
# cp /tmp/zpool.cache /mnt/boot/zfs/zpool.cache

At last, set /etc/rc.conf, /etc/fstab and /boot/loader.conf for your new system.

Set rc.conf

1
# echo 'zfs_enable="YES"' >> /mnt/etc/rc.conf

Set loader.conf

1
2
# echo 'zfs_load="YES"' >> /mnt/boot/loader.conf
# echo 'vfs.root.mountfrom="zfs:tank"' >> /mnt/boot/loader.conf

Set fstab (usually, this file should be empty, because all mountpoints and swap will be automatically mounted after you boot from ZFS)

1
# touch /mnt/etc/fstab

One last step! Set your ZFS mountpoints.

1
2
3
4
5
6
# zfs set readonly=on tank/var/empty
# zfs unmount -a
# zfs set mountpoint=legacy tank
# zfs set mountpoint=/tmp tank/tmp
# zfs set mountpoint=/usr tank/usr
# zfs set mountpoint=/var tank/var

Then you can reboot, and you should be able to boot into your new FreeBSD-9.x based on ZFS. Now you can link /usr/home to /home.

1
# ln -sf /usr/home /home

Set timezone

1
# tzsetup

Set root password

1
# passwd

OK!Everything is done, enjoy your new FreeBSD system!