From 2c33d3703f54245026330da8af87efbafc495ed9 Mon Sep 17 00:00:00 2001 From: hadaq Date: Tue, 7 Feb 2012 13:28:31 +0000 Subject: [PATCH] added adaptec-check by C.Huhn as icinga plugin --- plugins/adaptec-check | 273 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100755 plugins/adaptec-check diff --git a/plugins/adaptec-check b/plugins/adaptec-check new file mode 100755 index 0000000..4e5046a --- /dev/null +++ b/plugins/adaptec-check @@ -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; } +| + +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) | + + +phys_dev_info: delimiter_line /Physical device information/i delimiter_line phys_dev_details | + + +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; } | + +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; } | + + +l_segment_info: delimiter_line "Logical device segment information" delimiter_line l_segment_details(s) | + + +l_devnum: "Logical device number" integer + +# name might be empty, therefore we look for the next newline: +l_name: "Logical device name" ':' /.*\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 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; } | + +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; } | + +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; } | + +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" | +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 +} + +} -- 2.43.0