chiark / gitweb /
c9e77fd2961ceb2ecad8d3ad747d84fcdef27920
[chiark-utils.git] / backup / snaprsync
1 #!/bin/bash
2 #
3 # usage: snaprsync <setting>... <positionals>
4 #  <setting> is ---<name>=<value>
5 #  <positionals> are assigned to unused mandatory values in order
6 # mandatory:
7 #   rhost device mountpoint localarea 
8 # optional:
9         localprevious=
10         snapkind=lvm
11         rsharedir=/usr/share/chiark-backup 
12         retcdir=/etc/chiark-backup
13         rvardir=/var/lib/chiark-backup
14         bwlimit=
15
16 set -e
17
18 badusage () { echo >&2 "snaprsync: bad usage: $1"; exit 12; }
19 x () { echo "+ $@"; "$@"; }
20
21 while true; do
22         case "$1" in
23         --?*=?*)
24                 name=${1#--}; name=${name%%=*}
25                 value=${1#--*=}
26                 case "$name" in
27                 rhost|device|mountpoint|localarea);;
28                 localprevious|rsharedir|retcdir|rvardir|bwlimit);;
29                 *) badusage "unknown setting $name";;
30                 esac
31                 eval "$name=\$value"
32                 ;;
33         --)     shift; break ;;
34         -*)     badusage "unknown option $1" ;;
35         *)      break ;;
36         esac
37         shift
38 done
39
40 for name in rhost device mountpoint localarea; do
41         eval "value=\$$name"
42         if [ "x$value" != x ]; then continue; fi
43         if [ $# = 0 ]; then badusage "no value for setting $name"; fi
44         eval "$name=$1"
45         shift
46 done
47
48 datefmt='%Y-%m-%d %H:%M:%S Z'
49 rsync="rsync ${bwlimit:+--bwlimit} $bwlimit"
50 export RSYNC_RSH='ssh -o compression=no'
51
52 ssh $rhost "date -u '+$rhost $datefmt start'"
53 ssh $rhost id
54 ssh $rhost ls -d $rsharedir
55 ssh $rhost ls -d $rvardir
56
57 test -d $localarea || x mkdir $localarea
58 ournode=`uname -n`
59 rsumsfile=for-$ournode.sums
60
61 td=/dev/enoent
62 rc=12
63 trap 'rm -rf $td; exit $rc' 0
64 td=`mktemp -td`
65
66 mkfifo -m 600 $td/sentinel
67 exec 4<>$td/sentinel
68
69 x ssh $rhost "$rsharedir/snap-drop"
70 x ssh $rhost "$retcdir/snap/$snapkind snap $rvardir $device $mountpoint"
71 ssh $rhost <$td/sentinel 4<&- "
72   set -e
73   date -u '+$rhost $datefmt main'
74   exec 3<&0 0</dev/null
75   (set +e; read x <&3; kill 0) &
76   cd $rvardir
77   umask 077
78   exec 3>$rsumsfile
79   cd snap-mount
80   summer -Ctqf . | sort -t'     ' -k2 >&3
81   test x"${PIPESTATUS[*]}" = 'x0 0'
82   date -u '+$rhost $datefmt sumsdone'
83   cd ..
84 " &
85 rsumpid=$!
86 x $rsync -aHSxz --numeric-ids --delete \
87         ${localprevious:+--link-dest} $localprevious \
88         $rhost:$rvardir/snap-mount/. $localarea/.
89 wait $rsumpid
90 x ssh $rhost "$rsharedir/snap-drop"
91
92 if [ "x${localprevious}" != x ]; then
93         cp "$localprevious,rsums" "$localarea,rsums"
94 fi
95 x $rsync -p \
96         $rhost:$rvardir/$rsumsfile \
97         "$localarea,rsums"