[OpenAFS] Add new fileserver
Steve Simmons
scs@umich.edu
Tue, 10 Apr 2007 13:49:39 -0400
--Apple-Mail-1-351683513
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
delsp=yes;
format=flowed
On Apr 8, 2007, at 4:39 AM, Chris Huebsch wrote:
>
> There is no command "give me all the available space on all of my afs
> servers". You need to write a little script for that. So space does
> not
> combine or sum up.
Enjoy. Works on the half-dozen cells I've tried it on.
--Apple-Mail-1-351683513
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
x-unix-mode=0755;
name=afsdf
Content-Disposition: attachment;
filename=afsdf
#!/usr/bin/perl -w
#-----------------------------------------------------------------------------
# $Id: afsdf,v 1.12 2006/01/10 15:08:54 scs Exp $
#
# NOTE: This tool is archived. Please check out
# a copy if you are planning on modifying the main copy.
#
# Repository: $Source: /home/scs/Projects/AFS.Tools/AFS.Reports/RCS/afsdf,v $
#
# $Log: afsdf,v $
# Revision 1.12 2006/01/10 15:08:54 scs
# Much tweaking for the very large umich cell.
#
# Revision 1.11 2005/11/14 23:38:30 scs
# Restore switches (not fully tested).
#
# Revision 1.10 2005/11/14 19:42:54 scs
# Removed old perl arglist, added check for divide by zero.
#
# Revision 1.9 2004/04/20 21:30:35 scs
# Removed need for auth.
#
# Revision 1.8 2004/04/09 14:41:06 scs
# Moved to common perl home.
#
# Revision 1.7 2004/03/15 19:44:10 scs
# Added check for zero division.
#
# Revision 1.6 2004/02/10 13:44:16 scs
# Now do warnings at server level and grand total level, too.
#
# Revision 1.5 2004/02/10 13:27:07 scs
# Moved to MB display, added commas.
#
# Revision 1.4 2004/01/08 15:17:52 scs
# Added initial work for switches (more needed), made warning/danger levels
# much more sophisticated (try --verbose).
#
# Revision 1.3 2003/11/25 17:50:45 scs
# Yes another column error.
#
# Revision 1.2 2003/11/25 17:28:10 scs
# Got subtotals in wrong columns.
#
# Revision 1.1 2003/11/21 22:17:48 scs
# Initial revision
#
#
# Construction notes:
#
# This passes both 'perl -w' and 'use strict' silently.
#
# Tab stops are set at 8, shift widths at 4.
#
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Generic modules and their location(s)
#-----------------------------------------------------------------------------
use strict;
use English; # Strongly recommended for readability
use Carp; # Creates very detailed and useful debug msgs
use Data::Dumper; # Prints complex variables
use warnings;
# Make output from perl -w be more verbose and useful
use diagnostics;
# Comment out when not debugging!
#BEGIN { $Exporter::Verbose=1; }
#-----------------------------------------------------------------------------
# Who the heck are we? Used in many error messages, define early.
#-----------------------------------------------------------------------------
use File::Basename;
my $TOOL = basename $0;
#-----------------------------------------------------------------------------
# option definitions
#-----------------------------------------------------------------------------
#
# Keep these in sync with the usage and help subroutines, but bear in
# mind that some options (like debug and sometimes verbose) may not
# be advertised to the user. See the usage/help subroutines for easy
# and reliable ways to keep the printing of default values in sync with
# their actual settings.
#
# Some switches and meanings:
# --version Print version and exit.
# --usage Print usage msg and exit.
# --help Print help and exit.
# -V --verbose Verbose mode. Not always advertised.
# --debug Debug mode. Not ever advertised.
# --perlwarn Interactively turn on perl -w flag for debugging.
# -m --mailto Mail message rather than print to stdout
# -W --warning Level at which we flag warnings
# -w --nowarning Never flag warnings
# -D --danger Level at which we flag dangerously full partitions
# -d --nowarning Never flag danger
# Declare all the variables set by the options
my (
$debug, $verbose, $perlwarn, # Control debug output
$help, $usage, $version, # Print a message and exit
$mail, $mailto, # Send email to mailto rather than print
$warning, $danger, # Warning and danger levels
$nowarning, $nodanger, # Supress warnings/danger messages
);
# Tweak these next two default values as needed. If you don't want
# warnings, just danger notices, set warn == danger. Note they
my $warn_level = 90.0;
my $danger_level = 95.0;
# Set the switches that need defaults. Zero is off, anything else
# is on. If the usage message prints them, set a string now describing
# their default value now.
$verbose = 0; my $verbose_dflt = $verbose ? "yes" : "no";
$debug = 0; my $debug_dflt = $debug ? "yes" : "no";
$nowarning = 0; my $nowarning_dflt = $nowarning ? "yes" : "no";
$nodanger = 0; my $nodanger_dflt = $nodanger ? "yes" : "no";
# Do *not* actually parse the options until the usage statements
# are built, below.
#-------------------------------------------------------------------------
# Usage and help messages, and basic setup for defining them.
#
# The help function prints a help message on STDERR and exits. It takes
# no parameters, and will complain if misused.
#
# The usage function will print an optional set of caller-supplied
# messages, followed by a standard usage message.
#
# The standard usage and help messages include the name and version
# number of the program being used. Some defaults are indicated;
# the messages should be defined before options are checked.
#-------------------------------------------------------------------------
# These funky lines define a variable named VERSION which we build from
# the RCS/CVS revision number.
my $VERSION = '$Revision: 1.12 $';
$VERSION =~ s/^.+\s+(\S+)\s.*$/$1/g;
# Call this function with additional strings of your own to
# print a usage message.
sub usage {
my $retval = 0;
# Keep this usage statement in sync with the getopts usage above!
# Feel free to rearrange the order and content for maximum clarity,
my $msg =
"Usage: $TOOL <option flag(s)> [ filedir [ filedir ]... ]
The options available are:
-V --verbose = be verbose (default: $verbose_dflt)
--usage = print this usage message and exit
--help = print a help message and exit
--version = print version number of this tool and exit
-M A --mailto A = send mail to 'A' with this report rather than
printing to stdout (not implemented yet)
-w X --warning X = warn if more than X% full (default: ${warn_level}%)
-d X --danger X = danger if more than X% full (default: ${danger_level}%)
-W --nowarning = supress warning messages (default: $nowarning_dflt)
-D --nodanger = supress danger messages (default: $nodanger_dflt)
$TOOL version $VERSION - send comments/bugs to scs\@umich.edu.
";
if ( @_ ) {
$retval = 1;
print STDERR "$TOOL: ";
foreach ( @_ ) {
print STDERR $_, "\n";
}
print STDERR "\n";
}
print STDERR $msg;
exit $retval;
}
sub help {
my $arg_count = scalar( @_ );
carp "$TOOL internal error: help called with args" if ( $arg_count );
my $msg =
"$TOOL: A $TOOL-specific help message has not been
defined yet. Please try
$TOOL --usage
$TOOL version $VERSION - send comments/bugs to scs\@umich.edu.
";
print STDERR $msg;
exit 0;
}
# ------------------------------------------------------------------------
# Process the options, giving immediate help/usage if requested
# ------------------------------------------------------------------------
use Getopt::Long qw(:config no_ignore_case);
my $result = GetOptions (
"verbose|V" => \$verbose, #boolean
"usage" => \$usage, #boolean
"help" => \$help, #boolean
"version" => \$version, #boolean
"perlwarn" => \$perlwarn, #boolean
"warning|w=i" => \$warn_level,
"danger|d=i" => \$danger_level,
"nowarning|W" => \$nowarning, #boolean
"nodanger|D" => \$nodanger, #boolean
"mailto=s" => \$mailto, #string
"debug=s" => \$debug #string
);
# Turn off warnings so we can process the flags
no strict;
my $oldwarning = $WARNING;
# Restore warnings if we should
use strict;
my $WARNING = $perlwarn ? $perlwarn : $oldwarning ;
usage if ( $usage );
help if ( $help );
if ( $version ) {
print "$TOOL version $VERSION\n";
exit 0;
}
if ( $verbose and ! $debug ) {
printf "%s version %s is running.\n", $TOOL, $VERSION;
}
if ( $debug ) {
printf "%s version %s is running with settings:\n", $TOOL, $VERSION;
printf " Warning level is %.2f%%, ", $warn_level ;
printf "warning notices are %s.\n", $nowarning ? "SUPRESSED" : "PRINTED" ;
printf " Danger level is %3.2f%%, ", $danger_level ;
printf "danger notices are %s.\n", $nodanger ? "SUPRESSED" : "PRINTED" ;
printf " Perl warnings are %s, ", $perlwarn ? "ON" : "OFF" ;
printf "native perl warnings are %s.\n", $WARNING ? "ON" : "OFF" ;
printf " Verbose is %s, ", $verbose ? "ON" : "OFF" ;
printf "debugging is %s.\n", $debug ? "ON" : "OFF" ;
}
# ------------------------------------------------------------------------
# Global variables
# ------------------------------------------------------------------------
my $warning_seen = 0;
my $danger_seen = 0;
my $warning_flag = " << Warning" ;
my $danger_flag = " << DANGER" ;
# Default is MB. We may want to make this a switch.
my $units = 1024 ;
# ------------------------------------------------------------------------
# Subroutines and their related variables
# ------------------------------------------------------------------------
sub commify {
my $t = reverse $_[0];
$t =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
return scalar reverse $t;
}
sub mk_flag {
my ( $pct ) = $_[0];
my $flag = "";
if ( $pct >= $danger_level ) {
$danger_seen++;
if ( ! $nodanger ) {
$flag = $danger_flag;
} else {
$flag = $warning_flag if ( ! $nowarning ) ;
}
} elsif ( $pct >= $warn_level ) {
$warning_seen++;
$flag = $warning_flag if ( ! $nowarning ) ;
}
return $flag
}
sub find_all {
my ( @list, $line, $pct, @servers ) ;
my ( $server, $servname, $partition, $size, $free, $used );
my ( $gtot_free, $gtot_used, $gtot_size ) = 0;
my ( $stot_free, $stot_used, $stot_size ) = 0;
# Get all the server names, but only once.
open( FSDATA, "vos listaddrs -noauth |" );
while ( $server = <FSDATA> ) {
chomp $server;
# I'm not thrilled with this, but it works for us
next if $server !~ /^afs/;
$server =~ s/\..*$//; # Shorten server names
push @servers, $server;
}
close FSDATA;
printf "%-6.6s %-3s %11s %11s %11s %8s\n",
"Server", "Ptn", "SizeMB", "Used", "Avail.", "Pct Full";
printf "%-6.6s %3s %11s %11s %11s %8s\n",
"="x6, '='x3, '='x11,'='x11, '='x11, '='x8;
# For each server, get disk usage and format it properly
for $server ( sort @servers ) {
my @fsdata;
$servname = $server;
$stot_free = $stot_used = $stot_size = 0;
open( FSDATA, "vos partinfo -server $server -noauth |" );
@fsdata = ( <FSDATA> );
foreach $line ( @fsdata ) {
chomp $line;
@list = split /[ :]/, $line ;
$partition = $list[4];
$partition =~ s/^\/vicep//;
$size = $list[12];
$free = $list[6];
$used = $size - $free;
$pct = ( $used / $size ) * 100 ;
printf "%-6.6s %-1s %11s %11s %11s %7.2f%%%s\n",
$servname, $partition, commify( int( $size / $units ) ),
commify( int( $used / $units ) ),
commify( int( $free / $units ) ),
$pct, mk_flag( $pct );
# Uncomment next line to supress repeated server names
#$servname = "";
$stot_free += $free;
$stot_used += $used;
$stot_size += $size;
$gtot_free += $free;
$gtot_used += $used;
$gtot_size += $size;
}
#print "\$stot_size is '$stot_size'\n";
# DB servers are servers, but may have no disk.
next if ( 0 == $stot_size );
$pct = ( $stot_used / $stot_size ) * 100;
# We should make a switch to turn subtotaling on and off
#printf "%-10.10s %-8s %11s %11s %11s %7.2f%%%s\n\n",
# " Subtotal", "", commify( int( $stot_size / $units ) ),
# commify( int( $stot_used / $units ) ),
# commify( int( $stot_free / $units ) ),
# $pct, mk_flag( $pct ) ;
}
if ( 0 == $gtot_size ) {
$pct = 0;
} else {
$pct = ( $gtot_used / $gtot_size ) * 100;
}
printf "%-11.11s %11s %11s %11s %8s\n",
"="x11, '='x11,'='x11, '='x11, '='x8;
printf "%-11.11s %11s %11s %11s %7.2f%%%s\n",
"Grand Total", commify( int( $gtot_size / $units ) ),
commify( int( $gtot_used / $units ) ),
commify( int( $gtot_free / $units ) ),
$pct, mk_flag( $pct ) ;
close FSDATA;
if ( $verbose ) {
if ( 0 == ( $danger_seen + $warning_seen ) ){
print " No partitions are overly full.\n";
} else {
printf " %s partitions fairly full, %s are dangerously full.\n",
$warning_seen ? $warning_seen : "No",
$danger_seen ? $danger_seen : "none";
}
}
}
# ------------------------------------------------------------------------
# MAIN - everything is set, lets do real work.
# ------------------------------------------------------------------------
find_all();
exit 0;
--Apple-Mail-1-351683513--