#!/usr/pkg/bin/perl
#
# Developed 05/28/2003 by Mike Discenza
# mike.discenza@dillards.com
#
#Important Note:
#       This script uses /usr/bin/svmon to monitor
#       memory usage.  svmon can only be executed by
#       root, so you must either setup an sudo, or run
#       munin-node as root for this to work right.
#
#
# Plugin to monitor memory usage on AIX.
#
#   DESCRIPTION
#   ===========
#      This will report back the amount of memory currently in use,
#      pages pinned in memory, the amount of free memory, and the amount
#      of swap space being used.  It uses /usr/bin/svmon,
#      /usr/sbin/lsps, and /usr/sbin/lsattr.
#      
#   RESTRICTIONS
#   ============
#      /usr/bin/svmon can only be executed by root.  You will either
#      have to run the munin-node as root, or set up an sudo for this
#      script.  The other commands (lsps, lsattr) should be executable
#      by everyone be defualt.
#
# Parameters:
#
# 	config   (required)
# 	autoconf (optional - only used by munin-config)
#
# Magic markers (optional - only used by munin-config and some
# installation scripts):
#%# family=contrib
#%# capabilities=autoconf


use strict;
use POSIX;

my($arg) = shift;

if($arg eq "autoconf")
  {
    if(-e "/usr/bin/svmon" && -X "/usr/bin/svmon")
      {
        print "yes\n";
        exit 0;
      }
    else
      {
        print "no\n";
        exit 1;
      }
  }
  
if($arg eq "config")
  {
    print "graph_args --base 1024 -l 0 --vertical-label Bytes --upper-limit ".getTotalMemBytes()."\n";
    print "graph_title Memory usage\n";
    print "graph_order inuse free pinned swap\n";
    print "inuse.label inuse\n";
    print "inuse.draw AREA\n";
    print "free.label free\n";
    print "free.draw STACK\n";
    print "pinned.label pinned\n";
    print "pinned.draw STACK\n";
    print "swap.label swap\n";
    print "swap.draw STACK\n";
    exit 0
  }

my($totalSwap,$swapUsed) = getSwapSpace();
my($inUse,$free,$pinned) = findMemoryUsage();

print "swap.value $swapUsed\ninuse.value $inUse\nfree.value $free\npinned.value $pinned\n";
  
sub getTotalMemBytes
{
  my($line,@memInfo,$item,$totalMem);
  open MEMLINE, "/usr/sbin/lsattr -El mem0|";
  while($line = <MEMLINE>)
    {
      @memInfo = split(/ +/,$line);
      if(lc($memInfo[0]) eq "size")
        {$totalMem = $memInfo[1];}
    }
  my($memInBytes) = ($totalMem * 1024) * 1024;
  return $memInBytes;
}

sub printArray
{
  my($array,$spacer,$useNums,@labels) = @_;
  my($item,);
  my($count) = 0;

  foreach $item (@{$array})
    {
      if($useNums == 1)
        {print $count.substr($spacer,0,length($spacer)-length($count)).$item."\n";}
      else
        {print $labels[$count].substr($spacer,0,length($spacer)-length($labels[$count])).$item."\n";}
      $count++;
    }
}

sub getSwapSpace
{
  my($line,@lineArray,$amountUsed,$totalSpace);
  open SWAPINFO, "/usr/sbin/lsps -a|tail +2|";
  while($line = <SWAPINFO>)
    {
      @lineArray = split(/ +/,$line);
      $totalSpace += (substr($lineArray[3],0,-2) * 1024) * 1024;
      $amountUsed += ((substr($lineArray[3],0,-2) * ($lineArray[4]/100)) * 1024) * 1024;
    }
  return (ceil($totalSpace),ceil($amountUsed));
}

sub findMemoryUsage
{
  my($line,@lineArray);
  my($inUse,$free,$pinned);
  open MEMINFO, "/usr/bin/svmon -G|tail +2|";
  while($line = <MEMINFO>)
    {
      @lineArray = split(/ +/,$line);
      if(lc($lineArray[0]) eq 'memory')
        {
          $inUse = ($lineArray[2] * 4) * 1024;
          $free = ($lineArray[3] * 4) * 1024;
          $pinned = ($lineArray[4] * 4) * 1024;
        }
    }
  return ($inUse,$free,$pinned);
}
