#!/usr/bin/perl
$TW="/sbin/tw_cli";

# get list of disks and put it in an array.
@Disks=();
open (PARTITIONS, "cat /proc/partitions |");
while (<PARTITIONS>) {
  $Line=$_;
  chomp $Line;
  ($junk,$junk,$junk,$junk,$Partition,$junk)=split (/ +/,$Line,6);
  if ($Partition =~ /^hd.$/ || $Partition =~ /^sd.$/ || $Partition =~ /^ide\/.*\/disc/ ) {
    push (@Disks, $Partition);
  }
}
close (PARTITIONS);

# check the disks that were found...
foreach $Disk (@Disks) {
  open (SMART, "smartctl -d ata -a /dev/$Disk || smartctl -d scsi -a /dev/$Disk |");
  while (<SMART>) {
    $Line=$_;
    chomp $Line;
    if ($Line =~ /^SMART Health Status:/ ) {
      $Status=$Line;
      $Status =~ s/.*: //g;
      $Status =~ s/OK/PASSED/g;
      $Status =~ s/FAILED!/FAILURE/g;
      print "$Disk:status:$Status\n";
    }
    if ($Line =~ /^SMART overall-health self-assessment test result:/ ) {
      $Status=$Line;
      $Status =~ s/.*: //g;
      $Status =~ s/OK/PASSED/g;
      $Status =~ s/FAILED!/FAILURE/g;
      print "$Disk:status:$Status\n";
    }
    if ($Line =~ /^Current Drive Temperature:/ ) {
      $Temp=$Line;
      $Temp =~ s/^.*(..) C$/$1/g;
      print "$Disk:temp:$Temp\n";
    }
    if ($Line =~ /^read:/) {
      @Data=split (/ /,$Line);
      foreach $Field (@Data) {
        $Num=$Field;
      }
      print "$Disk:read-errors:$Num\n";
    }
    if ($Line =~ /^write:/) {
      @Data=split (/ /,$Line);
      foreach $Field (@Data) {
        $Num=$Field;
      }
      print "$Disk:write-errors:$Num\n";
    }
    if ($Line =~ /^198 /) {
      @Data=split (/ /,$Line);
      foreach $Field (@Data) {
        $Num=$Field;
      }
      print "$Disk:disk-errors:$Num\n";
    }
    if ($Line =~ /^194 /) {
      #@Data=split (/ /,$Line);
      #foreach $Field (@Data) {
      #  $Num=$Field;
      #}
      ($junk,$junk,$junk,$junk,$junk,$junk,$junk,$junk,$junk,$Num,$junk)=split (/ +/,$Line,11);
      print "$Disk:temp:$Num\n";
    }
    if ($Line =~ /^  5/) {
      $Line =~ s/^ +//;
      @Data=split (/ +/,$Line);
      ($junk,$FieldName,$junk,$junk,$junk,$junk,$junk,$junk,$State,$FieldValue)=@Data;
      if ($State eq "-") {
        $State="PASSED";
      }
      print "$Disk:relocate-count:$FieldValue($State)\n";
    }

  }
  close (SMART);
}

if (-e "/dev/twe0") {
  # figure out what the 3Ware controller number is.  This is needed because they don't
  # always start at 0 for some reason and there may be more than 1.
  @Controllers=();
  open (EW, "$TW info |");
  while (<EW>) {
    $Line=$_;
    if ($Line =~ /^c/) {
      ($Controller,$Junk)=split (/ +/,$Line,2);
      push (@Controllers,$Controller);
    }
  }
  close (EW);

  # check each drive on each 3Ware controller...
  @Ports=();
  foreach $Controller (@Controllers) {
    open (EW, "$TW info $Controller |");
    while (<EW>) {
      $Line=$_;
      chomp $Line;
      if ($Line =~ /^p/ && $Line !~ /NOT-PRESENT/) {
        ($Port,$Junk)=split (/ +/,$Line,2);
        push (@Ports, "$Controller $Port");
      }
    }
    close (EW);
  }

  # Hit each port on each controller...
  foreach $Port (@Ports) {
    $ControllerNum=$Port;
    $ControllerNum =~ s/^.//;
    $ControllerNum =~ s/ .*$//;
    $PortNum=$Port;
    $PortNum =~ s/^....//;
    $Port =~ s/ //;
    open (SMART, "smartctl -a -d 3ware,$PortNum /dev/twe$ControllerNum |");
    while (<SMART>) {
      $Line=$_;
      chomp ($Line);
      if ($Line =~ /^SMART Health Status:/ ) {
        $Status=$Line;
        $Status =~ s/.*: //g;
        $Status =~ s/OK/PASSED/g;
        $Status =~ s/FAILED!/FAILURE/g;
        print "$Port:status:$Status\n";
      }
      if ($Line =~ /^SMART overall-health self-assessment test result:/ ) {
        $Status=$Line;
        $Status =~ s/.*: //g;
        $Status =~ s/OK/PASSED/g;
        $Status =~ s/FAILED!/FAILURE/g;
        print "$Port:status:$Status\n";
      }
      if ($Line =~ /^Current Drive Temperature:/ ) {
        $Temp=$Line;
        $Temp =~ s/^.*(..) C$/$1/g;
        print "$Port:temp:$Temp\n";
      }
      if ($Line =~ /^read:/) {
        @Data=split (/ /,$Line);
        foreach $Field (@Data) {
          $Num=$Field;
        }
        print "$Port:read-errors:$Num\n";
      }
      if ($Line =~ /^write:/) {
        @Data=split (/ /,$Line);
        foreach $Field (@Data) {
          $Num=$Field;
        }
        print "$Port:write-errors:$Num\n";
      }
      if ($Line =~ /^198 /) {
        @Data=split (/ /,$Line);
        foreach $Field (@Data) {
          $Num=$Field;
        }
        print "$Port:disk-errors:$Num\n";
      }
      if ($Line =~ /^194 /) {
        #@Data=split (/ /,$Line);
        #foreach $Field (@Data) {
        #  $Num=$Field;
        #}
        ($junk,$junk,$junk,$junk,$junk,$junk,$junk,$junk,$junk,$Num,$junk)=split (/ +/,$Line,11);
        print "$Port:temp:$Num\n";
      }
      if ($Line =~ /^  5/) {
        $Line =~ s/^ +//;
        @Data=split (/ +/,$Line);
        ($junk,$FieldName,$junk,$junk,$junk,$junk,$junk,$junk,$State,$FieldValue)=@Data;
        if ($State eq "-") {
          $State="PASSED";
        }
        print "$Port:relocate-count:$FieldValue($State)\n";
      }
    }
    close (SMART);
  }
}