File Coverage

blib/lib/FusionInventory/Agent/Task/Inventory/Generic/Storages/3ware.pm
Criterion Covered Total %
statement 57 73 78.0
branch 19 32 59.3
condition 0 3 0.0
subroutine 9 11 81.8
pod 0 2 0.0
total 85 121 70.2


line stmt bran cond sub pod time code
1             package FusionInventory::Agent::Task::Inventory::Generic::Storages::3ware;
2              
3 2     2   128769097 use strict;
  2         2  
  2         61  
4 2     2   13 use warnings;
  2         3  
  2         70  
5              
6 2     2   384 use FusionInventory::Agent::Tools;
  2         2  
  2         245  
7 2     2   715 use FusionInventory::Agent::Tools::Linux;
  2         4  
  2         140  
8              
9 2     2   9 use English qw(-no_match_vars);
  2         3  
  2         12  
10              
11             # Tested on 2.6.* kernels
12             #
13             # Cards tested :
14             #
15             # 8006-2LP
16             # 9500S-4LP
17             # 9550SXU-4LP
18             # 9550SXU-8LP
19             # 9650SE-2LP
20             # 9650SE-4LPML
21             # 9650SE-8LPML
22             #
23             # AMCC/3ware CLI (version 2.00.0X.XXX)
24              
25             sub isEnabled {
26 0     0 0 0 return canRun('tw_cli');
27             }
28              
29             sub doInventory {
30 0     0 0 0 my (%params) = @_;
31              
32 0         0 my $inventory = $params{inventory};
33 0         0 my $logger = $params{logger};
34              
35 0         0 my @devices;
36              
37 0         0 foreach my $card (_getCards()) {
38 0         0 foreach my $unit (_getUnits($card)) {
39              
40             # Try do get unit's serial in order to compare it to what was found
41             # in udev db.
42             # Works only on newer cards.
43             # Allow us to associate a node to a drive : sda -> WD-WMANS1648590
44 0         0 my $sn = getFirstMatch(
45             logger => $logger,
46             command => "tw_cli info $card->{id} $unit->{id} serial",
47             pattern => qr/serial number\s=\s(\w+)/
48             );
49              
50 0         0 foreach my $port (_getPorts($card, $unit)) {
51             # Finally, getting drives' values.
52 0         0 my $storage = _getStorage($card, $port);
53              
54 0 0       0 if ($OSNAME eq 'Linux') {
55              
56 0 0       0 @devices = getDevicesFromUdev(logger => $logger) unless @devices;
57              
58 0         0 foreach my $device (@devices) {
59             # How does this work with multiple older cards
60             # where serial for units is not implemented ?
61             # Need to be tested on a system with multiple
62             # 3ware cards.
63 0 0 0     0 if (
64             $device->{SERIALNUMBER} eq 'AMCC_' . $sn ||
65             $device->{MODEL} eq 'Logical_Disk_' . $unit->{index}
66             ) {
67 0         0 $storage->{NAME} = $device->{NAME};
68             }
69             }
70             }
71              
72 0         0 $inventory->addEntry(section => 'STORAGES', entry => $storage);
73             }
74             }
75             }
76             }
77              
78              
79             sub _getCards {
80 1     1   4 my ($file) = @_;
81              
82 1         4 my $handle = getFileHandle(
83             file => $file,
84             command => "tw_cli info"
85             );
86 1 50       3 return unless $handle;
87              
88 1         1 my @cards;
89 1         8 while (my $line = <$handle>) {
90 3 100       12 next unless $line =~ /^(c\d+)\s+([\w-]+)/;
91 1         7 push @cards, { id => $1, model => $2 };
92             }
93 1         5 close $handle;
94              
95 1         6 return @cards;
96             }
97              
98             sub _getUnits {
99 1     1   2 my ($card, $file) = @_;
100              
101 1         5 my $handle = getFileHandle(
102             file => $file,
103             command => "tw_cli info $card->{id}"
104             );
105 1 50       4 return unless $handle;
106              
107 1         2 my @units;
108 1         15 while (my $line = <$handle>) {
109 3 100       11 next unless $line =~ /^(u(\d+))/;
110 1         8 push @units, { id => $1, index => $2 };
111             }
112 1         6 close $handle;
113              
114 1         5 return @units;
115             }
116              
117             sub _getPorts {
118 1     1   2 my ($card, $unit, $file) = @_;
119              
120 1         5 my $handle = getFileHandle(
121             file => $file,
122             command => "tw_cli info $card->{id} $unit->{id}"
123             );
124 1 50       3 return unless $handle;
125              
126 1         1 my @ports;
127 1         10 while (my $line = <$handle>) {
128 4 100       15 next unless $line =~ /(p\d+)/;
129 2         9 push @ports, { id => $1 };
130             }
131 1         6 close $handle;
132              
133 1         6 return @ports;
134             }
135              
136             sub _getStorage {
137 1     1   2 my ($card, $port, $file) = @_;
138              
139 1         11 my $handle = getFileHandle(
140             file => $file,
141             command =>
142             "tw_cli info $card->{id} $port->{id} model serial capacity firmware"
143             );
144 1 50       3 return unless $handle;
145              
146 1         2 my $storage;
147 1         15 while (my $line = <$handle>) {
148 4 100       20 if ($line =~ /Model\s=\s(.*)/) {
    100          
    100          
    50          
149 1         5 $storage->{MODEL} = $1;
150             } elsif ($line =~ /Serial\s=\s(.*)/) {
151 1         4 $storage->{SERIALNUMBER} = $1;
152             } elsif ($line =~ /Capacity\s=\s(\S+)\sGB.*/) {
153 1         6 $storage->{DISKSIZE} = 1024 * $1;
154             } elsif ($line =~ /Firmware Version\s=\s(.*)/) {
155 1         6 $storage->{FIRMWARE} = $1
156             }
157             }
158 1         6 close $handle;
159              
160             $storage->{MANUFACTURER} = getCanonicalManufacturer(
161             $storage->{MODEL}
162 1         4 );
163 1         2 $storage->{TYPE} = 'disk';
164              
165             # Getting description from card model, very basic
166             # and unreliable
167             # Assuming only IDE drives can be plugged in
168             # 5xxx/6xxx cards and
169             # SATA drives only to 7xxx/8xxx/9xxxx cards
170             $storage->{DESCRIPTION} =
171             $card->{model} =~ /^[56]/ ? 'IDE' :
172 1 50       5 $card->{model} =~ /^[789]/ ? 'SATA' :
    50          
173             undef;
174              
175 1         5 return $storage;
176             }
177              
178             1;