by Bernd Schemmer, Initial Release: March 2009, Last Update: Aug 2009
Homepage: http://www.bnsmb.de/
Table of contents
There are a lot of useful things that can be done with ZFS - one of them is to create a cheap disk based backup with versioning using ZFS and rsync.
rsync is normally used to keep directories on different machines in sync. The main advantage of rsync compared with other solutions (like a simple cp) is it's efficient algorithm to copy only the files (or the part of the files) that changed. Using rsync together with the snapshot feature of ZFS you can create a fast disk based backup solution with versioning very easy.
This article only describes how to configure rsync and ZFS for this special purpose - it does not talk about the other ZFS or rsync features.
A machine running Solaris 10 either on x86 or SPARC with ZFS on
which rsync is also installed.
Note: ZFS is included in Solaris by default. rsync is part
of Solaris Express Community Edition (package: SUNWrsync) and
OpenSolaris. In the Solaris 10 OS rsync is only available on the
Companion CD (package: SFWrsync) and has to be installed
separately.
rsync home page: http://samba.anu.edu.au/rsync/
Manifest for rsync: http://opensolaris.org/os/community/smf/manifests/
First make sure that rsync is installed :
$ rsync --version rsync version 2.6.9 protocol version 29 Copyright (C) 1996-2006 by Andrew Tridgell, Wayne Davison, and others. <http://rsync.samba.org/> Capabilities: 64-bit files, socketpairs, hard links, symlinks, batchfiles, inplace, no IPv6, 64-bit system inums, 64-bit internal inums rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the GNU General Public License for details.
Then create a ZFS filesystem to hold the backups, e.g.
$ zfs create usbbox001/backup/bnsmb/sol9new
Now create or edit the rsync daemon config file (/etc/rsyncd.conf) and add a section for every backup, e.g.
[elke] comment = Backup of Elke's T40 path = /usbbox001/backup/elke/tp40 numeric ids = true log file = /var/log/rsyncd_elke.log list = true uid = root post-xfer exec = /usr/bin/create_zfs_snapshot $RSYNC_MODULE_PATH read only = false write only = false [sol9new] comment = Backup of the sol9 root fs (new) use chroot = yes path = /usbbox001/backup/bnsmb/sol9new/ numeric ids = true log file = /var/log/rsyncd_sol9.log list = true uid = root post-xfer exec = /usr/bin/create_zfs_snapshot $RSYNC_MODULE_PATH read only = false write only = false
In this example two backups are configured, one called "elke" and the other called "sol9new".
The important lines here are
post-xfer exec = /usr/bin/create_zfs_snapshot $RSYNC_MODULE_PATH
This line instructs the rsync daemon to call the executable /usr/bin/create_zfs_snapshot after a rsync session ends. The parameter $RSYNC_MODULE_PATH is replaced with the value for the entry "path" by the rsync daemon. Using this entry we can automatically create a ZFS snapshot after every rsync session.
The script /usr/bin/create_zfs_snapshot looks like:
#!/usr/bin/ksh # # Usage: /usr/bin/create_zfs_snapshot directoryname1 [... [directoryname#] # # for testing ... #PREFIX="echo " PREFIX="" SNAPSHOT_NAME="$( date | tr " " "_" )" for CURDIR in $* ; do ZFS_FS="$( zfs list -H ${CURDIR} | cut -f1 - )" ${PREFIX} zfs snapshot ${ZFS_FS}@${SNAPSHOT_NAME} done
The last thing missing is an SMF service to start the rsync daemon. You can either write one yourself or use the one referenced in the References above.
Note: Use ZFS delegation if you're running the rsync daemon under another user than root.
Now you can create as many backups as you like by calling rsync and the rsync daemon configuration automatically ensures the versioning via ZFS snapshots.
For example to create a regular backup of my Solaris root filesystem I use this script
$ cat /tools/scripts/backup_rootfs.sh
/usr/bin/rsync --progress --log-file /var/log/backup_rootfs.log --stats --sparse --keep-dirlinks \
--hard-links --executability --delete-after --one-file-system -ax / sol9::sol9new/rootfs
which is called regularly via an cron entry:
$ crontab -l | grep backup_rootfs
0 3 * * 0 /tools/scripts/backup_rootfs.sh 2>&1 >>/var/log/backup_rootfs_std_stderr.log
To view the snapshots use
zfs list -r -t snapshot <zfsvolume>
e.g
$ zfs list -r -t snapshot usbbox001/backup/elke/tp40 NAME USED AVAIL REFER MOUNTPOINT usbbox001/backup/elke/tp40@Sa_17_Jan_14:11:54_CET_2009 25.4K - 26.9K - usbbox001/backup/elke/tp40@Sat_Jan_17_18:27:50_MET_2009 801M - 2.63G - usbbox001/backup/elke/tp40@Thu_Feb_12_23:00:01_CET_2009 0 - 2.13G - usbbox001/backup/elke/tp40@Thu_Feb_12_23:04:07_CET_2009 0 - 2.13G - usbbox001/backup/elke/tp40@Thu_Feb_19_20:21:40_CET_2009 1.10M - 2.11G -
Omry Yadan wrote a small java program that does the same:
zync (http://projects.firefang.net/wiki/Zync)
Zync is a Java program that combines the power of rsync and zfs snapshots to back up remote servers. Configuration is very easy, and once configured, all you need to do is to add it to cron to be executed as often as you would like.