At this moment I am using Oleg's firmware on the Asus WL500g Premium. This device is used for Wifi router and samba server with USB hard disk and printer. I have also a Linksys NSLU2 with OpenSlug firmware as a NAS in my network. I want to backup this NAS automatically to the USB hard disk attached to the WL500g Premium. I found a nice description about how to do this [here](http://www.mikerubel.org/computers/rsync_snapshots/). This article describes exactly what i need, an "Easy automated snapshot-style backup".

The automated snapshot-style backup

How it works in detail can you read it in this article. In short the mechanism what is used is simple and powerful. The result is that each time you run a backup, a complete directory structure will be stored on the backup disk, but a file which is not changed will not be stored more than once. This is done by using hard links. When you create a normal file, the filename in a directory will be the first hard link. One file can have more than one hard link. A file with more than one hard links, will be permanantly deleted when the last hard link is removed. How to install and configure the rsync server on my NAS I am using rsync. First i installed a rsync server on my Linksys NAS

$ ipkg install rsync

To automatically startup the rsync server, i created a startup script:

$ vi /etc/init.d/rsyncd

#!/bin/sh  

case "$1" in  

start)  
 echo Starting rsync daemon  
 rsync --daemon  
 ;;  

stop)  
 echo Stopping running rsync daemon  
 killall rsync  
 ;;  

*) echo "command ignored" >&2  
 ;;  

esac

Make it executable by:

$ chmod +x /etc/init.d/rsyncd

Start it automatically in initlevel 3:

$ cd /etc/rc3.d  
$ ln -s /etc/init.d/rsyncd S90rsyncd

In the file /etc/rsync.conf, i have the following configured. More about rsync.conf

$ vi /etc/rsyncd.conf

#  
# configure according to your needs  
uid = arjan  
gid = users  
use chroot = yes  
max connections = 5  
syslog facility = local3  
pid file = /var/run/rsyncd.pid  
secrets file = /opt/etc/rsyncd.secrets  

[nas]  
path = /opt  
comment = Rietveld NAS  
read only = no  
hosts allow = 192.168.1.255/24  4

How to install and configure th4e backup script on my Asus WL500g Premium

The backup script will be created in /usr/local/sbin/rsync_script. The script will be used by other scripts:

MOUNT_DEVICE=/dev/discs/disc0/part3  
SOURCE_DIR=rsync://192.168.1.240/nas/  
SNAPSHOT_RW=/opt/nas  
SNAPSHOT_SUBDIR=Backup  
EXCLUDES=/opt/etc/backup_exclude  
DEST_BASE=$1  
RETVAL=0

if [ "$DEST_BASE" = "" ]  
then  
    echo Usage:  
    echo rsync_script BASE_NAME  
    echo " "  
    echo The BASE_NAME is for example: hourly, daily
    echo This will be the dir name in de backup dir
    exit  

fi

if [ -e /var/run/rsync_script ] ; then  
    echo Abort: other sync script is already running:  
    cat /var/run/rsync_script  
    exit  
fi  

echo Currently running rsync_$DEST_BASE script > /var/run/rsync_script_
echo Remounting $SNAPSHOT_RW for Read/Write access > /tmp/rsync_$DEST_BASE.log  

/bin/mount -o remount,rw $MOUNT_DEVICE $SNAPSHOT_RW  

if [ $? -ne 0 ]  
then  
    echo "snapshot: could not remount $SNAPSHOT_RW readwrite"  
    exit  
fi

echo ------------- Check before starting rsync ----------------- >> /tmp/rsync_$DEST_BASE.log  

# if this .first directory exists, something went wrong in the previous sync. Restore the name to .1  
echo Check if something went wrong in the past, check if $DEST_BASE.first does already exists >> /tmp/rsync_$DEST_BASE.log  

if [ -d $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.first ] ; then  
    echo $DEST_BASE.first does already exists, rename it to latest_snapshot >> /tmp/rsync_$DEST_BASE.log  
    /bin/mv $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.first $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/latest_snapshot  

    if [ $? -ne 0 ]; then  
        echo ERROR: renaming $DEST_BASE.first into latest_snapshot is failed >> /tmp/rsync_$DEST_BASE.log  
        RETVAL=1  
    fi  
fi  

echo "." >> /tmp/rsync_$DEST_BASE.log
echo ------------- starting rsync ----------------- >> /tmp/rsync_$DEST_BASE.log  
echo Check if a latest_snapshot directory is available >> /tmp/rsync_$DEST_BASE.log  

