Rsync in lieu of Time Machine

Status
Not open for further replies.

Eric Batte

Dabbler
Joined
Jan 11, 2015
Messages
27
Hey guys,

I've been using Freenas for the past 12 months as a time machine destination for my small company OSX Server. It worked fine until last month and just stopped working. I won't bore you with the details because I suspect its a Mac OS problem, but I'm thinking of this scenario instead of time machine:

1. Rsync files from Mac to Freenas on an hourly schedule to pickup incremental changes
2. Take hourly/daily/monthly snapshots of the data copied from OSX to replicate the same type of schedule that time machine keeps, expiring as needed

Anything unreasonable with that as a supplementary backup plan?

PS - I will continue to keep another drive with a time machine backup, but I also back this server up to crashplan central, and nightly clones of all drives so I have multiple copies in various locations.
 

Robert Trevellyan

Pony Wrangler
Joined
May 16, 2014
Messages
3,778
Anything unreasonable with that as a supplementary backup plan?
Seems reasonable to me. For an easier but not free setup, consider buying a copy of Arq Backup* and setting it up with an SSH destination on your FreeNAS.
* just a satisfied customer ...
 

Eric Batte

Dabbler
Joined
Jan 11, 2015
Messages
27
Thanks for the tip. I never heard or Arq.
 

Eric Batte

Dabbler
Joined
Jan 11, 2015
Messages
27
I'm seeking some assistance getting rsync setup either direction (OSX->Freenas or Freenas<-OSX). I've been trying tirelessly and it just shouldn't be this difficult to setup. I can't get complete success using an rsync task on Freenas or by trying to push from terminal in OSX to Freenas.

Currently my rsync task on Freenas results in:
"rsync error: error in rsync protocol data stream (code 12) at io.c(226) [Receiver=3.1.1]"

...and running
rsync -aH --no-p /Volumes/Shares/Shared\ Folders/Archive [user]@freenas:/mnt/Volume1/Archive
on the OSX command line starts copying a lot of files and ultimately hangs without completing.


Thoughts, suggestions are appreciated. Of course if there is a definitive guide to rsyncing between Freenas & OSX please point me to it. I haven't found a really great guide.

Thanks
 

Robert Trevellyan

Pony Wrangler
Joined
May 16, 2014
Messages
3,778
I've been working on a couple of python scripts for this. They run in a standard jail on FreeNAS and pull backups from the Macs, with hard-linking between incremental snapshots and regular pruning to keep storage space under control.

There are lots of caveats:
  • significant manual setup involved
  • manual restart if you restart the jail or FreeNAS
  • no notifications of success or failure
  • only tested locally for a couple of weeks on 4 Macs
  • manual restore, e.g. via NFS read-only share
If you're interested, I'll try to document reproducible steps for setup and post them ... someplace.
history.png
 
Last edited:

Eric Batte

Dabbler
Joined
Jan 11, 2015
Messages
27
I'd be interested in seeing what you're ve got setup. But I'm also curious why you chose this path of a python script running in a jail pulling from OS X. Could you not get a standard rsync task to work in freenas? Wouldn't it have less of these caveats if you pushed from OS X to freenas and/or did your scripting in OS X so you could creat notifications a little easier, etc?

Thanks
Eric
 

Robert Trevellyan

Pony Wrangler
Joined
May 16, 2014
Messages
3,778
A few reasons:
  • The scripts are general purpose (they can work with an attached hard drive) and should work on any *nix that has python and rsync installed, so tying them to a FreeNAS task was not desirable.
  • Pruning is much easier to do on the destination, so pulling from the server rather than pushing from the client is indicated.
  • They work regardless of whether anyone is logged in on the client.
  • I chose python because I've been teaching myself python.
The approach is inspired partly by BackupPC. The server is always on, and it attempts to pull a backup on a regular interval. If the client responds, a backup is made. If not, nothing bad happens.
 

Eric Batte

