Backing up Mac OS X to a Windows machine

Persistent Inappeasable Mind

Tuesday, November 10. 2009

Backing up Mac OS X to a Windows machine

Software hints

I know there's plenty of backing up/synchronizing software for Mac. I know Time Machine is awesome. But none of the software I tried was able to do it my way :). Thus, as I have a Linux/FreeBSD background, I wanted to do it my way and the command line solution seamed to be a good one.

My office Windows machine has plenty of disk space and is rarely used. It was an ideal system (with not so ideal file system) to do backups on.

Prerequisites: 

  • First I needed to share a folder on my Windows machine to my Mac laptop. Here's a nice tutorial on how to do this: How to mount a Windows shared folder on your Mac.
  • Next I needed the good backup software. I am fairly familiar with rdiff-backup. It's doing incremental backups, it's easy to use and it does its job really well. To install rdiff-backup I used MacPorts. Follow this guide to install MacPorts. It's easy as installing every mac software.
  • I also wanted a notification window to pop up each time it tried to do a backup and informing me if it succeeded or not. I used growlnotify. Needless to say you have to install Growl as well.

1. step: install rdiff-backup

First I needed to install rdiff-backup:

$ sudo port install rdiff-backup

2. step: install growlnotify

Next I had to install growlnotify (moving into a folder of a mounted Growl-x.x.dmg image)

$ cd /Volumes/Growl-1.2/Extras/growlnotify/
$ ./install.sh

3. step: check local IP address

Then I had to check my IP to see if I am connected to my office network (wired network interface en0). This could be probably done in a simpler way but I came up with this idea in seconds (all of this could be done with awk or sed :=)) and is funny to see so many pipes.

$ ifconfig | sed -n '/en0/,/media/p' | grep -v inet6 | grep inet | awk '{print $2}'  

             I had few seconds and here's a simpler version:

        $ ifconfig | awk '/en0/,/ether/ {if($1 == "inet") {print $2}}'

4. step: ping the Windows PC

Then I needed to check if my Windows machine was on and listening (only one ping should be enough):

$ ping -c 1 148.88.226.250

5. step: mount a shared samba folder

Then I checked if I could mount my Windows shared folder (samba). To do this I wanted to use Mac OS X keychain for for password so it would not be written in my bash script. My shared folder is smb://mkljun@MKLJUNDESKTOP/mkljunHome where mkljun is my username, MKLJUNDESKTOP my Windows machine name (IP address should do the same) and mkljunHome my shared folder.

$ osascript -e "try" -e "mount volume \"smb://mkljun@MKLJUNDESKTOP/mkljunHome\"" -e "end try"

This command would on other systems look something like like:
$ mount -t smbfs //mkljundesktop/mkljunHome /Volumes/mkljunHome -o username=mkljun, password=XXX
.

6. step: rdiff-backup

Then I checked if rdiff-backup is working properly (backing up my home folder on Mac OS X to a folder on the Windows machine).

$ rdiff-backup /Users/mkljun /Volumes/mkljunHome/BackupMac

7. step: growlnotify

A check if growlnotify is working.

$ growlnotify -t "backup" -m "Your IP is XXX but backup computer YYY could not be reached"

8. step : The Script

And I was ready to write a bash script

#!/bin/bash
# my backup script in /Users/mkljun/backup.sh

DestinationIP="148.88.226.250"
SourceIP=`ifconfig | sed -n '/en0/,/media/p' | grep -v inet6 | grep inet | awk '{print $2}'`

# ping destination (backup) ip address; output redirected to /dev/null
ping -c 1 $DestinationIP > /dev/null
# check if ping successful
if [ $? != 0 ]
then
    # if ping not successful, print notification (echo should be in one line!!)
    echo -e "-t 'Backup failed' -m 'Your IP is $SourceIP. Backup PC $DestinationIP 
                could not be reached'" | xargs /usr/local/bin/growlnotify
else
    # mount samba drive (osascript should be in one line)
    osascript -e "try" -e "mount volume \"smb://mkljun@MKLJUNDESKTOP/mkljunHome\"" 
                 -e "end try" > /dev/null
    # check if mount was successful
    if [ $? == 0 ]; then
      # this echo should be in one line with a pipe
      echo "-t 'Backup' -m 'Your IP is $SourceIP. Starting backing up now'" 
                    | xargs /usr/local/bin/growlnotify
      rdiff-backup /Users/mkljun /Volumes/mkljunHome/BackupMac > /dev/null
      # check if rdiff-backup successful
      if [ $? == 0 ]; then
        echo "-t 'Backup' -m 'Backup completed successfully'" | xargs /usr/local/bin/growlnotify
      else
        echo "-t 'Backup failed' -m 'Something was wrong'" | xargs /usr/local/bin/growlnotify
      fi
      # delete all backups older than 2 weeks
      rdiff-backup --remove-older-than 2W /Volumes/mkljunHome/BackupMac > /dev/null
    fi
fi

It is probably not the nicest script out there but its working. I could and probably should redirect standard outputs to a log file (with a day as a title) to to check it once in a while to see if the script is working (and even check if the file grew too big and delete it if necessary). But so far it works flawlessly for few days.

9. step: cron

The last thing to do was setting up a cron job so the script would run without my intervention. Let's say I want to run it every week day at 10AM when I'm probably in the office (there are two stars between 10 and 1-5 which are not showing up for some reason '0 10 1-5').

$ crontab -e
0 10   1-5 /Users/mkljun/backup.sh

10. the last version of a script

UPDATE: Here is the last version with logging to a file and all variables at the beginning of the script.


Trackbacks

When backup software fails (Time Machine)
It is very important to have daily/weekly/monthly backups of own information. I know many people realize the importance of backups only when worst happens - disk failures and a lot of studies show that users do not pay atention to this particular problem
Weblog: Persistent Inappeasable Mind
Tracked: Jul 09, 16:48

Comments
Display comments as (Linear | Threaded)

#1 - bunam 2009-11-20 23:25 -

Helo,
Did you have no trouble with long filenames or special chars or attributes ?
I planed to do the same but inside a mounted dmg or a sparsebundle image on the smb/windows share.

#1.1 - mkljun 2009-11-22 23:57 -

I did have have issues (I thought I pointed that out with "not so great file system").

1. Win FS has no support for hard links. I could survive with this. But if you are going to do your backup to a dmg image (with HFS) this would not be an issue. I actually did the exact thing but I was worried what would happen if the image gets corrupted. Right now I do backups on Win FS but I'm getting another machine with Linux and ext4 FS.

2. The only files that did make problems were those in Firefox and Thunderbird profile. So I first tar both profile folders and exclude them while performing backup:

http://rdiff-backup.nongnu.org/examples.html#exclude

#2 - Michael 2009-11-25 09:09 -

Thanks for this. I only wish I had found this before I decided to reformat my 2TB hard drive so I could still have used the drive on windows.


Add Comment

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Can you please write (or copy/paste) this text in the field below: i h a t e s p a m