|
#! /bin/sh |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PROGNAME=`basename $0` |
|
CONFIGPATH="$SYSCONFDIR/backup" |
|
REMOTEBACKUPDIR="$SYSCONFDIR/tar-backup" |
|
CONFIGFILE=${CONFIGPATH}/backup-specs |
|
DIRLIST=${CONFIGPATH}/dirs |
|
FILELIST=${CONFIGPATH}/files |
|
LOGPATH=${CONFIGPATH}/log |
|
|
|
|
|
mt_begin() { |
|
$MT -f "$1" retension |
|
} |
|
|
|
mt_rewind() { |
|
$MT -f "$1" rewind |
|
} |
|
|
|
mt_offline() { |
|
$MT -f "$1" offl |
|
} |
|
|
|
mt_status() { |
|
$MT -f "$1" status |
|
} |
|
|
|
|
|
MT_BEGIN=mt_begin |
|
MT_REWIND=mt_rewind |
|
MT_OFFLINE=mt_offline |
|
MT_STATUS=mt_status |
|
|
|
|
|
PATH="/usr/ucb:${PATH}" |
|
export PATH |
|
|
|
|
|
|
|
|
|
startdate="`date`" |
|
here="`pwd`" |
|
|
|
localhost="`hostname | sed -e 's/\..*//' | tr A-Z a-z`" |
|
|
|
|
|
message() { |
|
if [ "$VERBOSE" != "" ]; then |
|
if [ $VERBOSE -ge $1 ]; then |
|
shift |
|
echo "$@" >&2 |
|
fi |
|
fi |
|
} |
|
|
|
|
|
bailout() { |
|
echo "$PROGNAME: $*" >&2 |
|
exit 1 |
|
} |
|
|
|
|
|
now() { |
|
date +%Y-%m-%d |
|
} |
|
|
|
|
|
test_root() { |
|
if [ ! -w ${ROOT_FS-/} ]; then |
|
bailout "The backup must be run as root or else some files will fail to be dumped." |
|
fi |
|
} |
|
|
|
root_fs() { |
|
echo "${ROOT_FS}$1" | tr -s / |
|
} |
|
|
|
advice() { |
|
echo "Directory $1 is not found." >&2 |
|
cat >&2 <<EOF |
|
The following directories and files are needed for the backup to function: |
|
|
|
1. Directory with configuration files and file lists: |
|
$CONFIGPATH |
|
2. Directory for backup log files |
|
$LOGPATH |
|
3. Main configuration file |
|
$CONFIGFILE |
|
|
|
Please, create these and invoke the script again. |
|
EOF |
|
} |
|
|
|
init_common() { |
|
|
|
if [ ! -d $CONFIGPATH ]; then |
|
advice $CONFIGPATH |
|
exit 1 |
|
fi |
|
if [ ! -d $LOGPATH ]; then |
|
if mkdir $LOGPATH; then |
|
: |
|
else |
|
advice $LOGPATH |
|
exit 1 |
|
fi |
|
fi |
|
|
|
if [ ! -r $CONFIGFILE ]; then |
|
echo "$PROGNAME: cannot read $CONFIGFILE. Stop." >&2 |
|
exit 1 |
|
fi |
|
. $CONFIGFILE |
|
|
|
|
|
|
|
test_root |
|
|
|
if [ x"${ADMINISTRATOR}" = x ]; then |
|
bailout "ADMINISTRATOR not defined" |
|
fi |
|
|
|
[ x"$TAR" = x ] && TAR=tar |
|
[ x"$SLEEP_TIME" = x ] && SLEEP_TIME=60 |
|
|
|
if [ x$VOLNO_FILE = x ]; then |
|
bailout "VOLNO_FILE not specified" |
|
fi |
|
|
|
if [ -r $DIRLIST ]; then |
|
BACKUP_DIRS="$BACKUP_DIRS `cat $DIRLIST`" |
|
fi |
|
if [ -r $FILELIST ]; then |
|
BACKUP_FILES="$BACKUP_FILES `cat $FILELIST`" |
|
fi |
|
|
|
if [ \( x"$BACKUP_DIRS" = x \) -a \( x"$BACKUP_FILES" = x \) ]; then |
|
bailout "Neither BACKUP_DIRS nor BACKUP_FILES specified" |
|
fi |
|
if [ -z "$RSH" ]; then |
|
RSH=rsh |
|
MT_RSH_OPTION= |
|
else |
|
MT_RSH_OPTION="--rsh-command=$RSH" |
|
fi |
|
if [ -z "$TAPE_FILE" ]; then |
|
TAPE_FILE=/dev/tape |
|
fi |
|
|
|
|
|
: ${MT:=mt} |
|
case $TAPE_FILE in |
|
*:*) MT="$MT $MT_RSH_OPTION";; |
|
*) ;; |
|
esac |
|
|
|
POSIXLY_CORRECT=1 |
|
export POSIXLY_CORRECT |
|
} |
|
|
|
init_backup() { |
|
init_common |
|
TAR_PART1="${TAR} -c --format=gnu --multi-volume --one-file-system --sparse --volno-file=${VOLNO_FILE}" |
|
if [ "x$XLIST" != x ]; then |
|
TAR_PART1="${TAR_PART1} \`test -r $REMOTEBACKUPDIR/$XLIST && echo \"--exclude-from $REMOTEBACKUPDIR/$XLIST\"\`" |
|
fi |
|
if [ "$RSH_COMMAND" != "" ]; then |
|
TAR_PART1="${TAR_PART1} --rsh-command=$RSH_COMMAND" |
|
fi |
|
if [ x$BLOCKING != x ]; then |
|
TAR_PART1="${TAR_PART1} --blocking=${BLOCKING}" |
|
fi |
|
|
|
|
|
if [ "x${DUMP_REMIND_SCRIPT}" != "x" ]; then |
|
TAR_PART1="${TAR_PART1} --info-script='${DUMP_REMIND_SCRIPT}'" |
|
fi |
|
|
|
|
|
|
|
|
|
|
|
LOGFILE="${LOGPATH}/log-`now`-level-${DUMP_LEVEL}" |
|
} |
|
|
|
init_restore() { |
|
init_common |
|
|
|
TAR_PART1="${TAR} --extract --multi-volume" |
|
if [ "$RSH_COMMAND" != "" ]; then |
|
TAR_PART1="${TAR_PART1} --rsh-command=$RSH_COMMAND" |
|
fi |
|
if [ x$BLOCKING != x ]; then |
|
TAR_PART1="${TAR_PART1} --blocking=${BLOCKING}" |
|
fi |
|
|
|
|
|
if [ "x${DUMP_REMIND_SCRIPT}" != "x" ]; then |
|
TAR_PART1="${TAR_PART1} --info-script='${DUMP_REMIND_SCRIPT}'" |
|
fi |
|
LOGFILE="${LOGPATH}/restore-`now`" |
|
} |
|
|
|
wait_time() { |
|
if [ "${1}" != "now" ]; then |
|
if [ "${1}x" != "x" ]; then |
|
spec="${1}" |
|
else |
|
spec="${BACKUP_HOUR}" |
|
fi |
|
|
|
pausetime="`date | awk -v spec=\"${spec}\" ' |
|
BEGIN { |
|
split(spec, time, ":") |
|
} |
|
{ |
|
split($4, now, ":") |
|
diff = 3600 * (time[1] - now[1]) + 60 * (time[2] - now[2]); |
|
if (diff < 0) |
|
diff += 3600 * 24 |
|
print diff |
|
}'`" |
|
clear |
|
echo "${SLEEP_MESSAGE}" |
|
sleep "${pausetime}" |
|
fi |
|
} |
|
|
|
level_log_name() { |
|
echo "$REMOTEBACKUPDIR/${1}.level-${2-$DUMP_LEVEL}" |
|
} |
|
|
|
|
|
|
|
make_level_log() { |
|
if [ "z${localhost}" != "z$1" ] ; then |
|
$RSH "$1" mkdir $REMOTEBACKUPDIR > /dev/null 2>&1 |
|
$RSH "$1" rm -f `level_log_name temp` |
|
else |
|
mkdir $REMOTEBACKUPDIR > /dev/null 2>&1 |
|
rm -f `level_log_name temp` |
|
fi |
|
} |
|
|
|
|
|
|
|
flush_level_log() { |
|
message 10 "RENAME: `level_log_name temp` --> `level_log_name $2`" |
|
if [ "z${localhost}" != "z$1" ] ; then |
|
$RSH "$1" mv -f `level_log_name temp` "`level_log_name $2`" |
|
else |
|
mv -f `level_log_name temp` "`level_log_name $2`" |
|
fi |
|
} |
|
|
|
|
|
|
|
get_dump_time() { |
|
ls -r ${LOGPATH}/log-*-level-$1 \ |
|
| head -n 1 \ |
|
| sed "s,.*log-\(.*\)-level-$1,\1," |
|
} |
|
|
|
|
|
|
|
backup_host() { |
|
message 10 "ARGS: $@" |
|
rhost=$1 |
|
shift |
|
if [ "z${localhost}" != "z$rhost" ] ; then |
|
$RSH "$rhost" ${TAR_PART1} -f "${localhost}:${TAPE_FILE}" $@ |
|
else |
|
|
|
|
|
CMD="exec ${TAR_PART1} -f \"${TAPE_FILE}\" $@" |
|
message 10 "CMD: $CMD" |
|
sh -c "$CMD" |
|
RC=$? |
|
message 10 "RC: $RC" |
|
return $RC |
|
fi |
|
} |
|
|
|
print_level() { |
|
if [ ${1-$DUMP_LEVEL} -eq 0 ]; then |
|
echo "Full" |
|
else |
|
echo "Level ${1-$DUMP_LEVEL}" |
|
fi |
|
} |
|
|
|
prev_level() { |
|
print_level `expr $DUMP_LEVEL - 1` | tr A-Z a-z |
|
} |
|
|
|
remote_run() { |
|
rhost=$1 |
|
shift |
|
message 10 "REMOTE $rhost: $@" |
|
if [ "x$rhost" != "x${localhost}" ] ; then |
|
$RSH "${rhost}" "$@" |
|
else |
|
$* |
|
fi |
|
} |
|
|
|
license() { |
|
cat - <<EOF |
|
Copyright (C) 2013 Free Software Foundation, Inc. |
|
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. |
|
This is free software: you are free to change and redistribute it. |
|
There is NO WARRANTY, to the extent permitted by law. |
|
EOF |
|
} |
|
|