How to use ZFS and rsync to create a backup solution with versioning

by Bernd Schemmer, Initial Release: March 2009, Last Update: Aug 2009

Homepage: http://www.bnsmb.de/

Table of contents

  1. How to use ZFS and rsync to create a backup solution with versioning
    1. Introduction
    2. Purpose
    3. Scope
    4. Prerequisites
    5. References
    6. Installation
    7. Usage
    8. To Do
    9. Links


Introduction

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.

Purpose

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.

Scope

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.

Prerequisites

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.

References

rsync home page: http://samba.anu.edu.au/rsync/
Manifest for rsync: http://opensolaris.org/os/community/smf/manifests/

Installation

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.

Usage

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  -

To Do

Links

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.