chiark / gitweb /
rsync-backup.in, rsync-backup.8: Trim caches on fshash mismatch.
authorMark Wooding <mwooding@good.com>
Fri, 10 Apr 2015 14:19:25 +0000 (15:19 +0100)
committerMark Wooding <mwooding@good.com>
Mon, 18 May 2015 15:53:06 +0000 (16:53 +0100)
  * Capture the diff output in a file so we can pass it onto fshash for
    cache pruning if it's not empty.

  * If we're retrying because of an fshash mismatch then clear cache
    entries.  This is delayed from the cache-mismatch processing because
    we need the snapshot mounted so that fshash can do name->inode
    mapping.

  * By default, retry once.  Otherwise we don't get any benefit from
    evicting maybe-stale entries.

rsync-backup.8
rsync-backup.in

index 5ff20bcdbc2688035e81533e5e75af89712b2c39..fcbf197a0c11ccb384701359eb27a2fac897b8c8 100644 (file)
@@ -262,7 +262,10 @@ results in an
 .B fshash
 mismatch will be retried up to
 .I count
-times before being declared a failure.
+times before being declared a failure.  The default is to retry once,
+clearing mismatching files from the
+.BR fshash (1)
+caches before the second attempt.
 .TP
 .BI "runhook " hook " " args\fR...
 Invoke the named
index e9bb3bebfe5230253d73f27d153cdf18daf1df8e..2c1e3b6ca6e87ddae00418f390ffd746cba0e876 100644 (file)
@@ -120,6 +120,15 @@ run () {
   return $rc
 }
 
+run_diff () {
+  out=$1 old=$2 new=$3
+  ## Write a unified diff from OLD to NEW, to OUT.
+
+  set +e; diff -u "$old" "$new" >"$out"; rc=$?; set -e
+  case $rc in 1) cat "$out" ;; esac
+  return $rc
+}
+
 localp () {
   h=$1
   ## Answer whether H is a local host.
@@ -603,6 +612,7 @@ do_backup () {
 
   set -e
   attempt=0
+  fshash_diff=nil
 
   ## Run a hook beforehand.
   set +e; runhook setup $host $fs $date; rc=$?; set -e
@@ -630,6 +640,20 @@ do_backup () {
     esac
     $verbose " create snapshot"
 
+    ## If we had a fshash-mismatch, then clear out the potentially stale
+    ## entries, both locally and remotely.
+    case $fshash_diff in
+      nil) ;;
+      *)
+       $verbose "      prune cache"
+       run -stdin "local prune fshash" \
+         fshash -u -c$STOREDIR/fshash.cache -H$HASH new/ <$fshash_diff
+       run -stdin "@$host: prune fshash" \
+         _hostrun $userat$host <$fshash_diff \
+         "fshash -u -c$fshashdir/$fs.bkp -H$HASH ${snapmnt#*:}"
+       ;;
+    esac
+
     ## Build the list of hardlink sources.
     linkdests=""
     for i in $host $like; do
@@ -686,7 +710,9 @@ do_backup () {
 
     ## Compare the two maps.
     set +e
-    run "compare fshash maps for $host:$fs" diff -u new.fshash $localmap
+    fshash_diff=$STOREDIR/tmp/fshash-diff.$host.$fs.$date
+    run "compare fshash maps for $host:$fs" \
+      run_diff $fshash_diff new.fshash $localmap
     rc_diff=$?
     set -e
     case $rc_diff in
@@ -706,6 +732,7 @@ do_backup () {
 
   ## Glorious success.
   maybe rm -f $localmap
+  case $fshash_diff in nil) ;; *) maybe rm -f $fshash_diff ;; esac
   $verbose "   fshash match"
 
   ## Commit this backup.
@@ -860,7 +887,7 @@ host () {
   $verbose "host $host"
 }
 
-snaptype () { snap=$1; shift; snapargs="$*"; retry=0; }
+snaptype () { snap=$1; shift; snapargs="$*"; retry=1; }
 rsyncargs () { rsyncargs="$*"; }
 like () { like="$*"; }
 retry () { retry="$*"; }