## way it will be processed by a shell.
if localp $host; then run "@$host: $tag" sh -c "$cmd"
- else run "@$host: $tag" ssh $host "$cmd"
+ else run "@$host: $tag" ssh $userat$host "$cmd"
fi
}
## current host is local.
if localp $host; then echo $path
- else echo $host:$path
+ else echo $userat$host:$path
fi
}
+defhook () {
+ hook=$1
+ ## Define a hook called HOOK.
+
+ eval hk_$hook=
+}
+
+addhook () {
+ hook=$1 cmd=$2
+ ## Add command CMD to the hook HOOK.
+
+ eval old=\$hk_$hook; new="$old $cmd"
+ eval hk_$hook=\$new
+}
+
+runhook () {
+ hook=$1; shift 1
+ ## Invoke HOOK, passing it the remaining arguments.
+
+ eval cmds=\$hk_$hook
+ for cmd in $cmds; do
+ if ! $cmd "$@"; then return $?; fi
+ done
+}
+
###--------------------------------------------------------------------------
### Database operations.
## Get the volume host to create the snapshot.
set +e
- _hostrun >&2 3>&- $lvhost \
+ _hostrun >&2 3>&- $userat$lvhost \
"lvcreate --snapshot -n$lv.bkp $SNAPSIZE $vg/$lv"
snaprc=$?
set -e
case $tok in
"$tok_THAWED") ;;
*)
- _hostrun >&2 3>&- $lvhost "lvremove -f $vg/$lv.bkp" || :
+ _hostrun >&2 3>&- $userat$lvhost "lvremove -f $vg/$lv.bkp" || :
echo >&2 "$quis: unexpected token $tok (rfreezefs $fsdir on $fshost)"
exit 1
;;
esac
## Mount the snapshot on the volume host.
- _hostrun >&2 $lvhost "
+ _hostrun >&2 $userat$lvhost "
mkdir -p $SNAPDIR/$lv
mount -oro /dev/$vg/$lv.bkp $SNAPDIR/$lv"
}
bkprc=0
remote_fshash () {
- _hostrun $host "
+ _hostrun $userat$host "
umask 077
mkdir -p $fshashdir
cd ${snapmnt#*:}
done
}
+## Backup hooks.
+defhook setup
+defhook precommit
+defhook postcommit
+
backup_precommit_hook () {
host=$1 fs=$2 date=$3
- ## Override this hook in the configuration file for special effects.
+ ## Compatibility: You can override this hook in the configuration file for
+ ## special effects; but it's better to use `addhook precommit'.
:
}
+addhook precommit backup_precommit_hook
backup_commit_hook () {
host=$1 fs=$2 date=$3
- ## Override this hook in the configuration file for special effects.
+ ## Compatibility: You can override this hook in the configuration file for
+ ## special effects; but it's better to use `addhook commit'.
:
}
+addhook commit backup_commit_hook
do_backup () {
date=$1 fs=$2 fsarg=$3
set -e
attempt=0
+ ## Run a hook beforehand.
+ set +e; runhook setup $host $fs $date; rc=$?; set -e
+ case $? in
+ 0) ;;
+ 99) log "BACKUP of $host:$fs SKIPPED by hook"; return 0 ;;
+ *) log "BACKUP of $host:$fs FAILED (hook returns $?)"; return $? ;;
+ esac
+
## Report the start of this attempt.
log "START BACKUP of $host:$fs"
## Commit this backup.
case $dryrun in
nil)
- backup_precommit_hook $host $fs $date
+ runhook precommit $host $fs $date
mv new $date
mv new.fshash $date.fshash
insert_index $host $fs $date $VOLUME
- backup_commit_hook $host $fs $date
+ runhook commit $host $fs $date
mkdir hack
ln -s $date hack/last
mv hack/last .
###--------------------------------------------------------------------------
### Configuration functions.
+defhook start
+defhook end
+
+done_first_host_p=nil
+
host () {
host=$1
- like=
+ like= userat=
+ case $done_first_host_p in
+ nil) runhook start; done_first_host_p=t ;;
+ esac
case "${expire_policy+t},${default_policy+t}" in
t,) default_policy=$expire_policy ;;
esac
rsyncargs () { rsyncargs="$*"; }
like () { like="$*"; }
retry () { retry="$*"; }
+user () { userat="$*@"; }
retain () {
case $clear_policy in t) unset expire_policy; clear_policy=nil ;; esac
### Read the configuration and we're done.
usage () {
- echo "usage: $quis [-v] [-c CONF]"
+ echo "usage: $quis [-nv] [-c CONF]"
}
version () {
exec 8>&1
. "$conf"
+
+runhook end $bkprc
case "$bkprc" in
0) $verbose "All backups successful" ;;
*) $verbose "Backups FAILED" ;;