1 # -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
2 # vim: set filetype=sh sw=3 sts=3 expandtab autoindent:
4 # backupninja handler to do incremental backups using
5 # rsync and hardlinks, based on
7 # http://www.mikerubel.org/computers/rsync_snapshots/
9 # feedback: rhatto at riseup.net | gpl
10 # lot of enhancements grabbed from "rsnap" handler by paulv at bikkel.org
16 # log = rsync log file
17 # partition = partition where the backup lives
18 # fscheck = set to 1 if fsck should run on $partition after the backup is made
19 # read_only = set to 1 if $partition is mounted read-only
20 # mountpoint = backup partition mountpoint or backup main folder
21 # backupdir = folder relative do $mountpoint where the backup should be stored
22 # days = number of backup increments (min = 5)
23 # lockfile = lockfile to be kept during backup execution
24 # nicelevel = rsync command nice level
25 # enable_mv_timestamp_bug = set to "yes" if your system isnt handling timestamps correctly
29 # from = local or remote
30 # host = source hostname or ip, if remote backup
31 # testconnect = when "yes", test the connection for a remote source before backup
32 # include = include folder on backup
33 # exclude = exclude folder on backup
34 # ssh = ssh command line (remote only)
35 # rsync = rsync program
36 # rsync_options = rsync command options
37 # exclude_vserver = vserver-name (valid only if vservers = yes on backupninja.conf)
38 # numericids = when set to 1, use numeric ids instead of user/group mappings on rsync
39 # compress = if set to 1, compress data on rsync (remote source only)
40 # bandwidthlimit = set a badnwidth limit in kbps (remote source only)
41 # remote_rsync = remote rsync program (remote source only)
44 # initscripts = absolute path where scripts are located
45 # service = script name to be stoped at the begining of the backup and started at its end
47 # You can also specify some system comands if you don't want the default system values:
52 # touch = touch command
56 # You dont need to manually specify vservers using "include = /vservers".
57 # They are automatically backuped if vserver is set to "yes" on you backupninja.conf.
60 # config file evaluation
70 getconf log /var/log/backup/rsync.log
80 getconf enable_mv_timestamp_bug no
85 getconf testconnect no
87 getconf rsync_options "-av --delete"
93 getconf exclude_vserver
96 getconf bandwidthlimit
97 getconf remote_rsync rsync
103 # function definitions
107 if [[ "$2" < 4 ]]; then
108 error "Rotate: minimum of 4 rotations"
112 if [ -d $1.$2 ]; then
113 $nice $mv /$1.$2 /$1.tmp
116 for ((n=`echo "$2 - 1" | bc`; n >= 0; n--)); do
117 if [ -d $1.$n ]; then
118 dest=`echo "$n + 1" | bc`
119 $nice $mv /$1.$n /$1.$dest
124 if [ -d $1.tmp ]; then
125 $nice $mv /$1.tmp /$1.0
129 $nice $cp -alf /$1.1/. /$1.0
134 function move_files {
136 ref=$tmp/makesnapshot-mymv-$$;
144 backupdir="$mountpoint/$backupdir"
146 # does $backupdir exists?
148 if [ ! -d "$backupdir" ]; then
149 error "Backupdir $backupdir does not exist"
153 # setup number of increments
155 if [ -z "$days" ]; then
158 keep="`echo $days - 1 | bc -l`"
163 if [ ! -z "$lockfile" ]; then
164 $touch $lockfile || warning "Could not create lockfile $lockfile"
169 if [ ! -z "$nicelevel" ]; then
170 nice="nice -n $nicelevel"
177 if [ "$from" == "remote" ] && [ "$testconnect" == "yes" ]; then
178 debug "$ssh -o PasswordAuthentication=no $user@$host 'echo -n 1'"
179 result=`ssh -o PasswordAuthentication=no $user@$host 'echo -n 1'`
180 if [ "$result" != "1" ]; then
181 fatal "Can't connect to $host as $user."
183 debug "Connected to $srchost successfully"
187 # rsync options for local sources
189 if [ "$from" == "local" ]; then
191 rsync_local_options="$rsync_options"
193 if [ ! -z "$numericids" ]; then
194 rsync_local_options="$rsync_local_options --numeric-ids "
199 # rsync options for remote sources
201 if [ "$from" == "remote" ]; then
203 rsync_remote_options="$rsync_options --rsync-path=$remote_rsync"
205 if [ "$compress" == "1" ]; then
206 rsync_remote_options="$rsync_remote_options --compress"
209 if [ ! -z "$bandwidthlimit" ]; then
210 rsync_remote_options="$rsync_remote_options --bwlimit=$bandwidthlimit"
213 if [ ! -z "$numericids" ]; then
214 rsync_remote_options="$rsync_remote_options --numeric-ids"
221 if [ $enable_mv_timestamp_bug == "yes" ]; then
227 for path in $exclude; do
228 EXCLUDES="$EXCLUDES --exclude=$path"
233 if [ ! -z "$service" ]; then
234 for daemon in $service; do
235 info "Stopping service $daemon..."
236 $initscripts/$daemon stop
240 echo "Starting backup at `date`" >> $log
242 # mount backup destination folder as read-write
244 if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then
245 if [ -d "$mountpoint" ]; then
246 mount -o remount,rw $mountpoint
248 error "Could not mount $mountpoint"
254 # add vservers to included folders
256 if [ "$vservers_are_available" == "yes" ]; then
258 # sane permission on backup
259 mkdir -p $backupdir/$VROOTDIR
260 chmod 000 $backupdir/$VROOTDIR
262 for candidate in $found_vservers; do
263 candidate="`basename $candidate`"
264 found_excluded_vserver="0"
265 for excluded_vserver in $exclude_vserver; do
266 if [ "$excluded_vserver" == "$candidate" ]; then
267 found_excluded_vserver="1"
271 if [ "$found_excluded_vserver" == "0" ]; then
272 include="$include $VROOTDIR/$candidate"
277 # the backup procedure
279 for SECTION in $include; do
281 section="`basename $SECTION`"
283 if [ ! -d "$backupdir/$SECTION/$section.0" ]; then
284 mkdir -p $backupdir/$SECTION/$section.0
287 info "Rotating $backupdir/$SECTION/$section..."
288 echo "Rotating $backupdir/$SECTION/$section..." >> $log
289 rotate $backupdir/$SECTION/$section $keep
290 info "Syncing $SECTION on $backupdir/$SECTION/$section.0..."
292 if [ "$from" == "local" ]; then
293 debug $rsync $rsync_local_options $EXCLUDES /$SECTION/ $backupdir/$SECTION/$section.0/
294 $nice $rsync $rsync_local_options $EXCLUDES /$SECTION/ $backupdir/$SECTION/$section.0/ >> $log
295 if [ "$?" != "0" ]; then
296 warning "Rsync error when trying to transfer $SECTION"
298 elif [ "$from" == "remote" ]; then
299 if [ -z "$user" ] || [ -z "$host" ]; then
300 error "Config file error: either user or host was not specified"
303 debug $nice $rsync $rsync_remote_options $EXCLUDES -e "$ssh" $user@$host:/$SECTION/ $backupdir/$SECTION/$section.0
304 $nice $rsync $rsync_remote_options $EXCLUDES -e "$ssh" $user@$host:/$SECTION/ $backupdir/$SECTION/$section.0 >> $log
305 if [ "$?" != "0" ]; then
306 warning "Rsync error when trying to transfer $SECTION"
310 error "Invalid source $from"
314 $touch $backupdir/$SECTION/$section.0
318 # remount backup destination as read-only
320 if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then
321 mount -o remount,ro $mountpoint
324 # check partition for errors
326 if [ "$fscheck" == "1" ] || [ "$fscheck" == "yes" ]; then
329 warning "Could not umount $mountpoint to run fsck"
331 $nice $fsck -v -y $partition >> $log
338 if [ ! -z "$service" ]; then
339 for daemon in $service; do
340 info "Starting service $daemon..."
341 $initscripts/$daemon start
345 # removes the lockfile
347 if [ ! -z "$lockfile" ]; then
348 $rm $lockfile || warning "Could not remove lockfile $lockfile"
351 echo "Finnishing backup at `date`" >> $log