|MiNi0n|
October 2nd, 2002, 16:13
Originally saw this idea on deadly.org here:

http://undeadly.org/cgi?action=article&sid=20020920002712

I simply "OpenBSDified" the Linux scripts found here:

http://www.mikerubel.org/computers/rsync_snapshots/

-----

Previous to setting up the above I was using a rather weak implementation of dump to backup files in /home on my network at home. After tweaking the scripts I now have a snapshot style backup that creates snapshots of my home every 4 hours as well as a daily snapshot save taken at 1:00 AM. Because of the way it's setup it takes very little space and it's quite simple to exclude files you don't want/need backed up and as well if you're able to use a secondary drive for it it will remount as read only once the snapshots are done so you can't delete them. In essence you can create a mini NetApp on your system using a secondary disc!!!

You'll need to build rsync out of the ports to get started. Next I recommend you read the second article I listed above as it will explain how the whole process works in more clarity than I can muster.

The main difference between the Linux scripts in the above and what you'll need to get it working on OpenBSD lies in differences between Linux's cp command and mount commands. I've included my scripts below so you can see how I tweaked them.


What's important to understand is my system setup so that you can understand my scripts.

-> first hd at wd0 with the standard partitions
-> second hd at wd1h mounted at /u


I've merely altered Mike's brilliant scripts to suit my needs as such:

---- make_snapshot.sh ----

#!/usr/local/bin/bash
# ----------------------------------------------------------------------
# mikes handy rotating-filesystem-snapshot utility
# ----------------------------------------------------------------------
# RCS info: $Id: make_snapshot.sh,v 1.6 2002/04/06 04:20:00 mrubel Exp $
# ----------------------------------------------------------------------
# this needs to be a lot more general, but the basic idea is it makes
# rotating backup-snapshots of /home whenever called
# ----------------------------------------------------------------------

# ------------- system commands used by this script --------------------
ID=/usr/bin/id;
ECHO=/bin/echo;

MOUNT=/sbin/mount;
UMOUNT=/sbin/umount;
RM=/bin/rm;
MV=/bin/mv;
CP=/bin/cp;
TOUCH=/usr/bin/touch;

RSYNC=/usr/local/bin/rsync;


# ------------- file locations -----------------------------------------

MOUNT_DEVICE=/dev/wd1h;
SNAPSHOT_RW=/u;
EXCLUDES=/root/backup_exclude;


# ------------- the script itself --------------------------------------

# make sure we're running as root
if (( `$ID -u` != 0 )); then { $ECHO "Sorry, must be root. Exiting..."; exit; } fi

# attempt to remount the R mount point as RW; else abort
$UMOUNT $MOUNT_DEVICE ;
$MOUNT -rw $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
$ECHO "snapshot: could not remount $SNAPSHOT_RW readwrite";
exit;
}
fi;


# rotating snapshots of /home

# step 1: delete the oldest snapshot, if it exists:
if [ -d $SNAPSHOT_RW/home/hourly.3 ] ; then \
$RM -rf $SNAPSHOT_RW/home/hourly.3 ; \
fi ;

# step 2: shift the middle snapshots(s) back by one, if they exist
if [ -d $SNAPSHOT_RW/home/hourly.2 ] ; then \
$MV $SNAPSHOT_RW/home/hourly.2 $SNAPSHOT_RW/home/hourly.3 ; \
fi;
if [ -d $SNAPSHOT_RW/home/hourly.1 ] ; then \
$MV $SNAPSHOT_RW/home/hourly.1 $SNAPSHOT_RW/home/hourly.2 ; \
fi;

# step 3: make a hard-link-only (except for dirs) copy of the latest snapshot,
# if that exists
if [ -d $SNAPSHOT_RW/home/hourly.0 ] ; then \
cd $SNAPSHOT_RW/home/hourly.0 && find . -print | cpio -p -dl ../hourly.1 && cd /root ;
fi;

# step 4: rsync from the system into the latest snapshot (notice that
# rsync behaves like cp --remove-destination by default, so the destination
# is unlinked first. If it were not so, this would copy over the other
# snapshot(s) too!
$RSYNC \
-va --delete --delete-excluded \
--exclude-from="$EXCLUDES" \
/home/ $SNAPSHOT_RW/home/hourly.0 ;

# step 5: update the mtime of hourly.0 to reflect the snapshot time
$TOUCH $SNAPSHOT_RW/home/hourly.0 ;

# and thats it for home.

