X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=backup%2Fsnaprsync;h=82ea5d416f8ab1dc86349b2c7287a7a3dd886626;hb=bb9589a647d1a092cc5fb9f5232d3c835c27c2f6;hp=a2bc96de8f058a9a8bdc1c0e4d4dd915491f0ff7;hpb=26f2a22823fa7991c485e304e642c8f1ef712ddc;p=chiark-utils.git diff --git a/backup/snaprsync b/backup/snaprsync index a2bc96d..82ea5d4 100755 --- a/backup/snaprsync +++ b/backup/snaprsync @@ -1,7 +1,7 @@ #!/bin/bash # # usage: snaprsync ... -# is ---= +# is --= # are assigned to unused mandatory values in order # mandatory: # rhost device mountpoint localarea @@ -11,18 +11,55 @@ rsharedir=/usr/share/chiark-backup retcdir=/etc/chiark-backup rvardir=/var/lib/chiark-backup + bwlimit= + subdir=. + rsyncopts= + rsynccompress=z + sshopts= + summer=summer + + +# snaprsync +# +# This file is part of chiark backup, a system for backing up GNU/Linux and +# other UN*X-compatible machines, as used on chiark.greenend.org.uk. +# +# chiark backup is: +# Copyright (C) 1997-1998,2000-2001,2007 +# Ian Jackson +# Copyright (C) 1999 Peter Maydell +# +# This is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3, or (at your option) any later version. +# +# This is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, consult the Free Software Foundation's +# website at www.fsf.org, or the GNU Project website at www.gnu.org. + + +set -e badusage () { echo >&2 "snaprsync: bad usage: $1"; exit 12; } -x () { echo "+ $@"; "$@"; } +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|rsharedir|retcdir|rvardir);; + localprevious|snapkind|rsharedir|retcdir|rvardir|bwlimit);; + subdir|rsyncopts|rsynccompress|sshopts|summer);; *) badusage "unknown setting $name";; esac eval "$name=\$value" @@ -43,36 +80,84 @@ for name in rhost device mountpoint localarea; do done datefmt='%Y-%m-%d %H:%M:%S Z' +rsync="rsync ${bwlimit:+--bwlimit} $bwlimit" +export RSYNC_RSH="ssh -o compression=no $sshopts" +sshpfx='PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin; export PATH; ' -ssh $rhost "date -u '+$rhost $datefmt'" -ssh $rhost id -ssh $rhost ls -d $rsharedir -ssh $rhost ls -d $rvardir +ssh $sshopts $rhost "$sshpfx date -u '+$rhost $datefmt start'" +ssh $sshopts $rhost "$sshpfx id" +ssh $sshopts $rhost "$sshpfx ls -d $rsharedir" +ssh $sshopts $rhost "$sshpfx ls -d $rvardir" test -d $localarea || x mkdir $localarea ournode=`uname -n` rsumsfile=for-$ournode.sums +summer="$summer -ACDBtqfx" -x ssh $rhost "$rsharedir/snap-drop" -x ssh $rhost "$retcdir/snap/$snapkind snap $rvardir $device $mountpoint" -ssh $rhost " - set -ex +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 $sshopts $rhost "$sshpfx $rsharedir/snap-drop $rvardir" +x ssh $sshopts $rhost " + $sshpfx + set -e + cd $rvardir + echo '$retcdir/snap/$snapkind drop $rvardir' >snap-drop.new + mv snap-drop.new snap-drop +" +x ssh $sshopts $rhost "$sshpfx $retcdir/snap/$snapkind snap $rvardir $device $mountpoint" +ssh $sshopts $rhost <$td/sentinel 4<&- " + $sshpfx + set -e + date -u '+$rhost $datefmt main' + exec 3<&0 0$rsumsfile cd snap-mount - summer -Cqf . >&3 - date -u +'sums done $datefmt' + $summer . >&3 + date -u '+$rhost $datefmt sumsdone' cd .. " & -fixme kill this thing if we die -rsumpid=$! -RSYNC_RSH='ssh -o compression=no' \ - x rsync -aHSxz --numeric-ids --delete \ +xspawned rsum +x $rsync -aHSx$rsynccompress --numeric-ids --delete $rsyncopts \ ${localprevious:+--link-dest} $localprevious \ - $rhost:$rvardir/snap-mount/. $localarea/. -wait $rsumpid -x ssh $rhost "$rsharedir/snap-drop" -RSYNC_RSH=ssh rsync -p - fixme use localprevious,rsums as seed if available - $rhost:$rvardir/$rsumsfile $localarea,rsums + $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 $sshopts $rhost "$sshpfx $rsharedir/snap-drop $rvardir" + +if [ "x${localprevious}" != x ] && test -f "$localprevious,rsums"; then + cp "$localprevious,rsums" "$localarea,rsums" +fi +x $rsync -pI \ + $rhost:$rvardir/$rsumsfile \ + "$localarea,rsums" + +xwait $lsum +date -u "+ $datefmt checking" + +set +e +diff -u <(sed -e 's/^mountpoint/dir /' "$localarea,rsums") \ + "$localarea,lsums" >"$localarea,sumsdiff" +diffrc=$? +set -e +test $diffrc = 0 || test $diffrc = 1 + +date -u "+ $datefmt checked $diffrc" +rc=$diffrc