1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
#!/bin/bash
#
# usage: snaprsync <setting>... <positionals>
# <setting> is --<name>=<value>
# <positionals> are assigned to unused mandatory values in order
# mandatory:
# rhost device mountpoint localarea
# optional:
localprevious=
snapkind=lvm
rsharedir=/usr/share/chiark-backup
retcdir=/etc/chiark-backup
rvardir=/var/lib/chiark-backup
bwlimit=
subdir=.
rsyncopts=
summer=summer
set -e
badusage () { echo >&2 "snaprsync: bad usage: $1"; exit 12; }
nb_echo () { (echo "$@"); } # See Debian #382798
x () { nb_echo "+ $@"; "$@"; }
xspawned () { eval "${1}pid=$!; nb_echo \"+[$!] ($1) &\";"; }
xwait () { eval "nb_echo \"+[\$${1}pid] ($1)...\"; wait \$${1}pid;"; }
while true; do
case "$1" in
--?*=*)
name=${1#--}; name=${name%%=*}
value=${1#--*=}
case "$name" in
rhost|device|mountpoint|localarea);;
localprevious|snapkind|rsharedir|retcdir|rvardir|bwlimit);;
subdir|rsyncopts|summer);;
*) badusage "unknown setting $name";;
esac
eval "$name=\$value"
;;
--) shift; break ;;
-*) badusage "unknown option $1" ;;
*) break ;;
esac
shift
done
for name in rhost device mountpoint localarea; do
eval "value=\$$name"
if [ "x$value" != x ]; then continue; fi
if [ $# = 0 ]; then badusage "no value for setting $name"; fi
eval "$name=$1"
shift
done
datefmt='%Y-%m-%d %H:%M:%S Z'
rsync="rsync ${bwlimit:+--bwlimit} $bwlimit"
export RSYNC_RSH='ssh -o compression=no'
sshpfx='PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin; export PATH; '
ssh $rhost "$sshpfx date -u '+$rhost $datefmt start'"
ssh $rhost "$sshpfx id"
ssh $rhost "$sshpfx ls -d $rsharedir"
ssh $rhost "$sshpfx ls -d $rvardir"
test -d $localarea || x mkdir $localarea
ournode=`uname -n`
rsumsfile=for-$ournode.sums
summer="$summer -ACDbtqf"
td=/dev/enoent
rc=12
trap 'rm -rf $td; exit $rc' 0
td=`mktemp -td`
mkfifo -m 600 $td/sentinel
exec 4<>$td/sentinel
x ssh $rhost "$sshpfx $rsharedir/snap-drop"
ssh $rhost "
$sshpfx
set -e
cd $rvardir
echo '$retcdir/snap/$snapkind drop $rvardir' >snap-drop.new
mv snap-drop.new snap-drop
"
x ssh $rhost "$sshpfx $retcdir/snap/$snapkind snap $rvardir $device $mountpoint"
ssh $rhost <$td/sentinel 4<&- "
$sshpfx
set -e
date -u '+$rhost $datefmt main'
exec 3<&0 0</dev/null
(set +e; read x <&3; kill 0) &
cd $rvardir
umask 077
exec 3>$rsumsfile
cd snap-mount
$summer . >&3
date -u '+$rhost $datefmt sumsdone'
cd ..
" &
xspawned rsum
x $rsync -aHSxz --numeric-ids --delete $rsyncopts \
${localprevious:+--link-dest} $localprevious \
$rhost:$rvardir/snap-mount/$subdir $localarea/.
date -u "+ $datefmt rsyncdone"
exec 3>$localarea,lsums
(cd $localarea && \
$summer . >&3) &
xspawned lsum
exec 3>&-
xwait rsum
exec 4<&-
date -u "+ $datefmt sumsdone"
x ssh $rhost "$sshpfx $rsharedir/snap-drop"
if [ "x${localprevious}" != x ] && test -f "$localprevious,rsums"; then
cp "$localprevious,rsums" "$localarea,rsums"
fi
x $rsync -p \
$rhost:$rvardir/$rsumsfile \
"$localarea,rsums"
xwait $lsum
date -u "+ $datefmt checking"
set +e
diff -u "$localarea,rsums" "$localarea,lsums" >"$localarea,sumsdiff"
diffrc=$?
set -e
test $diffrc = 0 || test $diffrc = 1
date -u "+ $datefmt checked $diffrc"
rc=$diffrc
|