Booting FreeBSD from ZFS

       645 words, 4 minutes

Here are my notes on how to configure a full ZFS-based FreeBSD system. In this particular case, the system is “FreeBSD 9.0-CURRENT #0: Thu May 12 15:34:46 UTC 2011” and it runs on a Dell Inspiron Mini 1012 (Intel Atom N450) with 1GB of RAM. This is just a P.O.C. as it is said that ZFS would required at least 2GB of RAM to perform nicely.

Get the media

I grabbed the FreeBSD-9.0-CURRENT-201105-amd64-memstick.img image from my nearest mirror and burned it onto an USB stick:

# sudo dd if=FreeBSD-9.0-CURRENT-201105-amd64-memstick.img of=/dev/rdisk2 bs=1m

Stick the USB pen into the laptop and boot from it. When asked the task to perform, just select “”.

Summon the daemon

Log in as “root”. On the Live CD, there is no password set.

Run the sysinstall command and configure your keyboard layout ; then exit. Should you ask yourself, I used “Keymap” / “French ISO (accent)”, then “X Exit Install”.

Find the name of your disks. I only have one local:

# sysctl kern.disks
kern.disks: da1 da0 ada0
# gpart list | egrep "Geom|Mediasize"
Geom name: ada0
   Mediasize: 200038809600 (186G)
Geom name: da0
   Mediasize: 65536 (64k)
   Mediasize: 735173120 (701M)
   Mediasize: 1025506304 (978M)

According to the reported sizes, my local disk is “ada0”. Clean the disk:

# gpart destroy ada0
ada0 destroyed

In my case, the disk contained previous partition layout from various testings and the gpart destroy command didn’t work. I had to wipe the disk out first:

# dd if=/dev/zero of=/dev/ada0 count=64
# gpart destroy ada0
ada0 destroyed

Create the partition table and the slices:

# gpart create -s gpt ada0
# gpart add -s 128K -t freebsd-boot -l boot ada0
ada0p1 added
# gpart add -s 2G -t freebsd-swap -l swap ada0
ada0p2 added
# gpart add -t freebsd-zfs -l tank ada0
ada0p3 added

Install the boot code to be able to actually boot from the ZFS root:

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

Load the ZFS modules to be able to create and populate the filesystems:

# kldload opensolaris.ko
# kldload zfs.ko
(...)
ZFS filesystem version 5
ZFS storage pool version 28

Create the ZFS pool using the single disk:

# zpool create tank /dev/gpt/tank
# zpool set bootfs=tank tank

Create the FreeBSD tree:

# zfs set checksum=fletcher4 tank
# zfs create -o compression=on -o exec=on -o setuid=off tank/tmp
# chmod 1777 /tank/tmp
# zfs create -o compression=gzip -o dedup=on tank/usr
# zfs create tank/usr/home
# cd /tank; ln -s /usr/home home
# mkdir /tank/var
# cd /tank/var; ln -s /tmp tmp

Have a look at the “source” link below to get smarter directory layout.

Install the FreeBSD content:

# cd /usr/freebsd-dist
# sh -c 'for FIC in *txz; do cat ${FIC} | tar --unlink -xpJf - -C /tank/; done'

Configure FreeBSD:

# chroot /tank
# echo 'zfs_enable="YES"' > /etc/rc.conf
# cat > /boot/loader.conf
vfs.zfs.prefetch_disable="1"
vfs.root.mountfrom="zfs:tank"
zfs_load="YES"
^D
# echo "/dev/gpt/swap none swap sw 0 0" >> /etc/fstab
# passwd root
# tzsetup
# cd /etc/mail; make aliases
# exit

Save the ZFS cache-file:

# cd /boot/zfs
# zpool export tank && zpool import tank
# cp /boot/zfs/zpool.cache /tank/boot/zfs/

Configure the filesystem mount points:

# zfs unmount -a
# zfs set mountpoint=legacy tank
# zfs set mountpoint=/tmp tank/tmp
# zfs set mountpoint=/usr tank/usr
# zfs set mountpoint=/usr/home tank/usr/home

Reboot into FreeBSD and enjoy:

# reboot

Note that the keyboard layout is configured as US on reboot…
Use “sysinstall” to configure the rest of the system.

BTW, the ZFS system goes like this:

# zpool list 
NAME   SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
tank   184G  1.03G   183G     0%  1.14x  ONLINE  -
# zfs list -r -o name,used,avail,refer,mountpoint,compressratio
NAME            USED  AVAIL  REFER  MOUNTPOINT  RATIO
tank           1.10G   180G   324M  legacy      2.02x
tank/tmp         35K   180G    35K  /tmp        1.00x
tank/usr        735M   180G   735M  /usr        2.57x
tank/usr/home  38.5K   180G  38.5K  /usr/home   1.04x

That’s All Folks!