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: