2 # backupninja handler to do incremental backups using
3 # rsync and hardlinks, based on
5 # - http://www.mikerubel.org/computers/rsync_snapshots/
6 # - rsnap handler by paulv at bikkel.org
7 # - maildir handler from backupninja
9 # feedback: rhatto at riseup.net | gpl
15 # log = rsync log file
16 # partition = partition where the backup lives
17 # fscheck = set to 1 if fsck should run on $partition after the backup is made
18 # read_only = set to 1 if $partition is mounted read-only
19 # mountpoint = backup partition mountpoint or backup main folder (either local or remote)
20 # backupdir = folder relative do $mountpoint where the backup should be stored (local or remote)
21 # format = specify backup storage format: short, long or mirror (i.e, no rotations)
22 # days = for short storage format, specify the number of backup increments (min = 5)
23 # keepdaily = for long storage format, specify the number of daily backup increments
24 # keepweekly = for long storage format, specify the number of weekly backup increments
25 # keepmonthly = for long storage format, specify the number of monthly backup increments
26 # lockfile = lockfile to be kept during backup execution
27 # nicelevel = rsync command nice level
28 # enable_mv_timestamp_bug = set to "yes" if your system isnt handling timestamps correctly
30 # multiconnection = set to "yes" if you want to use multiconnection ssh support
33 # from = local or remote
34 # host = source hostname or ip, if remote backup
35 # port = remote port number (remote source only)
36 # user = remote user name (remote source only)
37 # testconnect = when "yes", test the connection for a remote source before backup
38 # include = include folder on backup
39 # exclude = exclude folder on backup
40 # ssh = ssh command line (remote source only)
41 # protocol = ssh or rsync (remote source only)
42 # rsync = rsync program
43 # rsync_options = rsync command options
44 # exclude_vserver = vserver-name (valid only if vservers = yes on backupninja.conf)
45 # numericids = when set to 1, use numeric ids instead of user/group mappings on rsync
46 # compress = if set to 1, compress data on rsync (remote source only)
47 # bandwidthlimit = set a badnwidth limit in kbps (remote source only)
48 # remote_rsync = remote rsync program (remote source only)
49 # id_file = ssh key file (remote source only)
50 # batch = set to "yes" to rsync use a batch file as source
51 # batchbase = folder where the batch file is located
52 # filelist = set yes if you want rsync to use a file list source
53 # filelistbase = folder where the file list is placed
56 # dest = backup destination type (local or remote)
57 # testconnect = when "yes", test the connection for a remote source before backup
58 # ssh = ssh command line (remote dest only)
59 # protocol = ssh or rsync (remote dest only)
60 # numericids = when set to 1, use numeric ids instead of user/group mappings on rsync
61 # compress = if set to 1, compress data on rsync (remote source only)
62 # host = destination host name (remote destination only)
63 # port = remote port number (remote destination only)
64 # user = remote user name (remote destination only)
65 # id_file = ssh key file (remote destination only)
66 # bandwidthlimit = set a badnwidth limit in kbps (remote destination only)
67 # remote_rsync = remote rsync program (remote dest only)
68 # batch = set to "yes" to rsync write a batch file from the changes
69 # batchbase = folder where the batch file should be written
70 # fakesuper = set to yes so rsync use the --fake-super flag (remote destination only)
73 # initscripts = absolute path where scripts are located
74 # service = script name to be stoped at the begining of the backup and started at its end
76 # You can also specify some system comands if you don't want the default system values:
81 # touch = touch command
85 # You dont need to manually specify vservers using "include = /vservers".
86 # They are automatically backuped if vserver is set to "yes" on you backupninja.conf.
91 # 20090329 - rhatto at riseup.net
93 # - Added support for:
94 # - Remote destinations
95 # - Long rotation format similar to maildir handler
96 # - Batch files through --read-batch and --write-batch
97 # - Custom file list using --files-from
98 # - SSH persistent connection using ControlMaster
99 # - The rsync:// protocol
100 # - Metadata folder for each backup folder
101 # - General refactoring
105 # function definitions
107 function eval_config {
121 getconf log /var/log/backup/rsync.log
131 getconf keepmonthly 1
134 getconf enable_mv_timestamp_bug no
136 getconf multiconnection no
143 getconf rsync_options "-av --delete --recursive"
145 if [ "$from" == "remote" ]; then
146 getconf testconnect no
151 if [ "$protocol" == "ssh" ]; then
152 # sshd default listen port
155 # rsyncd default listen port
160 getconf bandwidthlimit
161 getconf remote_rsync rsync
162 getconf id_file /root/.ssh/id_dsa
167 if [ "$batch" == "yes" ]; then
169 if [ ! -z "$batchbase" ]; then
178 getconf exclude_vserver
188 if [ "$dest" == "remote" ]; then
189 getconf testconnect no
194 if [ "$protocol" == "ssh" ]; then
195 # sshd default listen port
198 # rsyncd default listen port
203 getconf bandwidthlimit
204 getconf remote_rsync rsync
205 getconf id_file /root/.ssh/id_dsa
210 if [ "$batch" != "yes" ]; then
212 if [ "$batch" == "yes" ]; then
214 if [ ! -z "$batchbase" ]; then
226 getconf initscripts /etc/init.d
231 if [ "$dest" != "local" ] && [ "$from" == "remote" ]; then
232 fatal "When source is remote, destination should be local."
236 if [ "$from" != "local" ] && [ "$from" != "remote" ]; then
237 fatal "Invalid source $from"
241 backupdir="$mountpoint/$backupdir"
243 if [ "$dest" == "local" ] && [ ! -d "$backupdir" ]; then
244 error "Backupdir $backupdir does not exist"
248 if [ ! -z "$log" ]; then
249 mkdir -p `dirname $log`
252 if [ "$format" == "short" ]; then
253 if [ -z "$days" ]; then
256 keep="`echo $days - 1 | bc -l`"
260 if [ ! -z "$nicelevel" ]; then
261 nice="nice -n $nicelevel"
266 ssh_cmd="ssh -T -o PasswordAuthentication=no $host -p $port -l $user -i $id_file"
268 if [ "$from" == "remote" ] || [ "$dest" == "remote" ]; then
269 if [ "$testconnect" == "yes" ] && [ "$protocol" == "ssh" ]; then
270 test_connect $host $port $user $id_file
274 if [ "$multiconnection" == "yes" ]; then
275 ssh_cmd="$ssh_cmd -S $tmp/%r@%h:%p"
278 if [ $enable_mv_timestamp_bug == "yes" ]; then
282 for path in $exclude; do
283 excludes="$excludes --exclude=$path"
288 function rotate_short {
293 local metadata="`dirname $folder`/metadata"
295 if [[ "$keep" < 4 ]]; then
296 error "Rotate: minimum of 4 rotations"
300 if [ -d $folder.$keep ]; then
301 $nice $mv /$folder.$keep /$folder.tmp
304 for ((n=`echo "$keep - 1" | bc`; n >= 0; n--)); do
305 if [ -d $folder.$n ]; then
306 dest=`echo "$n + 1" | bc`
307 $nice $mv /$folder.$n /$folder.$dest
308 $touch /$folder.$dest
309 mkdir -p $metadata/`basename $folder`.$dest
310 date +%c%n%s > $metadata/`basename $folder`.$dest/rotated
314 if [ -d $folder.tmp ]; then
315 $nice $mv /$folder.tmp /$folder.0
318 if [ -d $folder.1 ]; then
319 $nice $cp -alf /$folder.1/. /$folder.0
324 function rotate_short_remote {
327 local metadata="`dirname $folder`/metadata"
330 if [[ "$2" < 4 ]]; then
331 error "Rotate: minimum of 4 rotations"
337 ##### BEGIN REMOTE SCRIPT #####
339 if [ -d $folder.$keep ]; then
340 $nice mv /$folder.$keep /$folder.tmp
343 for ((n=$(($keep - 1)); n >= 0; n--)); do
344 if [ -d $folder.\$n ]; then
346 $nice mv /$folder.\$n /$folder.\$dest
347 touch /$folder.\$dest
348 mkdir -p $metadata/`basename $folder`.\$dest
349 date +%c%n%s > $metadata/`basename $folder`.\$dest/rotated
353 if [ -d $folder.tmp ]; then
354 $nice mv /$folder.tmp /$folder.0
357 if [ -d $folder.1 ]; then
358 $nice $cp -alf /$folder.1/. /$folder.0
360 ##### END REMOTE SCRIPT #######
362 ) | (while read a; do passthru $a; done)
366 function rotate_long {
370 seconds_weekly=604800
371 seconds_monthly=2628000
373 keepweekly=$keepweekly
374 keepmonthly=$keepmonthly
379 if [ ! -d "$backuproot" ]; then
380 echo "Debug: skipping rotate of $backuproot as it doesn't exist."
384 for rottype in daily weekly monthly; do
385 seconds=$((seconds_${rottype}))
387 dir="$backuproot/$rottype"
388 metadata="$backuproot/metadata/$rottype.1"
390 if [ ! -d $dir.1 ]; then
391 echo "Debug: $dir.1 does not exist, skipping."
393 elif [ ! -f $metadata/created ] && [ ! -f $metadata/rotated ]; then
394 echo "Warning: metadata does not exist for $dir.1. This backup may be only partially completed. Skipping rotation."
398 # Rotate the current list of backups, if we can.
399 oldest=`find $backuproot -maxdepth 1 -type d -name $rottype'.*' | @SED@ 's/^.*\.//' | sort -n | tail -1`
400 [ "$oldest" == "" ] && oldest=0
401 for (( i=$oldest; i > 0; i-- )); do
402 if [ -d $dir.$i ]; then
403 if [ -f $metadata/created ]; then
404 created=`tail -1 $metadata/created`
405 elif [ -f $metadata/rotated ]; then
406 created=`tail -1 $metadata/rotated`
410 cutoff_time=$(( now - (seconds*(i-1)) ))
411 if [ ! $created -gt $cutoff_time ]; then
413 if [ ! -d $dir.$next ]; then
414 echo "Debug: $rottype.$i --> $rottype.$next"
415 $nice mv $dir.$i $dir.$next
416 mkdir -p $backuproot/metadata/$rottype.$next
417 date +%c%n%s > $backuproot/metadata/$rottype.$next/rotated
419 echo "Debug: skipping rotation of $dir.$i because $dir.$next already exists."
422 echo "Debug: skipping rotation of $dir.$i because it was created" $(( (now-created)/86400)) "days ago ("$(( (now-cutoff_time)/86400))" needed)."
429 if [ $keepweekly -gt 0 -a -d $backuproot/daily.$max -a ! -d $backuproot/weekly.1 ]; then
430 echo "Debug: daily.$max --> weekly.1"
431 $nice mv $backuproot/daily.$max $backuproot/weekly.1
432 mkdir -p $backuproot/metadata/weekly.1
433 date +%c%n%s > $backuproot/metadata/weekly.1/rotated
436 max=$((keepweekly+1))
437 if [ $keepmonthly -gt 0 -a -d $backuproot/weekly.$max -a ! -d $backuproot/monthly.1 ]; then
438 echo "Debug: weekly.$max --> monthly.1"
439 $nice mv $backuproot/weekly.$max $backuproot/monthly.1
440 mkdir -p $backuproot/metadata/monthly.1
441 date +%c%n%s > $backuproot/metadata/monthly.1/rotated
444 for rottype in daily weekly monthly; do
445 max=$((keep${rottype}+1))
446 dir="$backuproot/$rottype"
447 oldest=`find $backuproot -maxdepth 1 -type d -name $rottype'.*' | @SED@ 's/^.*\.//' | sort -n | tail -1`
448 [ "$oldest" == "" ] && oldest=0
449 # if we've rotated the last backup off the stack, remove it.
450 for (( i=$oldest; i >= $max; i-- )); do
451 if [ -d $dir.$i ]; then
452 if [ -d $backuproot/rotate.tmp ]; then
453 echo "Debug: removing rotate.tmp"
454 $nice rm -rf $backuproot/rotate.tmp
456 echo "Debug: moving $rottype.$i to rotate.tmp"
457 $nice mv $dir.$i $backuproot/rotate.tmp
464 function rotate_long_remote {
466 local backuproot="$1"
470 ##### BEGIN REMOTE SCRIPT #####
473 seconds_weekly=604800
474 seconds_monthly=2628000
476 keepweekly=$keepweekly
477 keepmonthly=$keepmonthly
480 if [ ! -d "$backuproot" ]; then
481 echo "Debug: skipping rotate of $backuproot as it doesn't exist."
485 for rottype in daily weekly monthly; do
486 seconds=\$((seconds_\${rottype}))
488 dir="$backuproot/\$rottype"
489 metadata="$backuproot/metadata/\$rottype.1"
491 if [ ! -d \$dir.1 ]; then
492 echo "Debug: \$dir.1 does not exist, skipping."
494 elif [ ! -f \$metadata/created ] && [ ! -f \$metadata/rotated ]; then
495 echo "Warning: metadata does not exist for \$dir.1. This backup may be only partially completed. Skipping rotation."
499 # Rotate the current list of backups, if we can.
500 oldest=\`find $backuproot -maxdepth 1 -type d -name \$rottype'.*' | @SED@ 's/^.*\.//' | sort -n | tail -1\`
501 [ "\$oldest" == "" ] && oldest=0
502 for (( i=\$oldest; i > 0; i-- )); do
503 if [ -d \$dir.\$i ]; then
504 if [ -f \$metadata/created ]; then
505 created=\`tail -1 \$metadata/created\`
506 elif [ -f \$metadata/rotated ]; then
507 created=\`tail -1 \$metadata/rotated\`
511 cutoff_time=\$(( now - (seconds*(i-1)) ))
512 if [ ! \$created -gt \$cutoff_time ]; then
514 if [ ! -d \$dir.\$next ]; then
515 echo "Debug: \$rottype.\$i --> \$rottype.\$next"
516 $nice mv \$dir.\$i \$dir.\$next
517 mkdir -p $backuproot/metadata/\$rottype.\$next
518 date +%c%n%s > $backuproot/metadata/\$rottype.\$next/rotated
520 echo "Debug: skipping rotation of \$dir.\$i because \$dir.\$next already exists."
523 echo "Debug: skipping rotation of \$dir.\$i because it was created" \$(( (now-created)/86400)) "days ago ("\$(( (now-cutoff_time)/86400))" needed)."
529 max=\$((keepdaily+1))
530 if [ \$keepweekly -gt 0 -a -d $backuproot/daily.\$max -a ! -d \$backuproot/weekly.1 ]; then
531 echo "Debug: daily.\$max --> weekly.1"
532 $nice mv $backuproot/daily.\$max $backuproot/weekly.1
533 mkdir -p $backuproot/metadata/weekly.1
534 date +%c%n%s > $backuproot/metadata/weekly.1/rotated
537 max=\$((keepweekly+1))
538 if [ \$keepmonthly -gt 0 -a -d $backuproot/weekly.\$max -a ! -d $backuproot/monthly.1 ]; then
539 echo "Debug: weekly.\$max --> monthly.1"
540 $nice mv $backuproot/weekly.\$max $backuproot/monthly.1
541 mkdir -p $backuproot/metadata/monthly.1
542 date +%c%n%s > $backuproot/metadata/monthly.1/rotated
545 for rottype in daily weekly monthly; do
546 max=\$((keep\${rottype}+1))
547 dir="$backuproot/\$rottype"
548 oldest=\`find $backuproot -maxdepth 1 -type d -name \$rottype'.*' | @SED@ 's/^.*\.//' | sort -n | tail -1\`
549 [ "\$oldest" == "" ] && oldest=0
550 # if we've rotated the last backup off the stack, remove it.
551 for (( i=\$oldest; i >= \$max; i-- )); do
552 if [ -d \$dir.\$i ]; then
553 if [ -d $backuproot/rotate.tmp ]; then
554 echo "Debug: removing rotate.tmp"
555 $nice rm -rf $backuproot/rotate.tmp
557 echo "Debug: moving \$rottype.\$i to rotate.tmp"
558 $nice mv \$dir.\$i $backuproot/rotate.tmp
562 ##### END REMOTE SCRIPT #######
564 ) | (while read a; do passthru $a; done)
568 function setup_long_dirs {
572 local dir="$destdir/$backuptype"
573 local tmpdir="$destdir/rotate.tmp"
574 local metadata="$destdir/metadata/$backuptype.1"
576 if [ ! -d $destdir ]; then
577 echo "Creating destination directory $destdir..."
581 if [ -d $dir.1 ]; then
582 if [ -f $metadata/created ]; then
583 echo "Warning: $dir.1 already exists. Overwriting contents."
585 echo "Warning: we seem to be resuming a partially written $dir.1"
588 if [ -d $tmpdir ]; then
591 echo "Fatal: could mv $destdir/rotate.tmp $dir.1 on host $host"
595 mkdir --parents $dir.1
597 echo "Fatal: could not create directory $dir.1 on host $host"
601 if [ -d $dir.2 ]; then
602 echo "Debug: update links $backuptype.2 --> $backuptype.1"
603 cp -alf $dir.2/. $dir.1
604 #if [ $? == 1 ]; then
605 # echo "Fatal: could not create hard links to $dir.1 on host $host"
610 [ -f $metadata/created ] && rm $metadata/created
611 [ -f $metadata/rotated ] && rm $metadata/rotated
615 function setup_long_dirs_remote {
619 local dir="$destdir/$backuptype"
620 local tmpdir="$destdir/rotate.tmp"
621 local metadata="$destdir/metadata/$backuptype.1"
625 ##### BEGIN REMOTE SCRIPT #####
626 if [ ! -d $destdir ]; then
627 echo "Creating destination directory $destdir on $host..."
631 if [ -d $dir.1 ]; then
632 if [ -f $metadata/created ]; then
633 echo "Warning: $dir.1 already exists. Overwriting contents."
635 echo "Warning: we seem to be resuming a partially written $dir.1"
638 if [ -d $tmpdir ]; then
640 if [ \$? == 1 ]; then
641 echo "Fatal: could mv $destdir/rotate.tmp $dir.1 on host $host"
645 mkdir --parents $dir.1
646 if [ \$? == 1 ]; then
647 echo "Fatal: could not create directory $dir.1 on host $host"
651 if [ -d $dir.2 ]; then
652 echo "Debug: update links $backuptype.2 --> $backuptype.1"
653 cp -alf $dir.2/. $dir.1
654 #if [ \$? == 1 ]; then
655 # echo "Fatal: could not create hard links to $dir.1 on host $host"
660 [ -f $metadata/created ] && rm $metadata/created
661 [ -f $metadata/rotated ] && rm $metadata/rotated
662 ##### END REMOTE SCRIPT #######
664 ) | (while read a; do passthru $a; done)
668 function move_files {
670 ref=$tmp/makesnapshot-mymv-$$;
678 function prepare_storage {
680 section="`basename $SECTION`"
682 if [ "$format" == "short" ]; then
685 info "Rotating $backupdir/$SECTION..."
686 echo "Rotating $backupdir/$SECTION..." >> $log
688 if [ "$dest" == "remote" ]; then
689 rotate_short_remote $backupdir/$SECTION/$section $keep
691 rotate_short $backupdir/$SECTION/$section $keep
692 if [ ! -d "$backupdir/$SECTION/$section.0" ]; then
693 mkdir -p $backupdir/$SECTION/$section.0
697 elif [ "$format" == "long" ]; then
699 if [ $keepdaily -gt 0 ]; then
701 elif [ $keepweekly -gt 0 ]; then
703 elif [ $keepmonthly -gt 0 ]; then
706 fatal "keeping no backups";
711 info "Rotating $backupdir/$SECTION/..."
712 echo "Rotating $backupdir/$SECTION/..." >> $log
714 if [ "$dest" == "remote" ]; then
715 rotate_long_remote $backupdir/$SECTION
716 setup_long_dirs_remote $backupdir/$SECTION $btype
718 rotate_long $backupdir/$SECTION
719 setup_long_dirs $backupdir/$SECTION $btype
722 elif [ "$format" == "mirror" ]; then
725 fatal "Invalid backup format $format"
733 if [ "$from" == "local" ]; then
735 elif [ "$from" == "remote" ]; then
736 if [ "$protocol" == "rsync" ]; then
737 orig="rsync://$user@$host:$port/$SECTION/"
739 orig="$user@$host:/$SECTION/"
747 if [ "$dest" == "local" ]; then
748 dest_path="$backupdir/$SECTION/$suffix/"
750 if [ "$protocol" == "rsync" ]; then
751 dest_path="rsync://$user@$host:$port/$backupdir/$SECTION/$suffix/"
753 dest_path="$user@$host:$backupdir/$SECTION/$suffix/"
759 function set_batch_mode {
761 local batch_file="$batchbase/$SECTION/$suffix"
763 if [ "$batch" == "read" ]; then
764 if [ -e "$batch_file" ]; then
767 batch_option="--read-batch=$batch_file"
769 fatal "Batch file not found: $batch_file"
772 elif [ "$batch" == "write" ]; then
773 mkdir -p `dirname $batch_file`
774 batch_option="--write-batch=$batch_file"
779 function update_metadata {
784 if [ "$dest" == "local" ]; then
785 metadata="`dirname $dest_path`/metadata/`basename $dest_path`"
787 date +%c%n%s > $metadata/created
788 $touch $backupdir/$SECTION/$suffix
790 folder="`echo $dest_path | cut -d : -f 2`"
791 metadata="`dirname $folder`/metadata/`basename $folder`"
795 ##### BEGIN REMOTE SCRIPT #####
797 date +%c%n%s > $metadata/created
798 ##### END REMOTE SCRIPT #######
800 ) | (while read a; do passthru $a; done)
806 function test_connect {
813 if [ -z "$host" ] || [ -z "$user" ]; then
814 fatal "Remote host or user not set"
818 debug "$ssh_cmd 'echo -n 1'"
819 result=`$ssh_cmd 'echo -n 1'`
821 if [ "$result" != "1" ]; then
822 fatal "Can't connect to $host as $user."
825 debug "Connected to $host successfully"
830 function set_lockfile {
832 if [ ! -z "$lockfile" ]; then
833 $touch $lockfile || warning "Could not create lockfile $lockfile"
838 function unset_lockfile {
840 if [ ! -z "$lockfile" ]; then
841 $rm $lockfile || warning "Could not remove lockfile $lockfile"
846 function set_filelist {
850 if [ "$filelist" == "yes" ]; then
851 if [ ! -z "$filelistbase" ]; then
852 if [ -e "$filelistbase/$SECTION/$suffix" ]; then
853 filelist_flag="--files-from=$filelistbase/$SECTION/$suffix"
855 warning "File list $filelistbase/$SECTION/$suffix not found."
858 warning "No filelistbase set."
864 function set_rsync_options {
866 if [ ! -z "$numericids" ]; then
867 rsync_options="$rsync_options --numeric-ids"
870 if [ "$from" == "local" ] || [ "$dest" == "local" ]; then
871 # rsync options for local sources or destinations
872 rsync_options="$rsync_options"
875 if [ "$from" == "remote" ] || [ "$dest" == "remote" ]; then
877 # rsync options for remote sources or destinations
879 if [ "$compress" == "1" ]; then
880 rsync_options="$rsync_options --compress"
883 if [ ! -z "$bandwidthlimit" ]; then
884 rsync_options="$rsync_options --bwlimit=$bandwidthlimit"
887 if [ "$fakesuper" == "yes" ]; then
888 remote_rsync="$remote_rsync --fake-super"
891 rsync_options=($rsync_options --rsync-path="$remote_rsync")
893 if [ "$protocol" == "ssh" ]; then
894 if [ ! -e "$id_file" ]; then
895 fatal "SSH Identity file $id_file not found"
898 debug RSYNC_RSH=\"$ssh_cmd\"
899 echo RSYNC_RSH=\"$ssh_cmd\" >> $log
910 function stop_services {
912 if [ ! -z "$service" ]; then
913 for daemon in $service; do
914 info "Stopping service $daemon..."
915 $initscripts/$daemon stop
921 function start_services {
925 if [ ! -z "$service" ]; then
926 for daemon in $service; do
927 info "Starting service $daemon..."
928 $initscripts/$daemon start
936 # mount backup destination folder as read-write
938 if [ "$dest" == "local" ]; then
939 if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then
940 if [ -d "$mountpoint" ]; then
941 mount -o remount,rw $mountpoint
943 error "Could not mount $mountpoint"
954 # remount backup destination as read-only
956 if [ "$dest" == "local" ]; then
957 if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then
958 mount -o remount,ro $mountpoint
966 # check partition for errors
968 if [ "$dest" == "local" ]; then
969 if [ "$fscheck" == "1" ] || [ "$fscheck" == "yes" ]; then
972 warning "Could not umount $mountpoint to run fsck"
974 $nice $fsck -v -y $partition >> $log
982 function include_vservers {
984 # add vservers to included folders
986 if [ "$vservers_are_available" == "yes" ]; then
988 # sane permission on backup
989 mkdir -p $backupdir/$VROOTDIR
990 chmod 000 $backupdir/$VROOTDIR
992 for candidate in $found_vservers; do
993 candidate="`basename $candidate`"
994 found_excluded_vserver="0"
995 for excluded_vserver in $exclude_vserver; do
996 if [ "$excluded_vserver" == "$candidate" ]; then
997 found_excluded_vserver="1"
1001 if [ "$found_excluded_vserver" == "0" ]; then
1002 include="$include $VROOTDIR/$candidate"
1009 function start_mux {
1011 if [ "$multiconnection" == "yes" ]; then
1012 debug "Starting master ssh connection"
1013 $ssh_cmd -M sleep 1d &
1021 if [ "$multiconnection" == "yes" ]; then
1022 debug "Stopping master ssh connection"
1023 $ssh_cmd pkill sleep
1028 # the backup procedure
1037 echo "Starting backup at `date`" >> $log
1039 for SECTION in $include; do
1047 info "Syncing $SECTION on $dest_path..."
1048 debug $nice $rsync "${rsync_options[@]}" $filelist_flag $excludes $batch_option $orig $dest_path
1049 $nice $rsync "${rsync_options[@]}" $filelist_flag $excludes $batch_option $orig $dest_path >> $log
1051 if [ "$?" != "0" ]; then
1052 warning "Rsync error when trying to transfer $SECTION"
1065 echo "Finnishing backup at `date`" >> $log