Time Machine backups using FreeBSD ZFS

In this blog article, I described a way to use Netatalk3 to do Time Machine backups on FreeBSD.  This approach worked well, but it had some problems: The Time Machine backups are in every user’s home dir.  That’s messy and there is the potential that they’ll accidentally delete the backup. If I put the backups on a ZFS disk, I can compress them I would like the potential to use ZFS snapshots down the road I would prefer to have all the backups in one directory, rather than scattered across user profiles So, here is a new, better recipe.  Note that this recipe will only work with Netatalk 3.1.2 or better.  The current FreeBSD port is version 3.1.3, so that helps.  Firstly, as in the other recipe, the first step is to install netatalk3, and nss_mdns pkg install netatalk3 pkg install nss_mdns avahi needs mDNS, so that needs to be configured in /etc/nsswitch.conf.  Ensure that this line exists: hosts: files dns mdns Next create a ZFS dataset for the backups.  my zpool is /storage, and the Time Machine backups will be in /storage/timemachine.  Notice that I’ve turned on compression. zfs create storage/timemachine zfs set compression=gzip storage/timemachine zfs get all storage/timemachine zfs list I want to grant the ability to do time machine backups to a FreeBSD group, so I’ll make that, and add the users.  This group will be referred to in afp.conf. pw groupadd timemachine pw groupmod timemachine -m tom pw groupshow timemachine After that, we need to create user directories, one for each time machine user. mkdir storage/timemachine/tom chown tom:timemachine /storage/timemachine/tom chmod 700 /storage/timemachine/tom chmod 777 /storage/timemachine So, now that I have a compressed ZFS dataset to store the backups on, backup directories created, and a FreeBSD group created, I can create afp.conf.  I’ve chosen to limit Time Machine to 500GB space for each user. ; ; Netatalk 3.x configuration file ; [Global] vol preset = default_for_all_vol log file = /var/log/netatalk.log log level = default:warn  hosts allow = mimic model = TimeCapsule6,116 disconnect time = 1 vol dbpath = /var/netatalk/CNID/$u/$v/ [default_for_all_vol] file perm = 0640 directory perm = 0750 cnid scheme = dbd [Homes] basedir regex = /storage/home #500 GB (units of MB) vol size limit = 512000 [TimeMachine] time machine = yes path=/storage/timemachine/$u valid users = @timemachine #500 GB (units of MB) vol size limit = 512000 You should notice that the path of the [TimeMachine] share is set to path=/storage/timemachine/$u This means that for each logged in user, $u is substituted wth the name of the user. So, when Time Machine logs in as “tom”, the data is stored at /storage/timemachine/tom. Only members of the group “timemachine” will be able to use Time Machine. This line vol dbpath = /var/netatalk/CNID/$u/$v/ Ensures that each user as a CNID database for each volume.  Without this line, there is a single CNID database which is shared for all users who are using TimeMachine.  That generally results in corrupting the CNID database.  By specifying /$u/$v, we get a CNID database for each user for each volume, which is much more reliable. By specifying a disconnect time of one hour: disconnect time = 1 We can disconnect orphaned sessions and hopefully avoid the dreaded “volume in use” error in TimeMachine. The rest of the steps are exactly as in the previous blog entry. You’ll need to start dbus, avahi, and netatalk, like this: /usr/local/etc/rc.d/dbus onestart /usr/local/etc/rc.d/avahi-daemon onestart /usr/local/etc/rc.d/netatalk onestart The next step takes place on your OS X client machine.  On each host that will perform backups, enable Time Machine to see non-TM volumes: defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1 Then, mount your user’s share using afp://.  This will make the share visible to TimeMachine. After this, you should be able to see your Netatalk shares in Time Machine, and perform backups