[OpenAFS] Add new fileserver

Steve Simmons scs@umich.edu
Fri, 13 Apr 2007 18:20:15 -0400


--Apple-Mail-5-627119848
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	delsp=yes;
	format=flowed


On Apr 12, 2007, at 10:19 AM, chas williams - CONTRACTOR wrote:

> In message <F411512C-1517-4702-BB5B-6F4015C16965@umich.edu>,Steve  
> Simmons write
> s:
>> You also comment that multihomed cells would be listed more than
>> once. Yes, uniq-ifying them would be good. Can you point me at a cell
>> to test against?
>
> yeah, i said unique but after thinking about it, there is no  
> requirement
> that the reverse addresses of the servers have to be the same  
> (although
> since we run krb it is a requirement here).  i think using - 
> printuuid might
> be the right solution.
>
> 	% vos listaddrs -printuuid -noresolve
> 	UUID: 009796ae-b44b-1290-94-25-460acf86aa77
> 	134.207.10.70
> 	134.207.12.70
...

Nice. Update version attached. This weeds multi-homed hosts to a  
single ref, allows cell to be specified on command line.

Anybody who uses this - if you get long pauses, you've got old (dead)  
fileservers left in your list. Do 'vos changeaddr <name> -remove' to  
each, and this'll run really fast. For the 18-odd umich servers it  
takes under a second. Otherwise you get about 60 seconds hang per  
down server.

Steve


--Apple-Mail-5-627119848
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
	x-unix-mode=0555;
	name=afsdf
Content-Disposition: attachment;
	filename=afsdf

#!/usr/bin/perl -w

#-----------------------------------------------------------------------------
# $Id: afsdf,v 1.14 2007/04/13 22:08:02 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.Reports/RCS/afsdf,v $
#
# $Log: afsdf,v $
# Revision 1.14  2007/04/13 22:08:02  scs
# Added cell switch, better variable initialization for totals. Made
# user we only fetch one server even if it has multiple addresses.
#
# Revision 1.13  2006/01/11 19:05:12  scs
# Make width of server name dynamic, allow for cell specification.
#
# 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.
#
#
# 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
    $cell,				# Choose what cell to list
);

# 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";
$cell = "";

# 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.14 $';
$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)
  -c    --cell name    = select what cell to list (default: your local cell)

$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
	"cell|c=s"	=> \$cell		#string
);

my $srv_width = length( "Grand Total" );;

# 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" ;
    printf" cell to use: ", "" eq $cell ? "local" : "$cell";
}
$cell = "-cell $cell" if "" ne $cell;

# ------------------------------------------------------------------------
# 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, 0, 0);
    my ( $stot_free, $stot_used, $stot_size ) = ( 0, 0, 0);
    my ( $longname );

    # Get all the server names, but only once.

    open( FSDATA, "vos listaddrs -printuuid $cell -noauth |" );
    while ( $line = <FSDATA> ) {
        # Suck in one servers worth of data, keeping only first name
        if ( $line =~ /^UUID:/ ) {
	     $server = <FSDATA>;
	     chomp $server;
	     while ( "" ne $line ) {
		$line = <FSDATA>;
	     	chomp $line;
	    }
	}
	$longname = length( $server );
	# Build server name width dynamicly
	$srv_width = $longname if $longname > $srv_width;
	push @servers, $server;
    }
    close FSDATA;

    printf "%-${srv_width}.${srv_width}s  %-3s  %11s  %11s  %11s  %8s\n",
	"Server", "Ptn", "SizeMB", "Used", "Avail.", "Pct Full";
    printf "%-${srv_width}.${srv_width}s  %3s  %11s  %11s  %11s  %8s\n",
	"="x$srv_width, '='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 $cell -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 "%-${srv_width}.${srv_width}s   %-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
	#$srv_width += 4;
	#printf "%-${srv_width}.${srv_width}s  %-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 "%${srv_width}.${srv_width}s       %11s  %11s  %11s  %8s\n",
	"="x${srv_width}, '='x11,'='x11, '='x11, '='x8;
    printf "%${srv_width}.${srv_width}s       %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-5-627119848--