eay@surf.sics.bu.oz (Eric the Young) (08/27/90)
A few weeks ago I wrote a perl script to intelligently expire news on our news partition. After asking around locally I found that most people have their news setup to expire news after a fixed number of days as opposed to running expire every time the news partition had less than x meg. free on it. Feeling that other people may be able to use this script I now post it. If I have just reinvented the wheel, break it to me gently If you have no interest in this, hit 'n' now. Background. Our site has a dedicated 120 meg. /usr/spool/news on a microvax 3600 running ultrix 3.0. The partitions has a very large number of inodes and has the 'min free disk %' set to zero (read tunefs under the -m option). I have my script run from cron every few hours with parameters set so that every time there is less than 20 meg. free, it runs expire so that there will be a least 30 meg. free when expire has finished. What this means is that the disk will normally all ways have about 20 meg. free (less if lots of news comes in a space of a few hours) and will remove news only when it needs to. Since there should never normally be under 10 meg. free, the disk degradation that would occur at this point (due to 0% free disk) should not occur. If anyone finds this useful, please give me some feed back (this is my first software post, I need encouragement :-) :-) --8<--8<-- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: expiredisk.perl # Wrapped by eay@surf on Mon Aug 27 17:20:04 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'expiredisk.perl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'expiredisk.perl'\" else echo shar: Extracting \"'expiredisk.perl'\" \(2789 characters\) sed "s/^X//" >'expiredisk.perl' <<'END_OF_FILE' X#!/usr/local/bin/perl X# X# expiretime v 1.1 Eric Young (eay@surf.bu.oz.au) X# X# This scipt is used to manage free disk space on our news partition. X# X# On our host we have a dedicated /usr/spool/news with a very high X# number of inodes and a minimun disk free space of 0%. X# This script, which is run every 2 hours, calculates the corect parameters X# to pass to expire so that expire will be run quite infrequently. X# X# 1) use df to see if we need to run expire X# 2) if yes; addup how much news there is for each day X# 3) run expire once with the correct parameters to delete just enough X# news. X# X# It is run on our system as X# expiretime 20000 30000 X# X# v 1.0 11/07/90 X# X$NEWSDIR='/usr/spool/news'; X X($#ARGV == 1) || die "expiretime <min-free> <free upto>\n"; open(LOG,">>/usr/adm/expiretime.log") || die "unable to open log file:%!"; X select(LOG); $|=1; X$minfree=$ARGV[0]; X$keepfree=$ARGV[1]; X X$free=&fsfree($NEWSDIR); X X$maxage=0; X@size_bytes=(); X@numfiles=(); X X$now=time(); X($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($now); X$nowday=$yday+($year*365); X printf(LOG "%02d:%02d - %2d/%02d/%02d: ",$hour,$min,$mday,$mon+1,$year); printf(LOG "Free: %d KeepFree: %d",$free,$minfree); if ($free > $minfree) X { X printf(LOG " No expire needed\n"); X exit 0; X } else X { X printf(LOG " Doing expire\n"); X } X chdir($NEWSDIR); X&dodir(); X X$maxage=1000 if ($maxage > 1000); # just in case for ($i=0; $i <= $maxage; $i++) X { X if ($numfiles[$i] > 0) X { X printf(LOG "day %2d num=%5d size_l=%10d\n",$i, X $numfiles[$i],$size_bytes[$i]/1024); X } X } X X$days=$maxage; X$totfree=0; for ($i=$maxage; $i >= 0; $i--) X { X $days=$i; X $totfree+=($size_bytes[$i]/1024); X last unless ($totfree+$free < ($keepfree)); X } X X$hist=$days+14; printf(LOG "/usr/lib/news/expire -i -e $days -E $hist\n"); if ($days >= 1) X { X exec("/usr/lib/news/expire -i -e $days -E $hist"); X } X sub dodir X { X opendir(DIR,'.') || die "Can't open dir"; X local(@filenames) = readdir(DIR); X closedir(DIR); X X for (@filenames) X { X next if $_ eq '.'; X next if $_ eq '..'; X X ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev, X $size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($_); X ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)= X localtime($mtime); X if ($mode & 0040000) # a dir X { X chdir $_ || die "Can't cd to $_"; X X &dodir(); X chdir('..'); X } X else X { X $age=$nowday-($yday+($year*365)); X if ($age > $maxage) X { X $maxage=$age; X $#size_bytes=$[+$maxage; X $#numfiles=$[+$maxage; X } X X $size_bytes[$age]+=$size; X $numfiles[$age]++; X } X } X } X sub fsfree X { X local($fs)=@_; X X open(FS,"/bin/df $fs|") || die "Unable to run df\n"; X for (<FS>) X { X chop; X split; X if ($_[0] =~ "dev") X { X close(FS); X return($_[3]); X } X } X die "unable to find disk usage for $fs\n"; X } X END_OF_FILE if test 2789 -ne `wc -c <'expiredisk.perl'`; then echo shar: \"'expiredisk.perl'\" unpacked with wrong size! fi chmod +x 'expiredisk.perl' # end of 'expiredisk.perl' fi echo shar: End of shell archive. exit 0 -- Eric Young | "It is always best to start running System Programmer, SICS Bond Uni.| away early, before the rush. That way ACSnet: eay@surf.sics.bu.oz.au | there are fewer bodies to trip over."