Rsync-Bootable-Backup-in-Yosemite

Rsync Bootable Backup in Yosemite

I am cheap. And I don’t like to use things like CCC if I can use open source tools like rsync, so I was intrigued to find Nicholas Challager’s 2011 post on making a bootable backup of OSX using rsync.

Of course, OSX has changed a lot. And even well maintained, paid backup solutions like CCC (vers. 3.x) have been badly broken by new releases of OSX. However, why not give it a go?

I followed the instructions: making my PNY 128gb usb 3.0 a formatted disk using Mac OS X Extended (Journaled) GUI Partition Table, set the drive not to ignore permissions in the finder, made the .backupignore file and ran the script.

Failure.

I went into the script

  
#!/bin/bash

# Disc backup script
# Requires rsync 3

# Ask for the administrator password upfront
sudo -v

# IMPORTANT: Make sure you update the `DST` variable to match the name of the
# destination backup drive

DST="/Volumes/Macintosh HD/"
SRC="/"
EXCLUDE="$HOME/.backupignore"

PROG=$0

# --acls                   update the destination ACLs to be the same as the source ACLs
# --archive                turn on archive mode (recursive copy + retain attributes)
# --delete                 delete any files that have been deleted locally
# --delete-excluded        delete any files (on DST) that are part of the list of excluded files
# --exclude-from           reference a list of files to exclude
# --hard-links             preserve hard-links
# --one-file-system        don't cross device boundaries (ignore mounted volumes)
# --sparse                 handle sparse files efficiently
# --verbose                increase verbosity
# --xattrs                 update the remote extended attributes to be the same as the local ones

if [ ! -r "$SRC" ]; then
    logger -t $PROG "Source $SRC not readable - Cannot start the sync process"
    exit;
fi

if [ ! -w "$DST" ]; then
    logger -t $PROG "Destination $DST not writeable - Cannot start the sync process"
    exit;
fi

logger -t $PROG "Start rsync"

sudo rsync --acls \
           --archive \
           --delete \
           --delete-excluded \
           --exclude-from=$EXCLUDE \
           --hard-links \
           --one-file-system \
           --sparse \
           --verbose \
           --xattrs \
           "$SRC" "$DST"

logger -t $PROG "End rsync"

# Make the backup bootable
sudo bless -folder "$DST"/System/Library/CoreServices

exit 0
  

Oh, ok. We’re not echoing things? We’re logging them? I went and changed that… and for the time being did:

$ cat /var/log/systemlog.systemlog grep rsync

Which showed me there were permissions issues. I looked again at my stickdrive. It’s groups did not match the groups on my drive… so I added an admin group and set that to read/write and went again.

Rsync ran this time without issues.

I booted up, pressed OPTION (entered my firmware password because I set that up) and selected my new bootable drive. Surprsiingly, this boot took about 10 minutes to complete. And once started, took about 10 more to even complete login. Unable even to open a terminal window to see my logs, I watched with some interest as the system figured out in Finder that the USB drive was not mounted, but the new root. After the system moved the drive from the list of mounted drives to a subfolder on the system… things ran decently. Spotlight had to rebuild a lot of things, and chrome was quite confused, but after another 20 minute of erroring (the logs of which enormous) the system started chugging along at a decnet pace. I ejected the “mounted” Macintosh HD. And tings went fine.

Upon reboot things went even faster, although startup was still slow… and a lot of errors go to the logs… it is not bad.

Switching back to my healthy internal HD, I decided to retry the process… after disabling a few startup items and turning off spotlight, and adding chrome/safari/firefox cache folders to .backupignore. Strangely, the rsync script failed with a permissions error.

Looking into the permissions, I found that the computer had unilaterally changed the permissions of my drive: resetting defaults for “ignore disk permissions” and (while not deleting the administrator profile) giving it read-only access for some unknown reason.

Apparently this bad behavior is set by /var/db/volinfo.database… and can be fixed by deleting this file. I found that worked, briefly… but that upon restart/ejection/etc. the permissions errors cropped up again.

So I amended the script, adding three lines after the EXCLUDE definition… and as well added the –checksum option to try to make sure that the slow startup wasn’t related to file corruption:

    
#!/bin/bash

# Disc backup script
# Requires rsync 3

# Ask for the administrator password upfront
sudo -v
# IMPORTANT: Make sure you update the `DST` variable to match the name of the
# destination backup drive

DST="/Volumes/Backup"
SRC="/"
EXCLUDE="$HOME/.backupignore"

sudo chflags nouchg $DST
sudo chown root:admin $DST
sudo chmod 775 $DST

PROG=$0

# --acls                   update the destination ACLs to be the same as the source ACLs
# --archive                turn on archive mode (recursive copy + retain attributes)
# --delete                 delete any files that have been deleted locally
# --delete-excluded        delete any files (on DST) that are part of the list of excluded files
# --exclude-from           reference a list of files to exclude
# --hard-links             preserve hard-links
# --one-file-system =--x   don't cross device boundaries (ignore mounted volumes)
# --sparse                 handle sparse files efficiently
# --verbose                increase verbosity
# --xattrs                 update the remote extended attributes to be the same as the local ones
# --p                      keep permissions

if [ ! -r "$SRC" ]; then
    echo "Source $SRC not readable - Cannot start the sync process"
    exit;
fi

if [ ! -w "$DST" ]; then
    echo "Destination $DST not writeable - Cannot start the sync process"
    exit;
fi

echo "Start rsync"

sudo rsync --acls \
           --archive \
           --delete \
           --delete-excluded \
           --exclude-from=$EXCLUDE \
           --hard-links \
           --one-file-system \
           --sparse \
           --verbose \
           --xattrs \
           --checksum \
           "$SRC" "$DST"

logger -t $PROG "End rsync"

# Make the backup bootable
sudo bless -folder "$DST"/System/Library/CoreServices

exit 0

  

It’s hacky, it’s ugly, and it’s slow… but it works for free… and I can set it to run regularly with cron. So I’m pleased enough to leave it here, and see if anybody wants to improve further. I would like it to work fast, from the get-go, but… the fact that it resolves errors eventually… that’s all I really need if my system ever does completely bite the dust. I can get back to coding real fast, and restore my data… and do a clean install of osx after without paying for 3rd party software.

Bugs: among other things, using target disk mode to start up to usb fails… option key works fine. Notes: Pressing shift during login, on your slow, cranky, rescure drive disables some extraneous login items. Some launched anyway… but… it saved some time.

comments powered by Disqus