delphij's Chaos


17 Oct 2007

FreeBSD ZFS from scratch

This article describes how to install FreeBSD on ZFS from installation CD-ROM, with ZFS as root partition.


You need to prepare a ‘disc1’ of FreeBSD, as well as a ‘LiveFS’ disc. Also, you should be familiar with daily operation of FreeBSD system administration.

In order to use ZFS on FreeBSD, one has to use FreeBSD 7.0 or better. For better stability and performance, you should have at least 1GB of RAM, and preferably running on a CPU which is capable to run FreeBSD/amd64, fortunately, most modern CPUs does support this.


Currently, FreeBSD does not support boot from ZFS. One has to rely on a separate UFS volume to boot FreeBSD, due to the limitation of boot and loader. There is work undergoing to support ZFS at boot stage, but it is not likely to enter 7.0-RELEASE due to the current schedule.

The first step is to slice down your disk. In order to reduce problems you could have, just use the LiveFS CD-ROM to boot system, and use fdisk(8) to create a partition for FreeBSD:

fdisk -IB /dev/ad4 (change ad4 to whatever your hard disk is)

Then you will see ‘ad4s1’ appear in /dev. Next, we label it:

bsdlabel -wB /dev/ad4s1
bsdlabel -e /dev/ad4s1

Now, create a ‘a’ label with 512MB of space, and a swap partition (preferably 2x your RAM size, no less than your RAM), and give the rest space under label ’d’.

Then initialize your future /boot:

newfs /dev/ad4s1a

Populate its filesystem. You need /lib, /usr/lib, /bin, /sbin, /usr/bin, /usr/sbin and /usr/share minus manpage. You should also populate /etc and /boot into it. If this does not fit into 512MB then you will have to remove some unnecessary bits, like /rescue.

That’s it, now reboot from hard disk.

The FreeBSD system is now set up, let’s create our zpool:

kldload zfs
zpool create tank ad4s1d

Note: the ’tank’ here is just the name derived from ZFSOnRoot. You can use whatever name you like.

If you have slow hard disk but fast CPU and a lot of RAM, then you can enable compression on ZFS to reduce disk I/O:

zfs set compression=on tank

Populate a FreeBSD system into the new ZFS:

mount -t cd9660 /dev/acd0 /mnt
setenv DESTDIR /tank
cd /mnt/7.0-CURRENT-200709/base

Our current root partition is going to be mounted under ZFS root, therefore, create a mount-point for it:

mkdir /tank/bootdir

Then, we should have the future “/boot” to point to actual /boot, which would be /tank/bootdir/boot. So:

ln -s bootdir/boot /tank/boot

In order to make the kernel to have the ability to mount ZFS, we must load ZFS module at boot. Therefore, put a line in /boot/loader.conf:


And one should tell the system to use ZFS as root, that is the following line in /boot/loader.conf:


Because we do want to upgrade our kernel in the future, we should have our boot partition mounted. That is the following line in /tank/etc/fstab:

/dev/ad4s1a /bootdir ufs rw 1 1

Now, check that there is a /tank/dev, where devfs would be mounted.

No, that’s not enough yet.

Finally, as root file system it should be mounted by the kernel and not ZFS itself. We should set the mount mode:

zfs set mountpoint=legacy tank

Note! This will explicitly unmount ’tank’ from /tank. If you want to mount it again then the following command line will work:

mount -t zfs tank /tank

Take a deep breath, let’s reboot.

If everything goes right then you will now have ZFS mounted as / and the old / as /bootdir.


As an experimental feature ZFS still have some rough edges. However, ZFS gives a lot of features that traditional file systems are lack of, including end-to-end data integration check, etc.