X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=handlers%2Fmaildir;h=b678b838797bb4655c613f58850a8e0d87f3f4ab;hb=cfc47e5571e61f4323b9f64f9cbb64dfbc4bf1b4;hp=8de2b979b7a959f2b3d36e948f00920e29770dcb;hpb=0e6fd3befaffa3fd1e2dba2de6ada2b807a0579b;p=matthijs%2Fupstream%2Fbackupninja.git diff --git a/handlers/maildir b/handlers/maildir index 8de2b97..b678b83 100644 --- a/handlers/maildir +++ b/handlers/maildir @@ -1,3 +1,5 @@ +# -*- mode: sh; sh-basic-offset: 8; indent-tabs-mode: nil; -*- + ############################################################### # # This handler slowly creates a backup of each user's maildir @@ -12,7 +14,17 @@ # weekly.2 # monthly.1 # if keepdaily is 3, keepweekly is 2, and keepmonthly is 1. -# +# +# The basic algorithm is to rsync each maildir individually, +# and to use hard links for retaining historical data. +# +# We rsync each maildir individually because it becomes very +# unweldy to start a single rsync of many hundreds of thousands +# of files. +# +# For the backup rotation to work, destuser must be able to run +# arbitrary bash commands on the desthost. +# ############################################################## getconf rotate yes @@ -85,7 +97,9 @@ function do_user() { --exclude '.Trash/*' --exclude '.Mistakes/*' --exclude '.Spam/*' \ $dir $destuser@$desthost:$destdir/$letter \ 2>&1` - if [ $? != 0 ]; then + ret=$? + # ignore 0 (success) and 24 (file vanished before it could be copied) + if [ $ret != 0 -a $ret != 24 ]; then warning "rsync $user failed" warning " returned: $ret" let "failedcount = failedcount + 1" @@ -99,8 +113,8 @@ $dir $destuser@$desthost:$destdir/$letter \ # and add new ones which have just been created. function do_remove() { - local tmp1=/tmp/maildirtmpfile$$ - local tmp2=/tmp/maildirtmpfile$$ + local tmp1=`maketemp maildir-tmp-file` + local tmp2=`maketemp maildir-tmp-file` for i in a b c d e f g h i j k l m n o p q r s t u v w x y z; do ls -1 "$srcdir/$i" | sort > $tmp1 @@ -147,23 +161,23 @@ function do_rotate() { [ "\$oldest" == "" ] && oldest=0 for (( i=\$oldest; i > 0; i-- )); do if [ -d \$dir.\$i ]; then - if [ -f \$dir.\$i/rotated ]; then - rotated=\`tail -1 \$dir.\$i/rotated\` + if [ -f \$dir.\$i/created ]; then + created=\`tail -1 \$dir.\$i/created\` else - rotated=0 + created=0 fi - cutoff_time=\$(( now - (seconds*i) )) - if [ \$rotated -lt \$cutoff_time ]; then + cutoff_time=\$(( now - (seconds*(i-1)) )) + if [ ! \$created -gt \$cutoff_time ]; then next=\$(( i + 1 )) if [ ! -d \$dir.\$next ]; then - echo "mv \$dir.\$i \$dir.\$next" + echo "Debug: mv \$dir.\$i \$dir.\$next" mv \$dir.\$i \$dir.\$next date +%c%n%s > \$dir.\$next/rotated else echo "Info: skipping rotation of \$dir.\$i because \$dir.\$next already exists." fi else - echo "Info: skipping rotation of \$dir.\$i because it was rotated" \$(( (now-rotated)/86400)) "days ago ("\$(( (now-cutoff_time)/86400))" needed)." + echo "Info: skipping rotation of \$dir.\$i because it was created" \$(( (now-created)/86400)) "days ago ("\$(( (now-cutoff_time)/86400))" needed)." fi fi done @@ -194,10 +208,9 @@ function do_rotate() { if [ -d $backuproot/rotate.tmp ]; then echo "Info: removing $backuproot/rotate.tmp" rm -rf $backuproot/rotate.tmp - else - echo "Info: moving \$dir.\$i to $backuproot/rotate.tmp" - mv \$dir.\$i $backuproot/rotate.tmp fi + echo "Info: moving \$dir.\$i to $backuproot/rotate.tmp" + mv \$dir.\$i $backuproot/rotate.tmp fi done done @@ -236,14 +249,17 @@ function setup_remote_dirs() { echo "Fatal: could not create directory $dir.1 on host $desthost" exit 1 fi + for i in a b c d e f g h i j k l m n o p q r s t u v w y x z; do + mkdir $dir.1/\$i + done fi if [ -d $destdir/$backuptype.2 ]; then echo "Info: updating hard links to $dir.1. This may take a while." - cp -al $destdir/$backuptype.2/. $dir.1 - if [ \$? == 1 ]; then - echo "Fatal: could not create hard links to $dir.1 on host $desthost" - exit 1 - fi + cp -alf $destdir/$backuptype.2/. $dir.1 + #if [ \$? == 1 ]; then + # echo "Fatal: could not create hard links to $dir.1 on host $desthost" + # exit 1 + #fi fi fi [ -f $dir.1/created ] && rm $dir.1/created