inq-team/einarc — pull request #6 by elops (2014-05-30 10:03:13+00:00)
Title: FIX: arcconf physical list state

```bash
# lspci | grep -i raid
82:00.0 RAID bus controller: Adaptec AAC-RAID (rev 09)

# /var/lib/einarc/tools/adaptec_arcconf/cli getconfig 1 pd
Controllers found: 1
----------------------------------------------------------------------
Physical Device information
----------------------------------------------------------------------
Device #0
Device is a Hard drive
State : Online
Supported : Yes
Transfer Speed : SATA 3.0 Gb/s
Reported Channel,Device(T:L) : 0,8(8:0)
Reported Location : Enclosure 0, Slot 0
Reported ESD(T:L) : 2,0(0:0)
Vendor : WDC
Model : WD1003FBYX-0
Firmware : 01.01V02
Serial number : WD-WCAW31019188
Reserved Size : 538264 KB
Used Size : 953343 MB
Unused Size : 1 MB
Total Size : 953869 MB
Write Cache : Enabled (write-back)
FRU : None
S.M.A.R.T. : No
S.M.A.R.T. warnings : 0
Power State : Full rpm
Supported Power States : Full rpm,Powered off,Reduced rpm
SSD : No
MaxCache Capable : No
MaxCache Assigned : No
NCQ status : Enabled

# /var/lib/einarc/tools/adaptec_arcconf/cli getconfig 1 ld
...
Group 0, Segment 0 : Present (Controller:1,Enclosure:0,Slot:0) WD-WCAW31019188
```
In example above you can see that in order to co-relate physical and logical drive
we need to rely on 'Reported Location' rather than 'Reported Channel,Device' since
Enclosure/Slot pair (and drive Serial) seem to be only reliable keys to establish relation
between two, hence change...

```diff
--- a/lib/einarc/adaptec_arcconf.rb
+++ b/lib/einarc/adaptec_arcconf.rb
@@ -316,7 +316,7 @@ module Einarc
hdd = false
when /Device is a Hard drive/
hdd = true

- when /Reported Channel,Device\(T:L\)\s*:\s*(\d+),(\d+).*/
+ when /Reported Location\s*:\s*Enclosure\s*(\d+),\s*Slot\s*(\d+)/
```

additionally _logical_list.each_with_index was secured to prevent accessing non-existent keys
which would result with failure.

```diff
--- a/lib/einarc/adaptec_arcconf.rb
+++ b/lib/einarc/adaptec_arcconf.rb
@@ -339,12 +341,13 @@ module RAID
_logical_list.each_with_index { |l, i|
next unless l
l[:physical].each { |pd|
+ next if not @physical.has_key?(pd)
next if %w{ failed }.include?(@physical[pd][:state])
next if @physical[pd][:state] == "hotspare"
```