Prevent periodic scripts that run longer than the expected period from

starting up before the previous script finishes.  This prevents an
infinite number of them from piling up and slowing a system down.

Since all the refactoring to make this happen required churning the
indenting of most of this file, make the indentation more consistent.

Reviewed by:	simon
MFC after:	1 week
This commit is contained in:
Brooks Davis 2012-02-12 23:18:05 +00:00
parent e50ebdcdab
commit df01f319c7

View File

@ -14,6 +14,18 @@ usage () {
exit 1
}
output_pipe()
{
# Where's our output going ?
eval output=\$${1##*/}_output
case "$output" in
/*) pipe="cat >>$output";;
"") pipe=cat;;
*) pipe="mail -E -s '$host ${1##*/} run output' $output";;
esac
eval $pipe
}
if [ $# -lt 1 ] ; then
usage
fi
@ -27,83 +39,102 @@ fi
host=`hostname`
export host
# If we were called normally, then create a lock file for each argument
# in turn and reinvoke ourselves with the LOCKED argument. This prevents
# very long running jobs from being overlapped by another run as this is
# will lead the system running progressivly slower and more and more jobs
# are run at once.
if [ $1 != "LOCKED" ]; then
ret=0
for arg; do
lockfile=/var/run/periodic.${arg##*/}.lock
lockf -t 0 "${lockfile}" /bin/sh $0 LOCKED "$arg"
case $? in
0) ;;
73) #EX_CANTCREATE
echo "can't create ${lockfile}" | output_pipe $arg
ret=1
;;
75) #EX_TEMPFAIL
echo "$host ${arg##*/} prior run still in progress" | \
output_pipe $arg
ret=1
;;
*)
ret=1
;;
esac
done
exit $ret
fi
if [ $# -ne 2 ]; then
usage
fi
shift
arg=$1
tmp_output=`mktemp ${TMPDIR:-/tmp}/periodic.XXXXXXXXXX`
# Execute each executable file in the directory list. If the x bit is not
# set, assume the user didn't really want us to muck with it (it's a
# README file or has been disabled).
for arg
do
# Where's our output going ?
eval output=\$${arg##*/}_output
case "$output" in
/*) pipe="cat >>$output";;
"") pipe=cat;;
*) pipe="mail -E -s '$host ${arg##*/} run output' $output";;
success=YES info=YES badconfig=NO empty_output=YES # Defaults when ${run}_* aren't YES/NO
for var in success info badconfig empty_output; do
case $(eval echo "\$${arg##*/}_show_$var") in
[Yy][Ee][Ss]) eval $var=YES;;
[Nn][Oo]) eval $var=NO;;
esac
done
success=YES info=YES badconfig=NO empty_output=YES # Defaults when ${run}_* aren't YES/NO
for var in success info badconfig empty_output
do
case $(eval echo "\$${arg##*/}_show_$var") in
[Yy][Ee][Ss]) eval $var=YES;;
[Nn][Oo]) eval $var=NO;;
esac
case $arg in
/*) if [ -d "$arg" ]; then
dirlist="$arg"
else
echo "$0: $arg not found" >&2
continue
fi
;;
*) dirlist=
for top in /etc/periodic ${local_periodic}; do
[ -d $top/$arg ] && dirlist="$dirlist $top/$arg"
done
;;
esac
case $arg in
/*) if [ -d "$arg" ]
then
dirlist="$arg"
else
echo "$0: $arg not found" >&2
continue
fi;;
*) dirlist=
for top in /etc/periodic ${local_periodic}
do
[ -d $top/$arg ] && dirlist="$dirlist $top/$arg"
done;;
esac
{
empty=TRUE
processed=0
for dir in $dirlist
do
for file in $dir/*
do
if [ -x $file -a ! -d $file ]
then
output=TRUE
processed=$(($processed + 1))
$file </dev/null >$tmp_output 2>&1
rc=$?
if [ -s $tmp_output ]
then
case $rc in
0) [ $success = NO ] && output=FALSE;;
1) [ $info = NO ] && output=FALSE;;
2) [ $badconfig = NO ] && output=FALSE;;
esac
[ $output = TRUE ] && { cat $tmp_output; empty=FALSE; }
fi
cp /dev/null $tmp_output
{
empty=TRUE
processed=0
for dir in $dirlist; do
for file in $dir/*; do
if [ -x $file -a ! -d $file ]; then
output=TRUE
processed=$(($processed + 1))
$file </dev/null >$tmp_output 2>&1
rc=$?
if [ -s $tmp_output ]; then
case $rc in
0) [ $success = NO ] && output=FALSE;;
1) [ $info = NO ] && output=FALSE;;
2) [ $badconfig = NO ] && output=FALSE;;
esac
[ $output = TRUE ] && { cat $tmp_output; empty=FALSE; }
fi
done
cp /dev/null $tmp_output
fi
done
if [ $empty = TRUE ]
then
if [ $empty_output = TRUE ]
then
done
if [ $empty = TRUE ]; then
if [ $empty_output = TRUE ]; then
[ $processed = 1 ] && plural= || plural=s
echo "No output from the $processed file$plural processed"
fi
else
echo ""
echo "-- End of $arg output --"
fi
} | eval $pipe
done
else
echo ""
echo "-- End of $arg output --"
fi
} | output_pipe ${arg}
rm -f $tmp_output