Note: This is rewritten from this forum post, which I found a bit confusing to follow.

FreeNAS is a wonderful BSD distribution that focuses on being a foundation for networked file sharing. You can use it to store all your files, Time Machine backups, movies, and add lots of other plugin-based functionality.

FreeNAS uses zfs as its filesystem, where the equivalent of a “disk” is a zpool. A zpool might consist of many drives configured redundantly. The zpool is the unit that we will back up.

I have an 8 TB external hard drive, so I can back up multiple zpools totalling up to 8 TB in size. The sync script in the forum post only supports one source pool, but could be modified fairly easily. As far as I can tell you can only get to a shell through the FreeNAS web portal so that’s where I enter these commands.

Create a new zpool to store the backup data

We will copy the contents of the origin zpool to the backup zpool.

First, plug in the external drive if you haven’t already. You may need to rescan your disks before you can use it:

$ camcontrol rescan all

Next, find which device your drive is using:

$ geom disk list

You’ll see a list of items that look like this:

1. Name: da0
   Mediasize: 8001563221504 (7.3T)
   Sectorsize: 512
   Stripesize: 4096
   Stripeoffset: 0
   Mode: r0w0e0
   descr: Seagate Expansion Desk
   lunid: 5000000000000001
   ident: XXXXXXXX
   rotationrate: unknown
   fwsectors: 63
   fwheads: 255

So the above device is using /dev/da0.

Next, create the new pool, replacing {DISK} with your device path (/dev/da0 for the example above):

$ zpool create -m /mnt/Backup -O compression=lz4 Backup {DISK}

Then you’ll create the dataset:

$ zfs create Backup/`uname -n | cut -f1 -d'.'`

Copy the contents of one zpool to the backup

Now you have a new, empty pool on your external drive mounted on /mnt/Backup. You can now copy files to it. The forum post above provides the following rsync based script that is easy to run. I used vi to paste the file directly onto my FreeNAS box, you can also wget the gist directly. I put mine in ~. Don’t forget to chmod +x it.

First I (and the original forum poster) recommend doing the backup in a terminal multiplexer like tmux or screen. I use screen because I’m more familiar with it. This is because it will take an extremely long time, and your FreeNAS portal session will time out. A multiplexer will let your backup continue in the background and allow you to resume the terminal session.

$ screen
$ cd ~
$ setenv MY_SOURCE_POOL {your pool name here}
$ ./backup_freenas_rsync

Set the MY_SOURCE_POOL environment variable to the name of the pool you want to back up. You can search for it in the source to see how it gets used if you’re confused.

Logs will be saved to /var/log/local/ where you can tail them if desired. If you lose your terminal session (and are using screen) you can recover your session with screen -r.

Detach the backup zpool

$ cd /
$ sync
$ zpool status Backup
$ zpool export Backup

Verify the pool is detached:

$ zpool list

You can now unplug the external drive.

Recovering data

With the hard drive plugged in, run the following:

$ camcontrol rescan all
$ zpool import Backup

The backup zpool will now be mounted again at /mnt/Backup where you can view/copy files as needed. You can use zpool import to list all unimported pools.