# now remount the RW snapshot mountpoint as readonly

$UMOUNT $SNAPSHOT_RW ;
$MOUNT -r $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
$ECHO "snapshot: could not remount $SNAPSHOT_RW readonly";
exit;
} fi;

---- end make_snapshot.sh ----

Next we have the script to make the daily:

---- daily_snapshot_rotate.sh ----

#!/usr/local/bin/bash
# ----------------------------------------------------------------------
# mikes handy rotating-filesystem-snapshot utility: daily snapshots
# ----------------------------------------------------------------------
# RCS info: $Id: daily_snapshot_rotate.sh,v 1.2 2002/03/25 21:53:27 mrubel Exp $
# ----------------------------------------------------------------------
# intended to be run daily as a cron job when hourly.3 contains the
# midnight (or whenever you want) snapshot; say, 13:00 for 4-hour snapshots.
# ----------------------------------------------------------------------

# ------------- system commands used by this script --------------------
ID=/usr/bin/id;
ECHO=/bin/echo;

MOUNT=/sbin/mount;
UMOUNT=/sbin/umount;
RM=/bin/rm;
MV=/bin/mv;
CP=/bin/cp;

# ------------- file locations -----------------------------------------

MOUNT_DEVICE=/dev/wd1h;
SNAPSHOT_RW=/u;

# ------------- the script itself --------------------------------------

# make sure we're running as root
if (( `$ID -u` != 0 )); then { $ECHO "Sorry, must be root. Exiting..."; exit; } fi

# attempt to remount the R mount point as RW; else abort
$UMOUNT $MOUNT_DEVICE ;
$MOUNT -rw $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
$ECHO "snapshot: could not remount $SNAPSHOT_RW readwrite";
exit;
}
fi;


# step 1: delete the oldest snapshot, if it exists:
if [ -d $SNAPSHOT_RW/home/daily.2 ] ; then \
$RM -rf $SNAPSHOT_RW/home/daily.2 ; \
fi ;

# step 2: shift the middle snapshots(s) back by one, if they exist
if [ -d $SNAPSHOT_RW/home/daily.1 ] ; then \
$MV $SNAPSHOT_RW/home/daily.1 $SNAPSHOT_RW/home/daily.2 ; \
fi;
if [ -d $SNAPSHOT_RW/home/daily.0 ] ; then \
$MV $SNAPSHOT_RW/home/daily.0 $SNAPSHOT_RW/home/daily.1; \
fi;

# step 3: make a hard-link-only (except for dirs) copy of
# hourly.3, assuming that exists, into daily.0
if [ -d $SNAPSHOT_RW/home/hourly.3 ] ; then \
# $CP -al $SNAPSHOT_RW/home/hourly.3 $SNAPSHOT_RW/home/daily.0 ; \
cd $SNAPSHOT_RW/home/hourly.3 && find . -print | cpio -p -dl ../daily.0 && cd /root ;
fi;

# note: do *not* update the mtime of daily.0; it will reflect
# when hourly.3 was made, which should be correct.

# now remount the RW snapshot mountpoint as readonly

$UMOUNT $SNAPSHOT_RW ;
$MOUNT -r $MOUNT_DEVICE $SNAPSHOT_RW ;

if (( $? )); then
{
$ECHO "snapshot: could not remount $SNAPSHOT_RW readonly";
exit;
} fi;

---- end daily_snapshot_rotate.sh ----



I put my exludes list in /root/backup_excludes, the format of the file should resemble this:

aurora# cat /root/backup_exclude
Tunez/
My_Music/
apps/
aurold/
Maildir/
2k/
Favorites/
FreeBSD/


You can cron this up just as Mike's page suggests. I didn't /dev/null my crons initially so I could see the output of each to get a good idea of what exactly was taking place and being backed up.

cod3fr3ak
April 13th, 2005, 09:13
I think i might try this... Thanks.

draconius
August 17th, 2005, 11:53
This is a good howto! I would like to point out this document, http://caia.swin.edu.au/reports/020927A/ , which has a similar method of backups that I originally followed when setting up my backup scheme at work.

This article also was based entirely on freebsd, and uses SSH / Rsync when doing backups, if you need to do backups over a non-secure link....which I do.

Anyways, nice job making the linux tutorial work with fbsd, and if anybody needs help with it, the article I am posting may help you out!

Kernel_Killer
August 17th, 2005, 13:00
This will also work for OS X images as well, now that rsync has been updated to handle resource forks (Just have to add the -T option in rsync).