summaryrefslogtreecommitdiffstats
path: root/usr.sbin/periodic
diff options
context:
space:
mode:
authorbrooks <brooks@FreeBSD.org>2012-02-12 23:18:05 +0000
committerbrooks <brooks@FreeBSD.org>2012-02-12 23:18:05 +0000
commit15a27123c92d3bfdcb21b119193e10fee4a40073 (patch)
tree667df037b877e38bb13b46bd6721778c47c186b4 /usr.sbin/periodic
parent306648088e53b84af5d9819cbbc395024153e40b (diff)
downloadFreeBSD-src-15a27123c92d3bfdcb21b119193e10fee4a40073.zip
FreeBSD-src-15a27123c92d3bfdcb21b119193e10fee4a40073.tar.gz
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
Diffstat (limited to 'usr.sbin/periodic')
-rw-r--r--usr.sbin/periodic/periodic.sh159
1 files changed, 95 insertions, 64 deletions
diff --git a/usr.sbin/periodic/periodic.sh b/usr.sbin/periodic/periodic.sh
index ca954ea..cfe6109 100644
--- a/usr.sbin/periodic/periodic.sh
+++ b/usr.sbin/periodic/periodic.sh
@@ -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
OpenPOWER on IntegriCloud