#!/usr/bin/perl

###########################################################################
# Author: Vincent Andrews
# Collects stats from GPFS mmpmon to display Client node information (io_s).
###########################################################################

if [ -f /usr/bin/gmetric ]; then
gmetric_command="/usr/bin/gmetric"
else
gmetric_command="/bin/gmetric"
fi

$mmpmon_command = "/usr/lpp/mmfs/bin/mmpmon";

if ( ! -x $gmetric_command ) {
	die("Gmetric command is not executable. Exiting...");
}

if ( ! -x $mmpmon_command ) {
	die("Not a GPFS Cluster member. Exiting...");
}

# Check out the nfs_stat has below for the list of all metrics
# and their appropriate index
@which_metrics = split(/ /, "12 14 16 18 20 22 24 26");

# Where to store the last stats file
$tmp_dir_base="/var/tmp/gpfs_node_stats";

$tmp_stats_file=$tmp_dir_base . "/" . "gpfs_server_stats";
$tmp_stats_file_new=$tmp_dir_base . "/" . "gpfs_server_stats_new";
$metric_prefix = "_io_s_";

###########################################################################
# This is the order of metrics from mmpmon io_s 
###########################################################################
%gpfs_stat = (
	12 => "Bytes_Read",
	14 => "Bytes_Written",
	16 => "Open-Create_Requests",
	18 => "Close_Requests",
	20 => "App_Read_Requests",
	22 => "App_Write_Requets",
	24 => "ReadDir_Requests",
	26 => "Inode_Updates"
);

# If the tmp directory doesn't exit create it
if ( ! -d $tmp_dir_base ) {
	system("mkdir -p $tmp_dir_base");
}

###############################################################################
# We need to store a baseline with statistics. If it's not there let's dump 
# it into the file. Don't do anything else
###############################################################################
if ( ! -f $tmp_stats_file ) {
	print "Creating baseline. No output this cycle\n";
	system("/usr/lpp/mmfs/bin/mmpmon -p -i /root/node-cmd | tr -s ' ' ' ' > $tmp_stats_file");
} else {

	# Let's read in the file from the last poll
	open(OLDGPFSDSTATUS, "< $tmp_stats_file");
	
	while(<OLDGPFSDSTATUS>)
	{
		my($line) = $_;
		chomp($line);
			@old_stats = split(/ /,$line);
			last;
	}

	
	# Get the time stamp when the stats file was last modified
	$old_time = (stat $tmp_stats_file)[9];
	close(OLDGPFSDSTATUS);

	system("/usr/lpp/mmfs/bin/mmpmon -p -i /root/node-cmd | tr -s ' ' ' ' > $tmp_stats_file_new");

	open(GPFSDSTATUS, "< $tmp_stats_file_new");
	
	$new_time = time(); 
	
	while(<GPFSDSTATUS>)
	{
		my($line) = $_;
		chomp($line);
			@new_stats = split(/ /,$line);
			system("echo '$line' >  $tmp_stats_file");
			last;
	}
	
	close(GPFSDSTATUS);

       # Time difference between this poll and the last poll
        my $time_difference = $new_time - $old_time;
        if ( $time_difference < 1 ) {
                die("Time difference can't be less than 1");
        }

	# Calculate deltas and send them to ganglia
	for ( $i = 0 ; $i <= $#which_metrics; $i++ ) {
		my $metric = $which_metrics[$i];
		my $delta = $new_stats[$metric] - $old_stats[$metric];
#		print " metric=$metric  new=$new_stats[$metric] old=$old_stats[$metric] delta=$delta" ;
		my $rate = int($delta / $time_difference);

               if ( $rate < 0 ) {
                        print "Something is fishy. Rate for " . $metric . " shouldn't be negative. Perhaps counters were reset. Doing nothing";
                } else {
#			print "$gpfs_stat{$metric} = $rate / sec\n";
                      system("$gmetric_command --type=uint16  --name=$metric_prefix$gpfs_stat{$metric} --value=$rate");
#	print "$gmetric_command --type=uinit16  --name=$metric_prefix$gpfs_stat{$metric} --value=$rate";
                }
        }
}
