#!/usr/bin/perl -w

# check_hdd_smart by Druggo 9/Sep/2010
# check S.M.A.R.T enabled disks health, especially GLIST & uncorrectable sectors
# 1. install smartmontools
# 2. smartctl --smart=on --offlineauto=on --saveauto=on /dev/something
# 3. add a line in sudoers : (note: delete this line: Defaults    requiretty)
#  nagios ALL=NOPASSWD:/usr/sbin/smartctl

use strict;
my (@hdds, $hdd);
my $smartctl = "sudo /usr/sbin/smartctl";
my $sh = 0;
my $sr = 0;
my $sp = 0;
my $su = 0;
my $out = "";
# relocated warning
my $rw = 20; 
# relocated critical
my $rc = 100;
my $pw = 10;
my $pc = 50;
my $uw = 10;
my $uc = 50;
my $argc = @ARGV;

if ( $argc gt 0 ) {
	@hdds = @ARGV;
}else {
	@hdds = </dev/sd[a-z]>;
}

foreach $hdd (@hdds) {
	next if (!-e $hdd);
	unless (open SMARTCTL,"$smartctl -a $hdd|") {
		print STDERR "Can't execute $smartctl: $!\n";
		exit(3);
	}
	my @tmp;
	my $type = '';
	while (<SMARTCTL>) {
		$type = 'ata' if (/ATA/i);
		$type = 'scsi' if (/SAS|SCSI/i);
		if ($type eq 'ata') {
			if (/SMART overall-health self-assessment test result: (\S+)/i) {
				$out .= "$hdd : $1, ";
				$sh = 1 if ($1 ne 'PASSED');
			}
			if (/5 Reallocated/i) {
				@tmp = split(/\s+/,$_);
				$out .= "reallocated : $tmp[10], ";
				$sr = 1 if ($tmp[10] > $rw);
				$sh = 1 if ($tmp[10] > $rc);
			}
			if (/197 Current/i) {
				@tmp = split(/\s+/,$_);
				$out .= "pending : $tmp[9], ";
				$sp = 1 if ($tmp[9] > $pw);
				$sh = 1 if ($tmp[9] > $pc);
			}
			if (/198 Offline/i) {
				@tmp = split(/\s+/,$_);
				$out .= "uncorrectable : $tmp[9]  ";
				$su = 1 if ($tmp[9] > $uw);
				$sh = 1 if ($tmp[9] > $uc);
			}
		}
		if ($type eq 'scsi') {
			if (/SMART Health Status: (\S+)/i) {
				$out .= "$hdd : $1, ";
				$sh = 1 if ($1 ne 'OK');
			}
			if (/Elements in grown defect list: (\S+)/i) {
				$out .= "reallocated : $1, ";
				$sr = 1 if ($1 > $rw);
				$sh = 1 if ($1 > $rc);
			}
			if (/^read:/i) {
				@tmp = split(/\s+/,$_);
				$out .= "read uncorr : $tmp[7], ";
				$su = 1 if ($tmp[7] > $uw);
				$sh = 1 if ($tmp[7] > $uc);
			}
			if (/^write:/i) {
				@tmp = split(/\s+/,$_);
				$out .= "write uncorr : $tmp[7]  ";
				$su = 1 if ($tmp[7] > $uw);
				$sh = 1 if ($tmp[7] > $uc);
			}
		}
	}
}

print $out;
exit(2) if ($sh == 1);
exit(1) if ($sr || $sp || $su);
exit(0);
