]> jspc29.x-matter.uni-frankfurt.de Git - hadesicinga.git/commitdiff
added adaptec-check by C.Huhn as icinga plugin
authorhadaq <hadaq>
Tue, 7 Feb 2012 13:28:31 +0000 (13:28 +0000)
committerhadaq <hadaq>
Tue, 7 Feb 2012 13:28:31 +0000 (13:28 +0000)
plugins/adaptec-check [new file with mode: 0755]

diff --git a/plugins/adaptec-check b/plugins/adaptec-check
new file mode 100755 (executable)
index 0000000..4e5046a
--- /dev/null
@@ -0,0 +1,273 @@
+#!/usr/bin/perl
+#
+# checks the status of Adaptec-RAIDs by reading the output of 'arcconf getstatus'
+#
+# Tested with these controllers:
+#   * Adaptec 5405
+#   * Adaptec 5805
+#
+# $Id: adaptec-check,v 1.1 2012-02-07 13:28:31 hadaq Exp $
+#
+
+use strict;
+use warnings;
+
+use Parse::RecDescent;
+use Data::Dumper;
+
+$::RD_HINT = 1;
+
+my $debug = 0;
+
+my $parser = new Parse::RecDescent(q{
+    
+# returns a hash of hashes with controller info:
+#  { 'ci' => {
+#      'c_model' => 'blafasel',
+#      'c_drives' => 'n',
+#      ...
+#      },
+#    'cj' => {
+#        'c_model' => 'bliblabubb',
+#        'c_ports' => 'm',
+#        ...
+#        }
+#  }   
+  general_info: controller_num controller_info logic_dev_info phys_dev_info success_msg
+{ $return = \%item; } 
+| <error>
+
+controller_num: "Controllers found:" integer
+
+success_msg: "Command completed successfully."
+      
+controller_info: delimiter_line "Controller information" delimiter_line controller_details
+
+logic_dev_info: delimiter_line "Logical device information" delimiter_line logic_dev_details(s) | <error>
+
+
+phys_dev_info: delimiter_line /Physical device information/i delimiter_line phys_dev_details | <error>
+
+    
+delimiter_line: /-+/
+
+controller_details: c_status c_channel c_model c_serial c_slot(?) c_temp c_mem c_copyback 
+    c_bg_cons_check c_failover c_priority c_perfmode c_stayawake c_spinup_int c_spinup_ext
+    c_defunct c_logic_dev c_ssd_cache(?) c_ssd_cache_max(?) c_ncq_status(?) 
+    c_version_info c_batt_info
+{ $return = \%item; } | <error>
+    
+c_status:        "Controller Status"               ':' ( status | 'Charging' )
+c_channel:       "Channel description"             ':' "SAS/SATA"
+c_model:         "Controller Model"                ':' "Adaptec" ("5405" | "5805")
+c_serial:        "Controller Serial Number"        ':' serial
+c_slot:          "Physical Slot"                   ':' integer
+c_temp:          "Temperature"                     ':' integer "C/" integer "F (Normal)" { $return = $item[3]; }
+c_mem:           "Installed memory"                ':' size
+c_copyback:      "Copyback"                        ':' onoff
+c_bg_cons_check: "Background consistency check"    ':' onoff
+c_failover:      "Automatic Failover"              ':' onoff
+c_priority:      "Global task priority"            ':' "High"
+c_perfmode:      "Performance Mode"                ':' "Default/Dynamic"
+c_stayawake:     "Stayawake period"                ':' onoff
+c_spinup_int:    "Spinup limit internal drives"    ':' integer
+c_spinup_ext:    "Spinup limit external drives"    ':' integer
+c_defunct:       "Defunct disk drive count"        ':' integer
+c_logic_dev:     "Logical devices/Failed/Degraded" ':' m|\d+/\d/\d|
+c_ssd_cache:     "SSDs assigned to MaxIQ Cache pool"        ':' integer
+c_ssd_cache_max: "Maximum SSDs allowed in MaxIQ Cache pool" ':' integer
+c_ncq_status:    "NCQ status"                      ':' onoff
+
+c_version_info: delimiter_line "Controller Version Information" delimiter_line 
+    c_version_bios c_version_firmware c_version_driver c_version_bootflash
+
+c_version_bios:      "BIOS"       ':' version                                   
+c_version_firmware:  "Firmware"   ':' version 
+c_version_driver:    "Driver"     ':' version  
+c_version_bootflash: "Boot Flash" ':' version
+
+# battery might be installed or not 
+c_batt_info: delimiter_line "Controller Battery Information" delimiter_line 
+    c_batt_status (c_batt_over_temp c_batt_capacity c_batt_time_remain)(?) { $return = \%item; }
+
+c_batt_status:      "Status"                           ':' ( status | "Charging" )  { $return = $item[3]; }
+c_batt_over_temp:   "Over temperature"                 ':' yesno
+c_batt_capacity:    "Capacity remaining"               ':' integer "percent" { $return = $item[3]; }
+c_batt_time_remain: "Time remaining (at current draw)" ':' integer "days," integer "hours," integer "minutes" 
+{ $return = (((($item[3]*24) + $item[5]) * 60) + $item[7])."m"; } # calculate time in minutes
+
+#
+# logical device info section
+#
+
+logic_dev_details: l_devnum l_name l_raidlevel l_status l_size l_stripe(?) l_readcache_mode 
+    l_maxiq_pref(?) l_maxiq(?) l_writecache_mode l_writecache_setting 
+    l_partitioned l_hotspare_protect l_hotspare_global(?) l_bootable l_stripes_failed
+    l_power l_power_slow(?) l_power_off(?) l_power_verify(?) l_power_state(?)
+    l_segment_info
+{ $return = \%item; } | <error>
+
+
+l_segment_info: delimiter_line "Logical device segment information" delimiter_line l_segment_details(s) | <error>
+
+
+l_devnum:             "Logical device number" integer
+
+# name might be empty, therefore we look for the next newline:
+l_name:               "Logical device name"      ':' <skip:'[ \t]*'>/.*\n/ 
+{ $return = $item[4]; chomp $return } # cut off the trailing newline
+
+l_raidlevel:          "RAID level"               ':' raidlevel
+l_status:             "Status of logical device" ':' status
+l_size:               "Size"                     ':' size
+l_stripe:             "Stripe-unit size"         ':' size
+l_readcache_mode:     "Read-cache mode"          ':' onoff
+l_maxiq_pref:         "MaxIQ preferred cache setting" ':' onoff
+l_maxiq:              "MaxIQ cache setting"      ':' onoff
+l_writecache_mode:    "Write-cache mode"         ':' writecache
+l_writecache_setting: "Write-cache setting"      ':' writecache
+l_partitioned:        "Partitioned"              ':' yesno
+l_hotspare_protect:   "Protected by Hot-Spare"   ':' yesno
+l_hotspare_global:    "Global Hot-Spare"         ':' /\d,\d+/
+l_bootable:           "Bootable"                 ':' yesno
+l_stripes_failed:     "Failed stripes"           ':' yesno
+l_power:              "Power settings"           ':' onoff
+l_power_slow:         "Slow down after(Minutes)" ':' time
+l_power_off:          "Power off after(Minutes)" ':' time
+l_power_verify:       "Verify after(Hours)"      ':' time
+l_power_state:        "Power State"              ':' ("Active" | "Standby" | "Powered Off")
+
+
+l_segment_details: "Segment" integer ':' l_segment_status l_segment_pos <skip:'[ \t]*'>disk_serial(?) { $return = \%item; }
+l_segment_status:  'Inconsistent' | "Present" | "Rebuilding" | "Spare"
+l_segment_pos:     /\(\d,\d+\)/
+
+
+phys_dev_details: p_hd_details(s) p_service_details { $return = \%item; } | <error>
+
+p_hd_details: p_devnum p_type p_state p_supported p_speed(?) p_channel (p_location p_esd)(?) p_vendor
+    p_model p_firmware p_serial(?) p_size p_writecache p_fru p_smart p_smartwarn (p_pwrstate 
+    p_pwrstates p_ssd(?) p_maxiq_capable(?) p_maxiq(?) p_ncq)(?) { $return = \%item; } | <error>
+
+p_service_details: p_devnum p_type p_channel p_enclosure p_esd_type p_vendor p_model p_firmware 
+    p_esd_status p_fan_status(s?) p_psu_status(s?) p_temp  { $return = \%item; } | <error>
+
+p_devnum:     "Device" /\#\d+/
+p_type:       "Device is" /an?/ ("Hard drive" | "Enclosure services device" )
+p_state:      "State"                        ':' ( 'Failed' | "Hot Spare" | 'Online' 
+                                                   | 'Ready' | 'Rebuilding' )
+p_supported:  "Supported"                    ':' yesno
+p_speed:      "Transfer Speed"               ':' "SATA" float "Gb/s" { $return = $item[4]; }
+p_channel:    "Reported Channel,Device(T:L)" ':' logic_loc
+p_location:   "Reported Location"            ':' "Enclosure" /\d,/ "Slot" /\d+/
+p_esd:        "Reported ESD(T:L)"            ':' logic_loc
+p_vendor:     "Vendor"                       ':' ( "Hitachi" | "LSI CORP" | "LSILOGIC" 
+                                                   | "WDC" | '*MISSING*' )(?)
+p_model:      "Model"                        ':' ( hd_model | /SASX36 A\.[01]/ | "SAS2X36" )(?)
+p_firmware:   "Firmware"                     ':' ( /\d+\.\d+([A-Z]\d+)?/ | "SN06" 
+                                                   | "JKAOA28A" | integer )(?)
+p_serial:     "Serial number"                ':' disk_serial
+p_size:       "Size"                         ':' size
+p_writecache: "Write Cache"                  ':' writecache
+p_fru:        "FRU"                          ':' "None"
+p_smart:      "S.M.A.R.T."                   ':' yesno
+p_smartwarn:  "S.M.A.R.T. warnings"          ':' integer
+p_pwrstate:   "Power State"                  ':' ("Full rpm" | "Powered off")
+p_pwrstates:  "Supported Power States"       ':' /Full rpm,Powered off(,Reduced rpm)?/
+p_ssd:        "SSD"                          ':' yesno
+p_maxiq_capable: "MaxIQ Cache Capable"       ':' yesno
+p_maxiq:      "MaxIQ Cache Assigned"         ':' yesno
+p_ncq:        "NCQ status"                   ':' onoff
+
+p_enclosure:  "Enclosure ID" ':' integer
+p_esd_type:   "Type"         ':' "SES2"
+p_esd_status: "Status of Enclosure services device"
+p_fan_status: "Fan" integer "status" ':' ('Unknown' | 'Critical' | 'Not available' )
+p_psu_status: "Power supply" integer "status" ':' 'Unknown'
+p_temp:       "Temperature"          ':' ('Abnormal' | 'Normal')
+
+
+integer:    /-?\d+/
+logic_loc:  /\d,\d+\(\d+:\d\)/
+raidlevel:  "0" | "1" | "6 Reed-Solomon" | "Simple_volume"
+
+hd_model:  /WD\d+[A-Z]+-\d/ | /ST\d{6,9}[AN]S/ | "HUA722020ALA330"
+
+size:       integer /[KM]B/ { $return = join(' ',@item) }
+status:     "Optimal" | "Impacted" | "Not Installed" | "Failed" | "Suboptimal, Fault Tolerant" | <error>
+string:     /\S+/
+undef:      '-'
+version:    /\d\.\d-\d/ /\(\d+\)/
+writecache: /Enabled \(write-back\)( when protected by battery(\/ZMM)?)?/ | 'Disabled (write-through)' | 'Unknown'
+
+float:  /\d+\.\d+/
+onoff: /on/i | /off/i | /enabled/i | /disabled/i | undef
+yesno: /yes/i | /no/i
+date: /\d{2}-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-\d{4}/ | 'xx-xxx-xxxx'
+time: /\d+[hm]/
+
+serial: /[0-9A-F]{11}/
+
+disk_size: float 'GB' { $return = "$item[1]" }| undef
+disk_blocks: integer | undef
+disk_serial: string | undef { $return = 'Unknown' }
+
+});
+
+
+
+#### execute command and parse output
+
+
+my $cmd   = "arcconf getconfig 1";
+my $input = `$cmd`;
+
+exit 42 if $input =~ /No controller found/;
+
+my $info = $parser->general_info(\$input);
+
+if ($input =~ /\S/) {
+    print STDERR "Unparsed remainder of '$cmd':\n$input\n";
+}
+
+print Dumper($info) if $debug;
+
+my $c_status = $info->{'controller_info'}->{'c_status'};
+
+# check for controller status:
+if ( $c_status ne "Optimal") {
+    print STDERR "Controller status: '$c_status'\n";
+}
+
+# check for battery status:
+my $c_batt_status = $info->{'controller_info'}->{'c_batt_info'}->{'c_batt_status'};
+
+if ( $c_batt_status !~ /Optimal|Charging/ ) {
+    print STDERR "Controller battery status: '$c_batt_status'\n";
+}
+
+foreach my $u (@{$info->{'logic_dev_info'}}) {
+    if ($u->{'l_status'} ne "Optimal") {
+    print STDERR "Unit $u->{'l_devnum'} ('$u->{'l_name'}') status is $u->{'l_status'}\n";
+}
+
+foreach my $p (@{$u->{'l_segment_info'}}) {
+    if ($p->{'l_segment_status'} !~ /Present|Spare/ ) {
+        print STDERR "Unit $u->{'l_devnum'} ('$u->{'l_name'}'), segment $p->{'l_segment_pos'} status is $p->{'l_segment_status'}\n";
+    }
+
+}
+
+foreach my $p (@{$info->{'phys_dev_info'}->{'p_hd_details(s)'}}) {
+
+    print "$p->{'p_type'} $p->{'p_devnum'} $p->{'p_state'}\n" if $debug;
+    
+    if ($p->{'p_state'} !~ /Online|Hot Spare|Ready/ ) {
+        print STDERR "$p->{'p_type'} $p->{'p_devnum'} (Serial: ".($p->{'p_serial'} or 'unknown')
+            .", Model: ".($p->{'p_model'}[0] or 'unknown').") status is '$p->{'p_state'}'.\n";
+    }
+
+    #TODO: also check for p_smart or p_smartwarn 
+}
+
+}