Building a FreeBSD NAS, part III: ZFS
Tags: howtos, freebsd
This is part III of my NAS project. Check out part II for some information about the base system setup and part I for the hardware setup.
Why ZFS?
Data security is paramount when setting up a NAS. You do not want to store valuable data on your NAS just to find out later on that it has been corrupted. Likewise, you might want your NAS to be able to survive one dead hard drive. This is where ZFS comes in handy. ZFS is a filesystem designed with server users in mind. Among other features, it offers:
- Automated compression
- Data integrity checks
- Volume mirroring (“software RAID”)
- Snapshots
- Deduplication
The best thing, though: It is available out-of-the-box in FreeBSD.
The setup
I am only covering some very basic usage scenarios here. In the following, I am assuming that you
have two disks on /dev/ada1
and /dev/ada2
respectively. We will put the home directories and a
mount point for media files on those disks and finish with a simple mirroring setup. At the risk of
sounding like a broken record here, I am repeating the sage advice of the ages: RAID does not
replace backups. RAID is not a backup solution.
In other words: This setup protects you against one hard drive failing, but not against people deleting their data deliberately. It always pays to keep an external hard drive around that can store backups in a secure location. I am using secure in the sense of being secure against damages in your apartment, not against international espionage, by the way.
Preparing the disks
We first need need to create a GPT on the disk:
$ gpart create -s gpt ada1
$ gpart show ada1
=> 34 3907029101 ada1 GPT (1.8T)
34 3907029101 - free - (1.8T)
Further partitions are not required. ZFS will do the rest for us.
Creating storage for the home directories
The basic entity of ZFS is a pool. A ZFS pool can consists of multiple disks. Each pool can contain numerous filesystems. Let’s start by creating a pool on the disk.
$ zpool create storage /dev/ada1
Pools can have any name. I do not want to get creative here and call mine simply storage.
Now let’s create a filesystem that uses the pool.
$ zfs create storage/home
Moving the home directories
This step is not really related to ZFS, but I am including it for the sake of completeness. Basically, I am copying all home directories to the pool, then fixing the permissions (for each user individually) and deleting the old home directories:
$ cp -rp /home/* /storage/home
$ chown -R user1:group1 /home/user1
$ chown -R user2:group2 /home/user2
...
$ rm -rf /home/*
Setting a new mount point
Having moved the directories to the pool, we nonetheless want the filesystem to appear as /home
.
Setting a new mount point is easy:
$ zfs set mountpoint=/home storage/home
Enabling compression
If you want to enable compression for the new filesystem (which I would recommend; see this
article about the benefits, for
example), we again use the
zfs
command:
$ zfs set compression=gzip storage/home
$ zfs get compressratio storage/home
NAME PROPERTY VALUE SOURCE
storage/home compressratio 1.11x -
Note that the compression ratio is likely to improve over time, depending on what sort of you data you store.
Creating storage for the media files
We need another filesystem for storing media files.
$ zfs create storage/media
$ zfs set atime=off storage/media
$ zfs set quota=800GB storage/media
Note that I disabled access time updates which improves read performance. For my media files, I do not care about access times because they will only be read by server applications.
I also set a quota for the media files to force me to throw away old stuff. Of course, the quota can
be reset any time using the zfs
command.
Attaching the second hard drive
Again, the zfs
command is our friend here:
$ zpool attach storage /dev/ada1 /dev/ada2
This command is so simple and easy, it made me immediately fall in love with ZFS. Setting up a mirror could not be easier…
Making the changes persistent and enabling monitoring
ZFS should be loaded automatically whenever the NAS boots up, so rc.conf
needs to be modified
accordingly:
$ echo 'zfs_enable="YES"' >> /etc/rc.conf
If you have configured your NAS to send you e-mails (which I explained in part II), you can instruct FreeBSD to include information about all ZFS pools in the daily status reports:
$ echo 'daily_status_zfs_enable="YES"' >> /etc/periodic.conf
This will result in status information about the pools:
Checking status of zfs pools:
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
storage 1.81T 980G 876G 52% 1.00x ONLINE -
all pools are healthy
Conclusion & some resources
I have but scratched the surface of ZFS features. Data deduplication, for example, is one of the great things about ZFS. It means that ZFS will not store identical blocks multiple times on a pool but just once. Unfortunately, my NAS has not enough RAM for this to work reliably. I will maybe cover this in another article.
In the meantime, here are some other great resources about using ZFS:
- A detailed ZFS tutorial, by Will Green
- Some usage scenarios for ZFS on a homeserver, by Simon Breden
May your drives never fail and your data prosper.