#!/usr/bin/env bash # R-1105: lock behaviour, 0.14.0 vs 0.18.1. A lock left by a KILLED process on ANOTHER hostname (the C2 shape: # the recreated container has a new hostname, so restic cannot prove the lock dead). Scratch repos only. set -u S= OUT=${1:?out}; W=$S/lockwork; rm -rf $W; mkdir -p $W $OUT export RESTIC_PASSWORD_FILE=$W/pw RESTIC_CACHE_DIR=$W/cache TZ=UTC head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n' > $RESTIC_PASSWORD_FILE mkdir -p $W/src; echo a > $W/src/a.txt for V in 0.14.0 0.18.1; do R=$S/bin/restic-$V; REPO=$W/repo-$V; O=$OUT/$V; mkdir -p $O $R -r $REPO init >/dev/null 2>&1; $R -r $REPO backup --tag t $W/src >/dev/null 2>&1; $R -r $REPO backup --tag t $W/src >/dev/null 2>&1 for KIND in shared exclusive; do if [ $KIND = shared ]; then # a backup reading stdin from a pipe that never ends holds a NON-exclusive lock ( sleep 600 | unshare --uts --map-root-user sh -c "hostname other-box; exec $R -r $REPO backup --stdin --stdin-filename x" ) >/dev/null 2>&1 & else # an exclusive holder: prune, killed the moment its lock file appears (the C2 crash shape) ( unshare --uts --map-root-user sh -c "hostname other-box; exec $R -r $REPO prune" ) >/dev/null 2>&1 & fi for i in $(seq 1 400); do [ -n "$(ls $REPO/locks 2>/dev/null)" ] && break; sleep 0.005; done pkill -9 -f "restic-$V -r $REPO" ; pkill -f 'sleep 600'; sleep 0.5 echo "locks after kill: $(ls $REPO/locks | wc -l)" > $O/$KIND.txt if [ "$(ls $REPO/locks | wc -l)" = 0 ]; then echo "NO LOCK LEFT — holder finished first" >> $O/$KIND.txt; continue; fi { echo "--- backup"; $R -r $REPO backup --tag t $W/src 2>&1; echo "rc=$?" echo "--- forget --prune"; $R -r $REPO forget --keep-last 1 --prune 2>&1; echo "rc=$?" echo "--- restore --no-lock"; $R -r $REPO restore latest --target $W/r1-$V-$KIND --no-lock 2>&1 | tail -2; echo "rc=${PIPESTATUS[0]}" echo "--- unlock (stale only)"; $R -r $REPO unlock 2>&1; echo "rc=$?"; echo "locks: $(ls $REPO/locks | wc -l)" echo "--- unlock --remove-all"; $R -r $REPO unlock --remove-all 2>&1; echo "rc=$?"; echo "locks: $(ls $REPO/locks | wc -l)" echo "--- forget --prune after"; $R -r $REPO forget --keep-last 1 --prune 2>&1 | tail -1; echo "rc=${PIPESTATUS[0]}" } >> $O/$KIND.txt $R -r $REPO backup --tag t $W/src >/dev/null 2>&1 done done sed -i "s#$W##g" $OUT/*/*.txt echo done