[net.news.adm] Running out of space - script to stop it

geoff@desint.UUCP (Geoff Kuenning) (09/01/85)

Um, I hesitate to post this because the durned implementation is a hack,
but I think some of you folks might appreciate a little shell script I've
got.  It's called 'ckuucp' and I run it every 20 minutes from crontab.  It
checks 'df' to see if /usr or /usr1 (my news filesystem) is getting
full.  (It's smart enough to add the sizes of D.* and TM.* files into the
news filespace, to allow for unbatching that hasn't happened).  If things
start to look bad, it kills off any uucico that's running, and sends you mail.

Deficiencies:  works for my system (SV.0), must be edited for others (somewhat
parameterized, though).  Doesn't check # of inodes (shouldn't usually matter,
but once my free-inode count got mucked up and I lost news).  Doesn't
distinguish non-news or outbound D.* files.  When disk gets extremely low,
doesn't distinguish uucico's that are sending outbound D.* files
(which would actually free up space).  Tends to leave lots of TM.* files
lying around (uuclean -n3 -pTM. can fix this nicely).  No man page (shame on
me).

Anyway, it's small enough I figured I'd generate less traffic by posting
it than by polling to find out who wants it, so here it is.  Best of luck.

	Geoff Kuenning
	...!ihnp4!trwrb!desint!geoff

------------------------------cut here--------------------------------
#!/bin/sh
#
#	%W%	%G% %U%
#
#	Periodically check the amount of disk space left on /usr
#	If it falls below $1 blocks (500 default), kill any running uucico
#	as soon as its current temp file disappears.  If it falls below
#	$2 blocks (100 default), kill all running uucico's regardless of
#	whether the current temp file is complete.
#
#	The size of the news spool directory is also watched.  If the sum of
#	the sizes of the D.* and TM.* files in /usr/spool/uucp, subtracted
#	from the free space on NEWSSYS, is less than $3 (default is the
#	value of $1), a soft limit on uucico's is invoked.  Similarly, if
#	$4 (default $2) is exceeded, uucico's will be killed immediately.
#
#	$5 is a multiplicative factor that will be applied to the number of
#	blocks in D.* files.  This is intended to allow space for fragmentation
#	and archiving.  The factor must be expressed as a rational number.  It
#	must be quoted, and if it contains shell metacharacters they must be
#	escaped *inside* the quotes.  For example,
#
#	    "5 \* 3"
#

PATH=/bin:/usr/bin
export PATH

SOFT=${1-500}
HARD=${2-100}
NSOFT=${3-$SOFT}
NHARD=${4-$HARD}
FACTOR=${5-"125 / 100"}
LIB=/usr/lib/uucp
SPOOL=/usr/spool/uucp
FILESYS=/usr
NEWSSYS=/usr1

cd $LIB
trap "rm -f $LIB/cklock*; exit 0" 1 2 3 9 15

#	set up lock files to prevent simultaneous checking

cp /dev/null cklock
chmod 400 cklock
ln cklock cklock1  ||  exit 1

trap "rm -f $LIB/cklock*; exit 0" 0 1 2 3 9 15

#	If there are less than $SOFT free blocks left on the $FILESYS
#	file system, we must kill uucp.  Restart is somebody else's business.


blocks=`df $FILESYS | sed "s/.*:  *\([0-9][0-9]*\) blocks.*/\1/"`
nblocks=`df $NEWSSYS | sed "s/.*:  *\([0-9][0-9]*\) blocks.*/\1/"`
totblocks=`ls -s /usr/spool/uucp/D.* /usr/spool/uucp/TM.* \
  | awk 'BEGIN{tot=0}{tot += $1} END {print tot}'`
nblocks=`eval expr $nblocks - $totblocks "'*'" $FACTOR`

templist=`echo $SPOOL/TM.*`
if [ "$templist" = "$SPOOL/TM.*" ]
then
    templist=
fi
while [ "X$templist" != X -a \
  \( "$blocks" -le $SOFT -o 0"$nblocks" -le "$NSOFT" \) ]
do
    if [ "$blocks" -le $HARD -o 0"$nblocks" -le "$NHARD" ]
    then
	plist=`ps -e|grep uucico|cut -c1-6`
	case "X$plist" in
	    X)
		;;
	    *)
		kill $plist
		echo uucico"'"s $plist killed due to no disk - \
		  "$blocks" "$nblocks" | mail root
		;;
	esac
	exit 0
    fi
    sleep 120
    nlist=
    for i in $templist
    do
	if [ -f "$i" ]
	then
	    nlist="$nlist $i"
	elif [ "$i" != "$SPOOL/TM.*" ]
	then
#
#	    Here we have found a disappearing temp file.  We will kill
#	    the uucp that owned it before it gets too much farther.
#
	    sleep 30		# Give it time to die on its own
	    owner=`expr $i : $SPOOL'/TM\.0*\([1-9][0-9]*\)\....'`
	    kill $owner		# Tough luck, it waited too long
	    echo uucico $owner killed due to low disk - "$blocks" "$nblocks" \
	      | mail root
	fi
    done
    templist="$nlist"
    blocks=`df $FILESYS | sed "s/.*:  *\([0-9][0-9]*\) blocks.*/\1/"`
    nblocks=`df $NEWSSYS | sed "s/.*:  *\([0-9][0-9]*\) blocks.*/\1/"`
    totblocks=`ls -s /usr/spool/uucp/D.* \
      | awk 'BEGIN {tot = 0} {tot += $1} END {print tot}'`
    nblocks=`eval expr $nblocks - $totblocks "'*'" $FACTOR`
done
exit 0
-- 

	Geoff Kuenning
	...!ihnp4!trwrb!desint!geoff