Time Machine is the Mac way of doing backups. The concept is fairly similar to incremental rsync snapshots. Officially, Apple does not support Time Machine backups to a network volume: network drives don’t show up in the Time Machine user interface. The only way to get network-based Time Machine is by buying a Time Capsule.

When doing a Time Machine backup to a normal disk (I tried it with a LaCie 1TB USB disk), one can see the file structure created. Mine looked like this: Backups.backupdb///Macintosh HD/… Inside this directory is my full system (minus the parts I explicitly excluded in the Time Machine config).

Since we have more than 1 Mac, I’d like to have all of them back up to the same hard drive. I already have a Linux-based server serving files over AFP. This is where it gets more interesting…

Once you get your linux server ready as an AFP server, as described in this blogpost, time has come to convince Time Machine to show unsupported drives as well. I also checked what the setting was before I changed it:

$ defaults
Command line interface to a user's defaults.
Syntax:

'defaults' [-currentHost | -host ] followed by one of the following:

  read                                 shows all defaults
  read                         shows defaults for given domain
  read                    shows defaults for given domain, key

  read-type               shows the type for the given domain, key

  write            writes domain (overwrites existing)
  write            writes key for domain

  rename     renames old_key to new_key

  delete                       deletes domain
  delete                  deletes key in domain

  domains                              lists all domains
  find                           lists all entries containing word
  help                                 print this help

 is (  | -app  | -globalDomain )
         or a path to a file omitting the '.plist' extension

 is one of:
  
  -string 
  -data 
  -int[eger] 
  -float  
  -bool[ean] (true | false | yes | no)
  -date 
  -array   ...
  -array-add   ...
  -dict     ...
  -dict-add   ...
$ defaults read com.apple.systempreferences TMShowUnsupportedNetworkVolumes
2008-12-06 15:12:37.248 defaults[10027:10b]
The domain/default pair of (com.apple.systempreferences, TMShowUnsupportedNetworkVolumes) does not exist
$ defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1
$ defaults read com.apple.systempreferences TMShowUnsupportedNetworkVolumes
1
$

In my setup, I ran into this problem and had to create my sparsebundle myself. This has the added advantage that I can choose the maximum size of the backup; Time Machine, by default, will use the complete disk! Contrary to the link above, I used Case Sensitive HFS+ to match the settings I found on a friends Time Capsule. This blogpost goes even deeper into detail on the settings for the creation of a sparsebundle.

At this point, I had my Time Machine setup working over the network, but I don’t consider it a good backup solution yet. The problem is that the sparsebundle is Apple specific. In the very unlikely event that Apple decides to stop support for Time Machine and sparsebundles, I can’t reach my data. So I searched for a way to retrieve the data stored inside the sparsebundle using open source tools.

Digging deeper into the sparsebundle file format, I realized that it’s not a file, but a directory. Mac OS X conveniently hides the content until you explicitly ask for it (Show Package content). Turns out that the internal structure looks like this:

drwxr-sr-x 3 root root 4096 2008-12-09 17:46 bands
-rw-r--r-- 1 root root  497 2008-12-09 17:27 Info.bckup
-rw-r--r-- 1 root root  497 2008-12-09 17:27 Info.plist
-rw-r--r-- 1 root root    0 2008-12-09 17:27 token

Inside bands are a bunch of hexadecimal numbered files, each (but the last one) the same size (8MB). The Info.plist and Info.bckup are the same:





	CFBundleInfoDictionaryVersion
	6.0
	band-size
	8388608
	bundle-backingstore-version
	1
	diskimage-bundle-type
	com.apple.diskimage.sparsebundle
	size
	2147516416

The content is fairly self explaining: It’s a disk image of 2147516416 bytes (2GB). The bands are 8MB (8388608 bytes) each.

I wrote a bash script to convert this sparsebundle format to a single dmg image. Obviously this script comes without any warranty at all. I tried it on a few test images and it seems to work fine. If the underlying unix-filesystem supports it, the dmg will be sparse.

To mount the dmg, I just did

mount -t hfsplus -o loop,ro Backup_image.dmg /mnt/tmp

Eventhough the dmg seems to have a partition table, the mount succeeds on my system (Ubuntu 8.10 server). The directory structure looks similar as described above, until you come down to the last level of directories (Desktop inside your user for example).

Here, Time Machine does some very weird stuff. Probably that’s the reason this only works inside a disk image and not naively over AFP. The directory listing (ls -li) looks like this:

10408 -r--r--r--   879 root root     0 2008-12-09 17:27 bin
10410 -r--r--r--   881 root root     0 2008-12-09 17:27 Desktop
10412 -r--r--r--   885 root root     0 2008-12-09 17:27 Documents
10413 drwx------     1  501 dialout 37 2008-11-29 15:00 Library
10997 -r--r--r-- 10141 root root     0 2008-12-09 17:27 Music
10999 -r--r--r-- 10150 root root     0 2008-12-09 17:27 Pictures
11001 -r--r--r-- 10166 root root     0 2008-12-09 17:27 Public
11003 -r--r--r-- 10171 root root     0 2008-12-09 17:27 Sites

Note that the “directory” Desktop is actually a file. Apparently, the “inode number” is a reference to the actual directory name in the “.HFS+ Private Directory”. Going into this directory revealed my Desktop at the time of the backup. Success at last!

3 Comments

  1. Pierre Gohon says:

    I’m trying to use you bash script but the image I get is of “data” type (file command), It’s not just seen as a HFS+ volume :

    [71868.211485] hfs: unable to find HFS+ superblock
    [72712.598367] hfs: unable to find HFS+ superblock

    Any idea ?

  2. Niobos says:

    Hmm, strange.

    Have you tried opening the resulting .dmg on MacOSX? If MacOS is able to read the file, it has something to do with your linux distribution. If not, it has something to do with the script…

    I remember playing around with the type of sparsebundle I used (partition map type). Maybe this is the problem you are seeing?
    I see that I have been thoughtful enough to forget to note what partition type I used…

    Hope this helps.

  3. Chris Harshman says:

    FYI, the layout ‘SPUD’ (not the default GPTSPUD) is what’s required for Linux to mount without complaining about a missing superblock:

    Mac $ hdiutil create -type SPARSEBUNDLE -fs HFS+ -size 10m -layout SPUD ./test_SPUD

    (Mounted the sparsebundle on the Mac, copied a text file, unmounted, and dragged-and-dropped to a Linux home directory exported via Samba)

    Linux # /usr/local/bin/sparsebundle_to_dmg.sh test_MBRSPUD.sparsebundle/ test_MBRSPUD.dmg
    Linux # mount -t hfsplus -o loop,ro test_MBRSPUD.dmg /mnt
    Linux # # ls /mnt
    untitled text 2