Mac – Time Machine on a Raspberry Pi

Requirements

First of all, you need the following:

  • a raspberry pi installed with 1 USB port available,
  • 1 external USB drive (I’ve used a 3TB external USB drive), pre-formatted under your Mac in HSF+, labelled as TimeMachine
  • internet connection 🙂
  • …and some time to perform all the steps and the initial backup.

Installation of your pi

As root, run the following to upgrade the system and install the required packages:

apt-get update && apt-get upgrade && apt-get -y install hfsplus hfsutils hfsprogs avahi-daemon libavahi-client3 db-util libgcrypt11

Now all the required debian packages are installed. We will install netatalk from the source code, because the debian packages are very old.

Setup the hard drive

Create a mount point as root:

mkdir /TimeMachine

Connect your external USB drive to your pi and run as root the following:

blkid

The output should be something like this:

 # blkid
/dev/mmcblk0p1: SEC_TYPE="msdos" UUID="xxxx-xxxx" TYPE="vfat"
/dev/mmcblk0p2: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" TYPE="ext4"
/dev/sda1: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" TYPE="ext3"
/dev/sdb1: LABEL="EFI" UUID="xxxx-xxxx" TYPE="vfat"
/dev/sdb2: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" LABEL="TimeMachine" TYPE="hfsplus"

Please take note of the UUID where you can see your hard drive installed and add the following line in your /etc/fstab file:

UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" /TimeMachine hfsplus rw,force,exec,auto,users 0 0

Now your drive will be automatically mounted at each reboot of the machine.

Install and configure Netatalk demon

Here you have 3 options:

  1. You can follow this guide if you want to create a .deb package which is easier manageable, especially on Debian;
  2. (For the lazy ones) download my precompiled deb file of version 3.1.1 from here, or 3.1.7 version from here, unzip and install it using dpkg -i
  3. Otherwise… just follow the next steps 🙂
Compile and install Netatalk

Download the latest stable code from here.
I’ve personally used version 3.0.4 for a while, and now I’ve upgraded to version 3.1.7.

Decompress the file, enter the folder and run the following:

./configure --with-init-style=debian --with-zeroconf

If no errors:

make

As root:

make install
cd /etc/init.d/
update-rc.d netatalk defaults

Configure afp.conf

Based on your version, you could have the configuration files in different locations.
Use the command afpd -v | grep "afp.conf"  to locate your afp.conf file.

Edit afp.conf based on your network configuration:

I’ve setup also an extra bit called [Homes] which shares the user /home directory using the same protocol. Quite handy to move around files 🙂 But this last part is NOT required for the scope of this post.

[Global]
mimic model = TimeCapsule6,106
; Global server settings
; Name of your computer in apple devices network
hostname = <your raspberry pi HOSTNAME>
; IP of your Pi
afp listen = <your raspberry pi IP>
hosts allow = <your network or the Mac's IP, for example 192.168.1.0/24>
; logging config
log file = /var/log/netatalk.log
log level = default:warn

[TimeMachine]
; Our Time Machine volume
path = /TimeMachine
cnid scheme = dbd
file perm = 0660
directory perm = 0770
time machine = yes

[Homes]
basedir regex = /home
cnid scheme = dbd
; Display each user home directory in this format
home name = Home $u

Now we can mount the drive and restart the services:

mount /TimeMachine && /etc/init.d/netatalk restart && /etc/init.d/avahi-daemon restart

Now the disk should be visible from your Mac and Time Machine application 🙂

First Time Machine backup

For the first Time Machine backup, I would really recommend to connect the external drive directly to the USB port of your Mac and follow these steps.

Before disconnect the drive from your pi, make sure to stop the services and unmount properly the disk:

/etc/init.d/avahi-daemon stop && /etc/init.d/netatalk stop && umount /TimeMachine && mount

Make sure the output does NOT show /TimeMachine mounted.

Create a sparsebundle manually

Connect the USB drive to your Mac and from the Terminal do the following:

cd /Volumes/TimeMachine/
hdiutil create -size 1500g -fs HFS+J -volname "TMachine" NAME_XXXXXXXXXXXX.sparsebundle

NAME is the hostname
XXXXXXXXXX is your MAC Address without “:”
200g means 1.5 TB (1500 GB). Please make sure it’s big enough to contain the first backup. After it will expand automatically. But if you set it less than the space required for the first backup, Time Machine might ignore it and create a normal folder structure, typical of USB hard drives.
Best practise is set about 80% of the capacity of your hard drive 😉

Start the first backup

Then, add this disk to Time Machine and let’s the backup start and finish.
For the fist backup, if it’s around 1Tb, be ready to leave the PC on all day.

Make sure that NO directories are created in the USB disk.
Just check the size of the sparsebundle file during the initial backup process. If it increases, it’s working! 🙂

I have to admit that I was doing something else when I’ve launched the backup and I’ve realised (I guess) that the sparsebundle file got renamed by Time Machine in a format like <hostname>.sparsebundle. Not sure why but… well, all worked so… from now on, I will use this new name for that file. :-p

If the backup doesn’t start automatically using the sparsebundle file, you can try to force it following these steps:

1) double click on your file sparsebunle to mount it
2) From Terminal, as superuser, run

tmutil setdestination /Volumes/TMachine/

3) Now force to run a new backup

Once completed, just take notes of the current permission of that file. You can check via terminal running ls -l /Volumes/TimeMachine/.
Now unmount the hard drive and reconnect it to your Raspberry Pi.

Final setup on the Raspberry Pi

Before mounting, do a quick check running the following (/dev/sdb2 is my Time Machine drive – please review the output of blkid if unsure):

fsck.hfsplus -f /dev/sdb2

If all is fine, you can mount the drive:

mount /TimeMachine/

And now, do a little trick to make sure to avoid permissions issues, and allow Time Machine to be able to write into the sparsebundle “file” (you will realise on Linux that it’s in fact a directory tree with files).

We’re going to create the same user and group that we have on the Mac on our Raspberry Pi.
Run a handy ls -l /TimeMachine and take note of the UID and GID.
If the group shows as numeric value, as root, you can run groupadd -g GID MACGROUP .

NOTE:GID is the value that you’ve seen with the previous command and MACGROUP is the name of the group that you saw running ls -l /Volumes/TimeMachine/ on you Mac Terminal.

Now, as root, create a new user that matches with the Mac user.

useradd -u UID -g GID MACUSER -m

NOTE: Same as before, UID is the value that you’ve seen with the previous command and MACUSER is the name of the user that you saw running ls -l /Volumes/TimeMachine/ on you Mac Terminal.

Now check again with ls -l /TimeMachine and you should see something like this: drwxr-xr-x 1 macuser staff 11 Apr 2 10:22 HOSTNAME.sparsebundle

NOTE: The group might be displayed as ‘dialout’ (or something else) instead of ‘staff’ as on your Mac. This is not a problem, as long as the numeric GID matches. If the group still shows as numeric value, it groupadd -g GID ‘staff’

All good? Then let’s restart netatalk:

/etc/init.d/netatalk restart

And now, we’re ready to:

  1. Add the remote disk “TimeMachine” to Time Machine;
  2. Initialise a second backup, just to make sure that all works fine (this will be probably less than 1GB);
  3. Have a drink as reward after all this work 🙂

Sources:
http://garmoncheg.blogspot.com.au/2012/11/time-capsule-for-25.html
http://administeria.com/?s=time+machine
http://buffalo.nas-central.org/wiki/Time_Machine_&_Time_Capsule_support_on_your_LinkStation