Dabbler
Joined
Jan 11, 2015
Messages
27
Thanks. How does your solution compare to a freenas rsync task?
 

Robert Trevellyan

Pony Wrangler
Joined
May 16, 2014
Messages
3,778
I see a few differences:
  1. There's absolutely no chance mine will start a new rsync while the previous one is still running.
  2. Mine stores each backup in a date- and time-stamped folder.
  3. Mine prunes old backups the same way Time Machine does, as you can see if you study the screenshot closely.
 

Henning Kessler

Contributor
Joined
Feb 10, 2015
Messages
143
Another alternative would be using openzfsonosx on the Mac and use zfs replication to FreeNAS
 

Robert Trevellyan

Pony Wrangler
Joined
May 16, 2014
Messages
3,778
OK, here goes with some very bare-bones instructions on how to use my scripts. Obviously, I will not take responsibility for any resulting data loss. Please note, I realized there was no clear benefit to running this from a jail, so I'm assuming you're not, because it makes the instructions much simpler. If you want to run this from a jail, you'll have to install the underlying software (python, rsync, mDNSResponder etc) and figure out how to automate it if you think that's important.
  1. Create a dataset for your rsync backups.
  2. Inside, create a folder or child dataset for each client user’s backup repository.
  3. Create a suitable rsync.exclude inside each client’s repository.
  4. Create a read-only share to use for restore (per client if privacy is a concern).
  5. If you don’t yet have an SSH key pair for your FreeNAS root user, login as root and run ssh-keygen. Press enter 3 times to accept the default location and no passphrase.
  6. Copy /root/.ssh/id_rsa.pub to the shared folder(s).
  7. For each client user, from the client machine, connect to the read-only share and copy or append id_rsa.pub to ~/.ssh/authorized_keys.
  8. Test SSH from FreeNAS to each client. If you have to enter a password, you did it wrong.
  9. Place backup.py and prune.py in a suitable location. The parent dataset from step 1 is as good a place as any. Make them executable.
  10. Create a startup shell script to launch backup.py for each client.
  11. Run the startup shell script from the command-line. Optionally, set up a task to launch it as a Post Init script.
The backup script will launch rsync, pulling from the client and writing to a folder named pending. If the backup completes successfully, pending will be renamed with the date- and time-stamp of when the backup completed. The next backup will be attempted one hour after the previous one completes, regardless of success or failure.

After a successful backup, the backup script will launch prune.py to prune existing backups, keeping up to 24 hours of hourly backups, up to 4 weeks of daily backups, and up to 1 year of weekly backups.

Inside each backup folder, you will find rsync.log, which itemizes the rsync transfer that created it, and prune.log, which shows which backups were retained and which were pruned after it was completed.

My startup shell script, located in the same folder as the backup and pruning scripts, looks like this:
Code:
./backup.py sue@media-mini:/Users media-mini &
./backup.py rob@robs-mini:/Users robs-mini &
./backup.py rob@robs-air:/Users robs-air &
./backup.py sue@sues-air:/Users sues-air &

The syntax is: <path-to-backup-script> <user>@<machine>:<source folder> <path-to-repository>. The trailing ampersand on each line means "launch this as a background task and return". Therefore, I'm backing up the Users folder from each client machine to a folder on FreeNAS with the same name as the client machine. The user in each case has permission to read everything inside the Users folder. If that's not the case for you, you will need to backup more selectively, or create another user on the client machine that can access everything you want to backup.

Backup script (backup.py): http://pastebin.com/RqECqwgU
Pruning script (prune.py): http://pastebin.com/jUmmWpZy
Example rsync.exclude for OS X: http://pastebin.com/MaTwEwP3

NOTE 1: the backup script assumes that the pruning script is called "prune.py", and that both are in the same folder.
NOTE 2: I had trouble with long machine names not being resolved by Bonjour on FreeNAS. For example, my laptop used to be called "robs-macbook-air", but FreeNAS couldn't find it via Bonjour, so I renamed it to "robs-air". I don't know if it was the length of the name or the second hyphen that caused the problem.
NOTE 3: Do NOT attempt to backup more than one source to the same repository.

