* 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.
.B fshash
mismatch will be retried up to
.I count
.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
.TP
.BI "runhook " hook " " args\fR...
Invoke the named
+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.
localp () {
h=$1
## Answer whether H is a local host.
## Run a hook beforehand.
set +e; runhook setup $host $fs $date; rc=$?; set -e
## Run a hook beforehand.
set +e; runhook setup $host $fs $date; rc=$?; set -e
esac
$verbose " create snapshot"
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
## Build the list of hardlink sources.
linkdests=""
for i in $host $like; do
## Compare the two maps.
set +e
## 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
rc_diff=$?
set -e
case $rc_diff in
## Glorious success.
maybe rm -f $localmap
## Glorious success.
maybe rm -f $localmap
+ case $fshash_diff in nil) ;; *) maybe rm -f $fshash_diff ;; esac
$verbose " fshash match"
## Commit this backup.
$verbose " fshash match"
## Commit this backup.
-snaptype () { snap=$1; shift; snapargs="$*"; retry=0; }
+snaptype () { snap=$1; shift; snapargs="$*"; retry=1; }
rsyncargs () { rsyncargs="$*"; }
like () { like="$*"; }
retry () { retry="$*"; }
rsyncargs () { rsyncargs="$*"; }
like () { like="$*"; }
retry () { retry="$*"; }