if [ -d $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/latest_snapshot ] ; then  
    echo latest_snapshot directory is available, so start a normal rsync operation >> /tmp/rsync_$DEST_BASE.log  
    /bin/mv $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/latest_snapshot $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.first  
    if [ $? -ne 0 ]; then  
        echo ERROR: renaming latest_snapshot into $DEST_BASE.first is failed >> /tmp/rsync_$DEST_BASE.log  
        RETVAL=1  
    fi


    echo "." >> /tmp/rsync_$DEST_BASE.log  
    if [ $RETVAL -eq 0 ]; then  

        /opt/bin/rsync -av --delete --link-dest=$SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.first/ $SOURCE_DIR $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/latest_snapshot/ >> /tmp/rsync_$DEST_BASE.log  

        if [ $? -ne 0 ]; then  
            echo ERROR: rsync command failed >> /tmp/rsync_$DEST_BASE.log  
            RETVAL=1  
        fi  
    fi  
else  
    echo latest_snapshot directory is not available, so start the first rsync operation >> /tmp/rsync_$DEST_BASE.log  
    echo this will take a while, so send a mail with information >> /tmp/rsync_$DEST_BASE.log  
    /usr/local/sbin/mail "De backup is voor de eerste keer gestart, dit kan wel even duren voordat dit klaar is!"
    echo "." >> /tmp/rsync_$DEST_BASE.log  
    /opt/bin/rsync -av $SOURCE_DIR $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/latest_snapshot/ >> /tmp/rsync_$DEST_BASE.log  
    if [ $? -ne 0 ]; then  
        echo ERROR: rsync command failed >> /tmp/rsync_$DEST_BASE.log  
        RETVAL=1  
    fi  
fi  

echo "." >> /tmp/rsync_$DEST_BASE.log
if [ $RETVAL -eq 0 ]; then  
    echo ------------- Until now everything ok, so start backup directory rotation ----------------- >> /tmp/rsync_$DEST_BASE.log  
    # Only do the directory rotation if everything went OK
    # delete the oldest snapshot, if it exists:  
    if [ -d $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.5 ] ; then  
        echo Removing $DEST_BASE.5 now >> /tmp/rsync_$DEST_BASE.log  
        /bin/rm -rf $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.5  
        if [ $? -ne 0 ]; then  
            echo ERROR: removing $DEST_BASE.5 failed >> /tmp/rsync_$DEST_BASE.log  
            RETVAL=1  
        fi  
    fi
    if [ -d $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.4 ] ; then  
        echo Rename $DEST_BASE.4 into $DEST_BASE.5 >> /tmp/rsync_$DEST_BASE.log  
        /bin/mv $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.4 $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.5  
        if [ $? -ne 0 ]; then  
            echo ERROR: renaming $DEST_BASE.4 into $DEST_BASE.5 failed >> /tmp/rsync_$DEST_BASE.log  
            RETVAL=1  
        fi  
    fi

    if [ -d $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.3 ] ; then  
        echo Rename $DEST_BASE.3 into $DEST_BASE.4 >> /tmp/rsync_$DEST_BASE.log  
        /bin/mv $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.3 $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.4  
        if [ $? -ne 0 ]; then  
            echo ERROR: renaming $DEST_BASE.3 into $DEST_BASE.4 failed >> /tmp/rsync_$DEST_BASE.log  
            RETVAL=1  
        fi  
    fi

    if [ -d $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.2 ] ; then  
    echo Rename $DEST_BASE.2 into $DEST_BASE.3 >> /tmp/rsync_$DEST_BASE.log  
    /bin/mv $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.2 $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.3  
        if [ $? -ne 0 ]; then  
            echo ERROR: renaming $DEST_BASE.2 into $DEST_BASE.3 failed >> /tmp/rsync_$DEST_BASE.log  
            RETVAL=1  
        fi  
    fi

    if [ -d $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.1 ] ; then  
        echo Rename $DEST_BASE.1 into $DEST_BASE.2 >> /tmp/rsync_$DEST_BASE.log  
        /bin/mv $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.1 $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.2  
        if [ $? -ne 0 ]; then  
            echo ERROR: renaming $DEST_BASE.1 into $DEST_BASE.2 failed >> /tmp/rsync_$DEST_BASE.log  
            RETVAL=1  
        fi  
    fi

    if [ -d $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.first ] ; then  
        echo Rename $DEST_BASE.first into $DEST_BASE.1 >> /tmp/rsync_$DEST_BASE.log  
        /bin/mv $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.first $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/$DEST_BASE.1  
        if [ $? -ne 0 ]; then  
            echo ERROR: renaming $DEST_BASE.first into $DEST_BASE.1 failed >> /tmp/rsync_$DEST_BASE.log  
            RETVAL=1  
        fi  
    fi
