[news.admin] news overflow, expire problems

geoff@desint.UUCP (Geoff Kuenning) (05/23/87)

In article <1610@drivax.UUCP> braun@drivax.UUCP (Karl T. Braun (kral)) writes:

> How does one gracefully recover from an overflowed partition?  Is there a way
> I can retrieve lost articles?

(1) If your log file didn't overflow (e.g., you ran out of i-nodes, not space),
    it will still list the missing article id's.  Use egrep and cut to pick
    the missing ID's out of the log, and feed them to the "askfor"
    script below.
(2) You may want to install the "ckuucp" script below in your crontab
    so that this won't happen in the future.
(3) For those people with expire problems, the "histmiss" script below will
    produce a list of articles missing from the history file.  It's faster
    than "expire -r", and works even on older systems where "expire -r"
    is broken.

In all three cases, you will have to edit the scripts to install your own
local pathnames, free-space limits, and so forth.  BSD and HDB systems
will have additional trouble with "ckuucp" because it doesn't know about
per-site spooling directories.  I run "ckuucp" out of my crontab every
fifteen minutes with the command:

    exec /usr/lib/uucp/ckuucp 700 400 1600 800 '11 / 10' 2>/dev/null
---------------------------cut here------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	askfor
#	ckuucp
#	histmiss
# This archive created: Fri May 22 20:55:19 1987
export PATH; PATH=/bin:$PATH
if test -f 'askfor'
then
	echo shar: will not over-write existing file "'askfor'"
else
cat << \SHAR_EOF > 'askfor'
: Use /bin/sh
#
# $Header$
#
# $Log$
#
#	Ask a news neighbor for specific articles.
#
#	Usage:
#
#	askfor dest-site < list-of-article-ids
OURSITE=`uname -n`
INEWS=/usr1/usenet/lib/inews

case $# in
    1) ;;
    *)
	echo 'Usage:  askfor dest-site < list-of-article-ids' 1>&2
	exit 1
	;;
esac

DEST=$1
TMP=/tmp/askfor$$
trap "/bin/rm ${TMP}?; exit 1" 1 2 15
echo 'Thank you' > ${TMP}a
xargs -s60 echo > ${TMP}b
while read arts
do
    $INEWS -n to.$DEST -t "cmsg sendme $arts $OURSITE" < ${TMP}a
done < ${TMP}b
/bin/rm ${TMP}?
SHAR_EOF
chmod +x 'askfor'
fi # end of overwriting check
if test -f 'ckuucp'
then
	echo shar: will not over-write existing file "'ckuucp'"
else
cat << \SHAR_EOF > 'ckuucp'

#!/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"
#
#	$6 and $7 are soft and hard limits for the number of free inodes in
#	the news spool filesystem.  Defaults are 2000 (hard) and 1000 (soft)
#

PATH=/bin:/usr/bin
export PATH

SOFT=${1-500}
HARD=${2-100}
NSOFT=${3-$SOFT}
NHARD=${4-$HARD}
FACTOR=${5-"125 / 100"}
NISOFT=${6-2000}
NIHARD=${7-1000}
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/"`
ninodes=`df $NEWSSYS | sed "s/.*blocks *\([0-9][0-9]*\) i-nodes.*/\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" \
    -o "0$ninodes" -le "$NISOFT" \) ]
do
    if [ "$blocks" -le $HARD -o 0"$nblocks" -le "$NHARD" \
      -o 0"$ninodes" -le "$NIHARD" ]
    then
	plist=`ps -e|grep uucico|cut -c1-6`
	case "X$plist" in
	    X)
		;;
	    *)
		kill $plist
		echo Subject: uucico killing'

'Uucico"'"s $plist have been killed due to no disk - \
		  "$blocks" "$nblocks" "$ninodes" | 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 Subject: uucico killing'

'uucico $owner killed due to low disk - "$blocks" "$nblocks" "$ninodes" \
	      | 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/"`
    ninodes=`df $NEWSSYS | sed "s/.*blocks.*\([0-9][0-9]*\) i-nodes.*/\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
SHAR_EOF
chmod +x 'ckuucp'
fi # end of overwriting check
if test -f 'histmiss'
then
	echo shar: will not over-write existing file "'histmiss'"
else
cat << \SHAR_EOF > 'histmiss'

#!/bin/sh
#
#	Produce a list of all files that are in the spool directory, but
#	not in the Usenet history file.
#
#	Usage:
#
#	histmiss [libdir] [spooldir] | xargs /bin/rm -f
#
#	to remove files not listed in the history file.
#
LIBDIR=${1:-/usr1/usenet/lib}
SPOOLDIR=${2:-/usr1/usenet/spool}
TMP=/tmp/hm$$
cd $SPOOLDIR
trap "rm ${TMP}?; exit 1" 1 2 15
find . -type f -print \
  | sed 's;^\./;;' \
  | sort -o ${TMP}a
awk '{for (i = 5;  i <= NF;  i++) print $i}' ${LIBDIR}/history \
  | tr . / \
  | sort -o ${TMP}b
comm -23 ${TMP}a ${TMP}b
rm ${TMP}?
SHAR_EOF
chmod +x 'histmiss'
fi # end of overwriting check
#	End of shell archive
exit 0
-- 
	Geoff Kuenning   geoff@ITcorp.com   {uunet,trwrb}!desint!geoff

dennis@rlgvax.UUCP (Dennis Bednar) (05/30/87)

The awk command in the histmiss shell script was very useful.
Thanks for the contribution.

However, there is a slight bug in it, that prevents it from
finding all news articles unreferenced by the history text file.

To fix it, change the 5 to a 4.  That is, field number 4 is
the first field containing an article filename.


-- 
FullName:	Dennis Bednar
UUCP:		{seismo|sundc}!rlgvax!dennis
USMail:		CCI; 11490 Commerce Park Dr.; Reston VA 22091
Telephone:	+1 703 648 3300