diff --git a/quotacheck/GNUmakefile b/quotacheck/GNUmakefile index 53c130d..a090d09 100644 --- a/quotacheck/GNUmakefile +++ b/quotacheck/GNUmakefile @@ -1,7 +1,7 @@ include GNUmakevars BINDIR=/usr/local/sbin -all: quotacheck quotastat +all: quotacheck quotastat quotasanitycheck clean: rm -f quotacheck *.bak @@ -9,7 +9,7 @@ clean: distclean: clean rm -f customize -install: $(BINDIR) $(BINDIR)/quotacheck $(BINDIR)/quotastat +install: $(BINDIR) $(BINDIR)/quotacheck $(BINDIR)/quotastat $(BINDIR)/quotasanitycheck %: %.pl customize sh ./customize < $< > $@ diff --git a/quotacheck/quotacheck.pl b/quotacheck/quotacheck.pl index 8961ae2..d15671b 100644 --- a/quotacheck/quotacheck.pl +++ b/quotacheck/quotacheck.pl @@ -1,25 +1,45 @@ #!@@@perl@@@ +use Getopt::Std; + sub warnmsg { my ($mount, $usage, $soft, $hard, $grace, $unit) = @_; + %dosdrv = ( + '/wifosv/dosprogs' => 'H:', + '/wsrdb/users' => 'J:', + '/wifosv/users' => 'K:', + '/usr/local/www' => 'W:', + ); - my $msg = "Sie haben auf $mount (Host $hostname) Ihr Limit von $soft $unit " . - "um " . ($usage - $soft) . " $unit überschritten.\n"; + if ($dosdrv{$mount}) { + $wo = 'Netzplatte ' . $dosdrv{$mount}; + } else { + $wo = "$mount (Host $hostname)"; + } + + my $msg = "Sie haben auf $wo Ihr in Disk Quotas gesetztes Limit\n" . + "überschritten. "; if ($grace eq "EXPIRED" or $usage >= $hard-2) { - $msg .= "Sie können dort KEINE Files mehr anlegen.\n" . - "Bitte löschen Sie eine entsprechende Anzahl Files\n" . - "oder wenden Sie sich an einen Systemadministrator.\n"; + $msg .= "Sie können dort KEINE Files mehr anlegen.\n" ; } else { $grace =~ s/days/Tage/g; $grace =~ s/hours/Stunden/g; - $msg .= "Sie können dieses Limit noch $grace um maximal " . - ($hard - $soft) . " $unit überschreiten.\n" . - "Sollte das nicht reichen, wenden Sie sich an einen Systemadministrator.\n"; + $msg .= "Sie können noch " . + ($hard - $usage) . " $unit anlegen.\n" ; } + $msg .= "\nBei dringendem Bedarf können Sie sofort zusätzlichen Platz schaffen,\n" . + "indem Sie auf $wo Files löschen, komprimieren oder auf eine\n" . + "andere Netzplatte verschieben.\n" . + "\n" . + "Lassen Sie sich bei Gelegenheit auch von einem der zuständigen\n" . + "Systemadministratoren unterstützen:\n" . + "Peter Holzer, hjp\@wsr.ac.at, Kl. 786\n" . + "Michael Demelbauer, michael\@wsr.ac.at, Kl. 787\n"; return $msg; } +getopts('ad', \%opts); $hostname=`hostname`; chomp($hostname); @@ -36,8 +56,7 @@ $df =~ s/\n[ \t]+/ /mg; for $ln (@df) { ($fs, $total, $used, $free, $pct, $mount) = split(/\s+/, $ln); if ($fs =~ m|^/dev/|) { - print $mount, "\n"; - open REPQUOTA, "@@@repquota@@@ $mount |" or die "cannot call @@@repquota@@@: $!"; + open REPQUOTA, "@@@repquota@@@ $mount 2>/dev/null |" or die "cannot call @@@repquota@@@: $!"; while () { $msg = ""; if (/(\w+) \s+ -- \s* @@ -46,42 +65,54 @@ for $ln (@df) { /x) { #print "ok: $1\n"; } elsif (/(\w+) \s+ \+- \s* - (\d+)\s+(\d+)\s+(\d+)\s+(EXPIRED|\d+\.\d+\ (?:days|hours))\s+ + (\d+)\s+(\d+)\s+(\d+)\s+(NOT\sSTARTED|EXPIRED|\d+\.\d+\ (?:days|hours))\s+ (\d+)\s+(\d+)\s+(\d+) /x) { print "block limit: $1: $2 > ($3 $4) $5\n"; $user = $1; - $msg = warnmsg($mount, $2, $3, $4, $5, "kB"); + $msg = warnmsg($mount, $2/1024, $3/1024, $4/1024, $5/1024, "MB"); } elsif (/(\w+) \s+ -\+ \s* (\d+)\s+(\d+)\s+(\d+)\s+ - (\d+)\s+(\d+)\s+(\d+)\s+(EXPIRED|\d+\.\d+\ (?:days|hours)) + (\d+)\s+(\d+)\s+(\d+)\s+(NOT\sSTARTED|EXPIRED|\d+\.\d+\ (?:days|hours)) /x) { print "file limit: $1: $5 > ($6 $7) $8\n"; $user = $1; $msg = warnmsg($mount, $5, $6, $7, $8, "Files"); } elsif (/(\w+) \s+ \+\+ \s* - (\d+)\s+(\d+)\s+(\d+)\s+(EXPIRED|\d+\.\d+\ (?:days|hours))\s+ - (\d+)\s+(\d+)\s+(\d+)\s+(EXPIRED|\d+\.\d+\ (?:days|hours)) + (\d+)\s+(\d+)\s+(\d+)\s+(NOT\sSTARTED|EXPIRED|\d+\.\d+\ (?:days|hours))\s+ + (\d+)\s+(\d+)\s+(\d+)\s+(NOT\sSTARTED|EXPIRED|\d+\.\d+\ (?:days|hours)) /x) { print "block limit: $1: $2 > ($3 $4) $5\n"; $user = $1; - $msg = warnmsg($mount, $2, $3, $4, $5, "kB"); + $msg = warnmsg($mount, $2/1024, $3/1024, $4/1024, $5/1024, "MB"); print "file limit: $1: $6 > ($7 $8) $9\n"; $msg .= "\n\n" . warnmsg($mount, $6, $7, $8, $9, "Files"); } else { - print "unparseable: $_"; + if ($. > 2) { # ignore header lines + print "$mount: $.: unparseable: $_"; + } } if ($msg) { - open (SENDMAIL, "|@@@sendmail@@@ -t -i"); - print SENDMAIL "To: <$user\@wsr.ac.at>\r\n"; - print SENDMAIL "Cc: \r\n"; + if ($opts{'d'}) { + open (SENDMAIL, ">&1"); + } else { + open (SENDMAIL, "|@@@sendmail@@@ -t -i"); + } + if ($opts{'a'}) { + print SENDMAIL "To: \r\n"; + print SENDMAIL "Subject: User $user: Disk Quotas überschritten\r\n"; + } else { + print SENDMAIL "To: <$user\@wsr.ac.at>\r\n"; + print SENDMAIL "Cc: \r\n"; + print SENDMAIL "Subject: Disk Quotas überschritten\r\n"; + } print SENDMAIL "Reply-To: \r\n"; - print SENDMAIL "Subject: Disk Quotas überschritten\r\n"; print SENDMAIL "\r\n"; print SENDMAIL "$msg\r\n"; } } + close (REPQUOTA); } } diff --git a/quotacheck/quotasanitycheck b/quotacheck/quotasanitycheck new file mode 100755 index 0000000..315f2a8 --- /dev/null +++ b/quotacheck/quotasanitycheck @@ -0,0 +1,103 @@ +#!/usr/bin/perl +# +# $Id: quotasanitycheck,v 1.1 1998-09-17 07:30:12 hjp Exp $ +# $Log: quotasanitycheck,v $ +# Revision 1.1 1998-09-17 07:30:12 hjp +# Made messages more user friendly (and less admin friendly). +# allow grace time "NOT STARTED". +# added quotasanitycheck. +# +# +# check quotas for sanity: +# * for each user, the difference between current usage and hard +# limit must be less than the available space (preferably much +# less). +# * all quotas must be above some limit +# * soft quotas must be less than hard quotas. + +use Getopt::Std; + +$opts{'b'} = 1; +$opts{'f'} = 1; +$opts{'F'} = 1; + +getopts('b:f:F:', \%opts); + +print "b=", $opts{'b'}, "f=", $opts{'f'}, "F=", $opts{'F'}, "\n"; + +$hostname=`hostname`; +chomp($hostname); +open (DF, "/usr/local/bin/df |") or die "cannot call /usr/local/bin/df: $!"; + +$fs = $/; +undef ($/); +$df = ; +close(DF); +$/ = $fs; + +$df =~ s/\n[ \t]+/ /mg; +@df = split(/\n/, $df); +for $ln (@df) { + ($fs, $total, $used, $free, $pct, $mount) = split(/\s+/, $ln); + if ($fs =~ m|^/dev/|) { + open REPQUOTA, "/usr/sbin/repquota $mount 2>/dev/null |" or die "cannot call /usr/sbin/repquota: $!"; + while () { + if (/(\w+) \s+ [-+][-+] \s* + (\d+)\s+(\d+)\s+(\d+)\s+(NOT\sSTARTED|EXPIRED|\d+\.\d+\ (?:days|hours)|)\s+ + (\d+)\s+(\d+)\s+(\d+)\s+(NOT\sSTARTED|EXPIRED|\d+\.\d+\ (?:days|hours)|) + /x) { + $user = $1; + $bluse = $2; + $blsoft = $3; + $blhard = $4; + $fluse = $6; + $flsoft = $7; + $flhard = $8; + print "$mount $user"; + print " block limit"; + print " soft $blsoft hard $blhard"; + if ($blsoft >= $blmin) { + print " min_ok"; + } else { + print " min_FAIL"; + } + if ($blsoft < $blhard) { + print " softhard_ok"; + } else { + print " softhard_FAIL"; + } + if ($blhard - $bluse < $free * $opts{'F'}) { + print " hardfree_ok"; + } else { + print " hardfree_FAIL"; + } + + print " file limit"; + print " soft: $flsoft hard $flhard"; + if ($flsoft >= $flmin) { + print " min_ok"; + } else { + print " min_FAIL"; + } + if ($flsoft < $flhard) { + print " softhard_ok"; + } else { + print " softhard_FAIL"; + } + if ($flhard - $fluse < $free) { + print " hardfree_ok"; + } else { + print " hardfree_FAIL"; + } + print "\n"; + + } else { + if ($. > 2) { # ignore header lines + print "$mount: $.: unparseable: $_"; + } + } + + } + close (REPQUOTA); + } +} diff --git a/quotacheck/quotastat.pl b/quotacheck/quotastat.pl index b408206..1f45c82 100644 --- a/quotacheck/quotastat.pl +++ b/quotacheck/quotastat.pl @@ -18,19 +18,16 @@ $df =~ s/\n[ \t]+/ /mg; open (STAT, ">>/usr/local/dfstat/quota.stat") or die "cannot append to quota.stat"; for $ln (@df) { ($fs, $total, $used, $free, $pct, $mount) = split(/\s+/, $ln); - if ($fs =~ m|^/dev/|) { - print $mount, "\n"; + if ($fs =~ m|^/dev/| and -f "$mount/quotas") { open REPQUOTA, "@@@repquota@@@ $mount |" or die "cannot call @@@repquota@@@: $!"; while () { $msg = ""; - if (/^\s+/) { + if (!/\d+/) { #print "header: $_"; } elsif (/(\w+) \s+ [-+][-+] \s* - (\d+)\s+(\d+)\s+(\d+)\s+(|EXPIRED|\d+\.\d+\ (?:days|hours))\s+ - (\d+)\s+(\d+)\s+(\d+)\s+(|EXPIRED|\d+\.\d+\ (?:days|hours)) + (\d+)\s+(\d+)\s+(\d+)\s+(|NOT\sSTARTED|EXPIRED|\d+\.\d+\ (?:days|hours))\s+ + (\d+)\s+(\d+)\s+(\d+)\s+(|NOT\sSTARTED|EXPIRED|\d+\.\d+\ (?:days|hours)) /x) { - print "block limit: $1: $2 > ($3 $4) $5\n"; - print "file limit: $1: $6 > ($7 $8) $9\n"; print STAT "$date\t$mount\t$1\t$2\t$3\t$4\t$6\t$7\t$8\n"; } else { print "unparseable: $_";