chiark / gitweb /
chiark-backup's snaprsync has new sshopts option.
[chiark-utils.git] / backup / snaprsync
index a2bc96d..3b4bfc7 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/bash
 #
 # usage: snaprsync <setting>... <positionals>
-#  <setting> is ---<name>=<value>
+#  <setting> is --<name>=<value>
 #  <positionals> are assigned to unused mandatory values in order
 # mandatory:
 #   rhost device mountpoint localarea 
        rsharedir=/usr/share/chiark-backup 
        retcdir=/etc/chiark-backup
        rvardir=/var/lib/chiark-backup
+       bwlimit=
+       subdir=.
+       rsyncopts=
+       sshopts=
+       summer=summer
+
+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|sshopts|summer);;
                *) badusage "unknown setting $name";;
                esac
                eval "$name=\$value"
@@ -43,36 +54,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"
+
+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 "$rsharedir/snap-drop"
-x ssh $rhost "$retcdir/snap/$snapkind snap $rvardir $device $mountpoint"
-ssh $rhost "
-  set -ex
+x ssh $sshopts $rhost "$sshpfx $rsharedir/snap-drop"
+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</dev/null
+  (set +e; read x <&3; kill 0) &
   cd $rvardir
   umask 077
   exec 3>$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 -aHSxz --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"
+
+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 <(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