fi

echo Touching latest_snapshot into the current date and time >> /tmp/rsync_$DEST_BASE.log  
/bin/touch $SNAPSHOT_RW/$SNAPSHOT_SUBDIR/latest_snapshot  
if [ $? -ne 0 ]; then  
    echo ERROR: touching latest_snapshot failed >> /tmp/rsync_$DEST_BASE.log  
    RETVAL=1  
fi
echo Remounting $SNAPSHOT_RW for Read Only access >> /tmp/rsync_$DEST_BASE.log  
/bin/mount -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW  
if [ $? -ne 0 ]; then  
    echo "ERROR: could not remount $SNAPSHOT_RW readonly" >> /tmp/rsync_$DEST_BASE.log  
    RETVAL=1  
fi

if [ $RETVAL -ne 0 ]; then  
    echo "ERROR detected while running rsync, send a mail to report this!" >> /tmp/rsync_$DEST_BASE.log  
    /usr/local/sbin/mailfile "De rsync $DEST_BASE is niet goed gegaan" /tmp/rsync_$DEST_BASE.log  
else  
    echo "No ERROR detected while running rsync" >> /tmp/rsync_$DEST_BASE.log  
    # /usr/local/sbin/mail "De rsync $DEST_BASE is goed gegaan"
    /usr/local/sbin/mailfile "TEST: De rsync $DEST_BASE is goed gegaan, inclusief logfile" /tmp/rsync_$DEST_BASE.log  
fi

rm /var/run/rsync_script_

The rsync_script file is a common script and will be called from several other files, for example /usr/local/sbin/rsync_hourly and contains only:

rsync_script 2hourly

The other scripts to make a backup per day, week, month and year will contain the following:

  • rsync_daily: rsync_script daily
  • rsync_weekly: rsync_script weekly
  • rsync_monthly: rsync_script monthly
  • rsync_yearly: rsync_script yearly

We can use the cron task to perform this automatically /opt/etc/crontab:

SHELL=/bin/sh  
PATH=/opt/sbin:/opt/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin  
MAILTO=""  
HOME=/  
# ---------- ---------- Default is Empty ---------- ---------- #  
* */12 * * * admin /usr/local/sbin/rsync_hourly  
0 1 * * * admin /usr/local/sbin/rsync_daily  
0 0 * * 0 admin /usr/local/sbin/rsync_weekly  
0 0 1 * * admin /usr/local/sbin/rsync_monthly  
0 18 31 12 * admin /usr/local/sbin/rsync_yearly

To send the mail you have to create the following scripts using mini_sendmail: Mini_sendmail is default in the Oleg firmware. /usr/local/sbin/mail:

MAILFROM=yourmail@provider.com  
MAILTO=destination@provider.com  
MAILOPT="-ssmtp.fiberworld.nl -f"

if [ "$1" = "" ]; then  
 echo "Usage: mail "  
 exit  
fi

( echo "From: <${MAILFROM}>  
 To: <${MAILTO}>  
 Subject: $1  
 ";  
) mini_sendmail ${MAILOPT}${MAILFROM} ${MAILTO}

/usr/local/sbin/mailfile:

MAILFROM=yourmail@provider.com  
MAILTO=destination@provider.com  
MAILOPT="-ssmtp.fiberworld.nl -f"

if [ "$1" = "" ]; then  
    echo "Usage: "  
    exit  
fi

( echo "From: <${MAILFROM}>  
To: <${MAILTO}>  
Subject: $1  
De volgende file is vanuit de Asus WL500g Premium verstuurd  
------------------  
";  
cat $2  
) mini_sendmail ${MAILOPT}${MAILFROM} ${MAILTO}

For maintenance on the backup disk it is also nice to remount it as rw back again. You can use this script /usr/local/sbin/mount_opt_rw:

MOUNT_DEVICE=/dev/discs/disc0/part3  
SNAPSHOT_RW=/opt/nas

mount -o remount,rw $MOUNT_DEVICE $SNAPSHOT_RW  

if [ $? -ne 0 ]; then  
    echo "snapshot: could not remount $SNAPSHOT_RW readonly"  
    exit  
fi

The /etc/backup_exclude contains:

$ vi /etc/backup_exclude

/NotBackuped/  
/lost+found/  

mini_sendmail information:

More rsync information:

Another backup project: