1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-22 02:50:28 +03:00

Initscript - add backup of corrupt non-persistent databases

Corrupt non-persistent databases never get analysed because ctdbd
zeroes them at startup.

Modify the initscript so that corrupt non-persistent databases are
moved aside to a backup.  If the number of backups for a particular
database exceeds $CTDB_MAX_CORRUPT_DB_BACKUPS (default 10) then the
oldest excess backups are garbage collected.

Abstracts from and cleans up the code for checking persistent
databases.

Logging of related messages is done to syslog or a log file as
specified.

Signed-off-by: Martin Schwenke <martin@meltin.net>

(This used to be ctdb commit 00cd75595685dae829758abf1a4cb644af7ed50e)
This commit is contained in:
Martin Schwenke 2012-03-28 14:50:36 +11:00 committed by Ronnie Sahlberg
parent 081a8ec403
commit a3ee4a900f

View File

@ -107,81 +107,108 @@ build_ctdb_options () {
maybe_set "--max-persistent-check-errors" "$CTDB_MAX_PERSISTENT_CHECK_ERRORS"
}
check_tdb () {
local PDBASE=$1
# Log given message or stdin to either syslog or a CTDB log file
do_log ()
{
if [ "$CTDB_SYSLOG" = "yes" -o \
"${CTDB_OPTIONS#*--syslog}" != "$CTDB_OPTIONS" ] ; then
test x"$TDBTOOL_HAS_CHECK" = x"1" && {
#
# Note tdbtool always exits with 0
#
local OK=`tdbtool $PDBASE check | grep "Database integrity is OK" | wc -l`
test x"$OK" = x"1" || {
return 1;
}
return 0;
}
tdbdump $PDBASE >/dev/null 2>/dev/null || {
return $?;
}
return 0;
logger -t "ctdb.init" "$@"
else
_l="${CTDB_LOGFILE:-/var/log/log.ctdb}"
{
date
if [ -n "$*" ] ; then
echo "$*"
else
cat
fi
} >>"$_l"
fi
}
check_persistent_databases () {
PERSISTENT_DB_DIR="${CTDB_DBDIR:-/var/ctdb}/persistent"
mkdir -p $PERSISTENT_DB_DIR 2>/dev/null
local ERRCOUNT=$CTDB_MAX_PERSISTENT_CHECK_ERRORS
select_tdb_checker ()
{
# Find the best TDB consistency check available.
use_tdb_tool_check=false
if [ -x /usr/bin/tdbtool ] && \
echo "help" | /usr/bin/tdbtool | grep -q check ; then
test -z "$ERRCOUNT" && {
ERRCOUNT="0"
}
test x"$ERRCOUNT" != x"0" && {
return 0;
}
if test -x /usr/bin/tdbtool ; then
HAVE_TDBTOOL=1
use_tdb_tool_check=true
elif [ -x /usr/bin/tdbtool -a -x /usr/bin/tdbdump ] ; then
do_log <<EOF
WARNING: The installed 'tdbtool' does not offer the 'check' subcommand.
Using 'tdbdump' for database checks.
Consider updating 'tdbtool' for better checks!
EOF
elif [ -x /usr/bin/tdbdump ] ; then
do_log <<EOF
WARNING: 'tdbtool' is not available.
Using 'tdbdump' to check the databases.
Consider installing a recent 'tdbtool' for better checks!
EOF
else
HAVE_TDBTOOL=0
do_log <<EOF
WARNING: Cannot check databases since neither
'tdbdump' nor 'tdbtool check' is available.
Consider installing tdbtool or at least tdbdump!
EOF
return 1
fi
}
if test x"$HAVE_TDBTOOL" = x"1" ; then
TDBTOOL_HAS_CHECK=`echo "help" | /usr/bin/tdbtool | grep check | wc -l`
else
TDBTOOL_HAS_CHECK=0
fi
check_tdb ()
{
_db="$1"
if test -x /usr/bin/tdbdump ; then
HAVE_TDBDUMP=1
else
HAVE_TDBDUMP=0
fi
if test x"$HAVE_TDBDUMP" = x"0" -a x"$TDBTOOL_HAS_CHECK" = x"0" ; then
echo "WARNING: Cannot check persistent databases since"
echo "neither 'tdbdump' nor 'tdbtool check' is available."
echo "Consider installing tdbtool or at least tdbdump!"
return 0
fi
if test x"$HAVE_TDBDUMP" = x"1" -a x"$TDBTOOL_HAS_CHECK" = x"0" ; then
if test x"$HAVE_TDBTOOL" = x"0"; then
echo "WARNING: 'tdbtool' is not available. Using 'tdbdump' to"
echo "check the persistent databases."
echo "Consider installing a recent 'tdbtool' for better checks!"
else
echo "WARNING: The installed 'tdbtool' does not offer the 'check'"
echo "subcommand. Using 'tdbdump' for persistent database checks."
echo "Consider updating 'tdbtool' for better checks!"
fi
fi
for PDBASE in `ls $PERSISTENT_DB_DIR/*.tdb.[0-9] 2>/dev/null`; do
check_tdb $PDBASE || {
echo "Persistent database $PDBASE is corrupted! CTDB will not start."
if $use_tdb_tool_check ; then
# tdbtool always exits with 0 :-(
if tdbtool "$_db" check 2>/dev/null |
grep -q "Database integrity is OK" ; then
return 0
else
return 1
fi
else
tdbdump "$_db" >/dev/null 2>/dev/null
return $?
fi
}
check_persistent_databases ()
{
_dir="${CTDB_DBDIR_PERSISTENT:-${CTDB_DBDIR:-/var/ctdb}/persistent}"
mkdir -p "$_dir" 2>/dev/null
[ "${CTDB_MAX_PERSISTENT_CHECK_ERRORS:-0}" = "0" ] || return 0
for _db in $(ls "$_dir/"*.tdb.*[0-9] 2>/dev/null) ; do
check_tdb $_db || {
do_log "Persistent database $_db is corrupted! CTDB will not start."
return 1
}
done
}
check_non_persistent_databases ()
{
_dir="${CTDB_DBDIR:-/var/ctdb}"
mkdir -p "$_dir" 2>/dev/null
for _db in $(ls "${_dir}/"*.tdb.*[0-9] 2>/dev/null) ; do
check_tdb $_db || {
_backup="${_db}.$(date +'%Y%m%d.%H%M%S.%N').corrupt"
do_log <<EOF
WARNING: database ${_db} is corrupted.
Moving to backup ${_backup} for later analysis.
EOF
mv "$_db" "$_backup"
# Now remove excess backups
ls -td "${_db}."*".corrupt" |
tail -n +$((${CTDB_MAX_CORRUPT_DB_BACKUPS:-10} + 1)) |
xargs rm -f
}
done
}
@ -239,7 +266,10 @@ start() {
# instance of ctdb got killed with -9 or similar
drop_all_public_ips
check_persistent_databases || return $?
if select_tdb_checker ; then
check_persistent_databases || return $?
check_non_persistent_databases
fi
if [ "$CTDB_SUPPRESS_COREFILE" = "yes" ]; then
ulimit -c 0