Please let me know if you discover any glaring defects. Better still, let me know if you find it useful.
 
Last edited:

Eric Batte

Dabbler
Joined
Jan 11, 2015
Messages
27
Thanks for the info Robert. Let me chew on this and see if I might give it a try.
 

Robert Trevellyan

Pony Wrangler
Joined
May 16, 2014
Messages
3,778
Please note, I just updated the pruning script with one that will actually keep the weekly backups.
:oops:
 

Robert Trevellyan

Pony Wrangler
Joined
May 16, 2014
Messages
3,778
Out of curiosity, I decided to try the FreeNAS rsync task option. The biggest differences from the python script approach described above are:

Negative - the user can no longer browse the backup history, because it's in the ZFS snapshots. They can only restore from the most recent backup. A skilled operator must be called on to assist with restore from a previous backup.

Positive - each rsync run takes a fraction of the time, because it doesn't have to build the directories and hard links.

With that in mind, the setup process would be:
  1. Create a dataset for your rsync backups.
  2. Inside, create a folder or child dataset for each client user’s backup repository.
  3. Create a suitable rsync.exclude inside each client’s repository.
  4. Create a read-only share to use for restore (per client if privacy is a concern).
  5. If you don’t yet have an SSH key pair for your FreeNAS root user, login as root and run ssh-keygen. Press enter 3 times to accept the default location and no passphrase.
  6. Copy /root/.ssh/id_rsa.pub to the shared folder(s).
  7. For each client user, from the client machine, connect to the read-only share and copy or append id_rsa.pub to ~/.ssh/authorized_keys.
  8. Test SSH from FreeNAS to each client. If you have to enter a password, you did it wrong.
  9. For each client, set up a FreeNAS rsync Pull task, with the timing arranged so they don't all kick off at once. Leave enough time between runs to allow for the expected rate of creation of new data. Check the rsync Archive and Delete options, and uncheck all the others. Put --delete-excluded --exclude-from=<path-to-exclude-file-for-client> in the Extra options box. Leave the task disabled.
  10. Run the task manually and let it finish. The first run will take much longer than subsequent runs.
  11. Enable the task.
  12. Set up your desired schedule(s) for ZFS snapshots on the dataset(s).
 

pirateghost

Unintelligible Geek
Joined
Feb 29, 2012
Messages
4,219
Interesting. I use 'backintime' on my laptop (Fedora) and my desktop (Arch). Gives me a nice GUI for my backups on my machines. I have the Windows boxes my wife and son use set up to push rsync to datasets that they can 'restore previous version' from at any time. I like this script you made. I might look at changing the way I back up.
 

Eric Batte

Dabbler
Joined
Jan 11, 2015
Messages
27
Windows machines can also browse zfs snapshots via "previous versions" in Explorer. This might be the the simplest way to access them that I'm aware of. Too bad there isn't a native way to do it in OS X.
 

Robert Trevellyan

Pony Wrangler
Joined
May 16, 2014
Messages
3,778
Well, you can always do zfs set snapdir=visible on your rsync dataset, and then make a read-only share of the .zfs/snapshot folder.
 
Last edited:

Robert Trevellyan

Pony Wrangler
Joined
May 16, 2014
Messages
3,778
make a read-only share of the .zfs/snapshot folder
Seems like that doesn't actually work very well. Probably better to make a read-only share of the dataset root and then navigate into .zfs/snapshot as necessary.
 

Eric Batte

Dabbler
Joined
Jan 11, 2015
Messages
27
Here's my next challenge: the remote path I'm trying to rsync has a space in it. I can't get the rsync task to validate the path no matter how I format the path using the escape character or quotes. Any thoughts on this?
 
Status
Not open for further replies.
Top