WhyInstalling a server with FreeBSD and taking advantages of the ZFS filesystem to efficiently deal with disk space management, cheap archiving (through snapshot) and rollback possibilities. Dealing with the upgrade process.

Devices and partitions

Devices

Hardware RAID controllers have some drawback when used with ZFS, as ZFS in a raidz configuration is able to detect more errors and deal better with them than hardware RAID. It will be necessary to access each disk individually to have the full benefits of ZFS.

Usually hardware RAID:

This will lead to a situation where it is nearly impossible to ensure that device numbering will always stay the same across modification, addition or disk deletion, and these kinds of operation are common when failure of a drive occurs. This difficulty to logically represent disk devices, make it prone to failure for the operating system to find the right device when the computer is rebooted. This device numbering problem also exists with USB devices where numbers are assigned according to the ones previously allocated.

The solution is not to rely on the operating system automatic numbering of devices but to use explicit labels to identify the disks.

There are several way to create labels, through the GPT partition table, the filesystem (UFS, MSDOS, …) or the GEOM infrastructure:

Settings label (various methods)
gpart modify -i index -l label device     # GUID partition table (GPT)
tunefs -L label device                    # UFS filesystem
glabel label -v label device              # GEOM infrastructure

Listing all of the labels and their associated devices number can be done for all the created labels (GPT, UFS, GEOM, …) with:

glabel status

Partitions

Partitioning done using MBR doesn’t allow to have partition size of several TB. To avoid this limitation, GUID Partition Table (GPT) needs to be used for large disk. Disks will be systematically partitioned using GPT, the boot disk included: the installer creates that partition type itself.

To create a single partition (GPT style) using the whole disk on the device da1:

gpart create -s GPT         da1                     # Create GUID Partition Table
gpart add    -t freebsd-ufs da1                     # Add new partition for an UFS filesystem
gpart show                  da1                     # Show the disk partitions

To create a bootable disk, on the da1 device, with a ZFS partition and a GPT partionning:

gpart create   -s GPT                         da1   # Creates a GUID partition table (GPT)
gpart add      -b 40   -s 984 -t freebsd-boot da1   # Creates a bootloader partition
gpart add      -b 1024 -s 5g  -t freebsd-zfs  da1   # Creates a ZFS partition
gpart bootcode -b /boot/pmbr                  da1   # Protects the MBR
gpart bootcode -p /boot/gptzfsboot -i 1       da1   # Installs the bootloader

The partition types that will be commonly used are:

Type Description
efi EFI partition
freebsd-boot Bootloader
freebsd-swap Swap
freebsd-ufs UFS filesystem
freebsd-zfs ZFS pool

Boot

Loader

The file /boot/loader.conf is automatically read and processed by the boot loader at startup, it contains instructions to load modules or pass configuration options to the kernel.

The bootloader can roll back a ZFS checkpoint and select the ZFS boot environment.

To show a nice menu with beastie, the FreeBSD logo:

# Boot menu
loader_logo="beastie"

Unable to find the root partition

If the root partition (ie: /) is not found during the boot process; FreeBSD will prompt you for that information. Unfortunately, sometimes USB keyboards are not operational. The solution is to manually specify it from the boot loader (when BIOS is still handling the keyboard):

set vfs.root.mountfrom=????

To mount from ZFS, don’t forget you need to have the zfs module loaded by the bootloader.

System configuration (rc.conf)

System configuration is done by the /etc/rc.conf configuration file and it will override default values defined by the system (in /etc/defaults/rc.conf).

Below are some reasonable values to:

# Keyboard / Mouse / Screen
#---------------------------
keymap="fr.iso.acc"                     # French keyboard
moused_flags="-3"                       # Emulate 3rd button
saver="NO"                              # No screen saver logo
blanktime="NO"                          # Never shutdown the screen

# Auto-diagnostic
#-----------------                 
smartd_enable="YES"                     # Check Harddisk health         
dumpdev="AUTO"                          # Save dump during kernel panic

# Misc
#------
clear_tmp_enable="YES"                  # Clear /tmp at startup
fsck_y_enable="YES"                     # Assume 'yes' for fsck
syslogd_flags="-s -s"                   # secure mode (no network)

Tuning

ZFS

On amd64 with at least 2 GB of memory, ZFS needs no tuning to behave correctly.

Network device

For network interface with heavy traffic load, it is advised to activate polling instead of using interrupts. This will reduce context switches overhead and chances of livelock.

Kernel needs to be compiled with the following options (the recommended value for HZ is 1000):

options         DEVICE_POLLING          # Device polling support
options         HZ=1000                 # Granularity of clock interrupts

Activating polling mode is done using ifconfig for the network card supporting it:

Use polling instead of interrupt
ifconfig device polling

Services

The whole set of services can be manually started or stopped if needed. This is managed by scripts available in the /etc/rc.d/ and /usr/local/etc/rc.d/ directories.

Some examples of script invocation (more actions are available: start, stop, restart, reload, status, poll):

Managing services
# Depends on rc.conf value (requires: `rc_script`_enable="YES")
service Name of the service start        # Start service
service Name of the service stop         # Stop  service

# Executes service action independently of rc.conf configuration
service Name of the service onestart     # Start service
service Name of the service onestop      # Stop  service

Debug

DTrace

DTrace is a dynamic tracing framework for troubleshooting kernel and application problems on production systems in real time. It was imported from the Solaris operating system, and it traces userland as well as the kernel: the pid provider is the fasttrap module, which ships with the base system.

A stock kernel needs no work — GENERIC already carries all of it. These are the options to keep if you build your own:

makeoptions WITH_CTF=1       # run ctfconvert(1), embedding Compact C Type Format
options KDTRACE_HOOKS        # all architectures - enable generation of DTrace hooks
options KDTRACE_FRAME        # amd64-only - ensure frames are compiled in
options DDB_CTF              # all architectures - kernel ELF linker loads CTF data

WITH_CTF is a documented src.conf knob as well — src.conf(5) describes it as “compile with CTF (Compact C Type Format) data” — so it no longer has to be passed on the make command line, which is what the FreeBSD 8 and 9 releases this section used to describe required.

Load every provider
kldload dtraceall