Subversion Repositories camp_sysinfo_client_3

Rev

Rev 157 | Rev 169 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 157 Rev 165
Line 1... Line 1...
1
#!/usr/bin/env perl
1
#!/usr/bin/env perl
2
use warnings;
2
use warnings;
3
use strict;  
3
use strict;
-
 
4
use Data::Dumper;
4
 
5
 
5
# Description: Use smartctl to get disk information
6
# Description: Use smartctl to get disk information
6
 
7
 
7
our $VERSION = '1.0';
8
our $VERSION = '2.0';
8
 
9
 
9
# R. W. Rodolico
10
# R. W. Rodolico
10
# grabs smart readings from all drives in system
11
# grabs smart readings from all drives in system
11
# note that in the case of some hardware RAID controller, will list the components of a "drive" and the drive itself,
12
# note that in the case of some hardware RAID controller, will list the components of a "drive" and the drive itself,
12
# so you may have up to twice the number of entries than you have physical drives, for example, if you have a megaraid
13
# so you may have up to twice the number of entries than you have physical drives, for example, if you have a megaraid
13
# controller where each physical drive is also a single logical drive.
14
# controller where each physical drive is also a single logical drive.
14
 
15
 
-
 
16
# find our location and use it for searching for libraries
15
BEGIN {
17
BEGIN {
16
   push @INC, shift;
18
   use FindBin;
-
 
19
   use File::Spec;
-
 
20
   use lib File::Spec->catdir($FindBin::Bin);
-
 
21
   use library;
17
}
22
}
18
 
23
 
19
use library;
24
exit 0 unless checkDate( 'm' ); # run this only on first of month
20
 
25
 
21
exit 0 unless checkDate( 'w' ); # run this only on Mondays
26
my %ignoreDriveTypes = ( # a list of drive "types" used by virtuals that we just ignore.
-
 
27
         'VBOX HARDDISK' => 1,
-
 
28
         );
22
 
29
 
23
sub trim {
-
 
24
 my $value = shift;
-
 
25
 $value =~ s/^\s+|\s+$//g;
-
 
26
 return $value;
-
 
27
}
-
 
28
 
30
 
29
sub getSmartReport {
31
sub getSmartInformationReport {
30
   my ($drive, $type) = @_;
32
   my ($drive, $type) = @_;
-
 
33
   $type = '' if ( $type =~ m/scsi/ );
31
   my @report = `smartctl -a $drive $type`;
34
   my @report = `smartctl -i $drive $type`;
32
   chomp @report;
35
   chomp @report;
-
 
36
   my %reportHash;
-
 
37
   for ( my $i = 0; $i < @report; $i++ ) {
-
 
38
      if ( $report[$i] =~ m/^(.*):(.*)$/ ) {
-
 
39
         $reportHash{$1} = trim($2);
-
 
40
      }
-
 
41
   }
-
 
42
   return \%reportHash;
-
 
43
} # getSmartInformationReport
-
 
44
 
-
 
45
sub getSmartAttributeReport {
-
 
46
   my ($drive, $type) = @_;
-
 
47
   $type = '' if ( $type =~ m/scsi/ );
-
 
48
   my @report = `smartctl -A $drive $type`;
-
 
49
   chomp @report;
-
 
50
   my %reportHash;
-
 
51
   my %headers;
-
 
52
   # bypass all the header information
-
 
53
   my $i;
-
 
54
   for ( $i = 0; $i < @report && $report[$i] !~ m/^ID#/; $i++ ) {}
-
 
55
   if ( $i < @report ) { # did we get an actual report? some drives will not give us one
-
 
56
      my $char = 0;
-
 
57
      while ( $char < length($report[$i]) ) {
-
 
58
         substr( $report[$i],$char ) =~ m/^([^ ]+\s*)/;
-
 
59
         my $header = $1;
-
 
60
         my $start = $char;
-
 
61
         my $length = length($header);
-
 
62
         if ( $header = &trim( $header ) ) {
-
 
63
            $headers{$header}{'start'} = $start;
-
 
64
            $headers{$header}{'length'} = $length-1;
-
 
65
         }
-
 
66
         $char += $length;
-
 
67
      }
-
 
68
      while ( ++$i < @report ) {
-
 
69
         last unless $report[$i];
-
 
70
         my $id = &trim(substr( $report[$i], $headers{'ID#'}{'start'}, $headers{'ID#'}{'length'} ));
-
 
71
         my $name = &trim(substr( $report[$i], $headers{'ATTRIBUTE_NAME'}{'start'}, $headers{'ATTRIBUTE_NAME'}{'length'} ));
-
 
72
         my $value = &trim(substr( $report[$i], $headers{'RAW_VALUE'}{'start'} ));
-
 
73
         $reportHash{$id}{'value'} = $value;
-
 
74
         $reportHash{$id}{'name'} = $name;
-
 
75
      }
-
 
76
   }
-
 
77
   #print Dumper( \%reportHash ); die;
33
   return @report;
78
   return \%reportHash;
34
}
79
}
35
 
80
 
36
 
81
 
37
sub getTotalWrites {
82
sub getAttributes {
38
 my @report = @_;
-
 
39
 return -2 unless grep{ /(Solid State Device)|(SSD)/ } @report;
-
 
40
 my @temp = grep{ /^Sector Size:/ } @report;
83
   my ($report,$sectorSize) = @_;
41
 my $sectors = shift @temp;
84
   my %reportHash;
42
#   print "The Value is [$sectors]\n"; die;
85
   # first let's get total disk writes
43
 if ( $sectors =~ m/^Sector Size\:\s+(\d+)\s+bytes/ ) {
86
   if ( defined( $report->{'241'} ) ) {
44
    $sectors = $1;
87
      $sectorSize =~ m/^(\d+)/;
45
    # print "Sectors is $sectors\n"; die;
88
      $reportHash{'writes'} = $report->{'241'} * $sectorSize;
46
    @temp =  grep{ /^241/ } @report;
89
   }
47
    my $lbas = $temp[0];
90
   # find total uptime
48
    if ( $lbas =~ m/(\d+)\s*$/ ) {
91
   if ( defined( $report->{'9'} ) ) {
49
       $lbas = $1;
-
 
50
       return $lbas * $sectors;
92
      $report->{'9'}->{'value'} =~ m/^(\d+)/;
51
    } else {
-
 
52
       return -3;
93
      $reportHash{'uptime'} = $1;
53
    }
94
   }
54
 } else { 
-
 
55
    return -4; 
95
   return \%reportHash;
56
 }
-
 
57
 return -1; # we could not find something
-
 
58
}
96
}
59
 
97
 
60
sub getInformation {
98
sub getInformation {
61
   my @report = @_;
99
   my $report = shift;
62
   my %info;
100
   my %info;
63
   my %keys = ( 
101
   my %keys = ( 
64
                  'Model Family:'  => { 
102
                  'Model Family'  => { 
65
                                          'tag' => 'Make',
103
                                          'tag' => 'Make',
66
                                          'regex' => '(.*)'
104
                                          'regex' => '(.*)'
67
                                      },
105
                                      },
68
                  'Device Model:'  => { 
106
                  'Device Model'  => { 
69
                                          'tag' => 'Model',
107
                                          'tag' => 'Model',
70
                                          'regex' => '(.*)'
108
                                          'regex' => '(.*)'
71
                                      },
109
                                      },
72
                  'Serial number:' => { 
110
                  'Serial number' => { 
73
                                          'tag' => 'Serial',
111
                                          'tag' => 'Serial',
74
                                          'regex' => '(.*)'
112
                                          'regex' => '(.*)'
75
                                      },
113
                                      },
76
                  'Serial Number:' => { 
114
                  'Serial Number' => { 
77
                                          'tag' => 'Serial',
115
                                          'tag' => 'Serial',
78
                                          'regex' => '(.*)'
116
                                          'regex' => '(.*)'
79
                                      },
117
                                      },
80
                  'User Capacity:' => { 
118
                  'User Capacity' => { 
81
                                          'tag' => 'Capacity',
119
                                          'tag' => 'Capacity',
82
                                          'regex' => '([0-9,]+)'
120
                                          'regex' => '([0-9,]+)'
83
                                      },
121
                                      },
84
                  'Logical block size:' =>{ 
122
                  'Logical block size' =>{ 
85
                                          'tag' => 'Sector Size',
123
                                          'tag' => 'Sector Size',
86
                                          'regex' => '(\d+)'
124
                                          'regex' => '(\d+)'
87
                                      },
125
                                      },
88
                  'Sector Size:'   => { 
126
                  'Sector Size'   => { 
89
                                          'tag' => 'Sector Size',
127
                                          'tag' => 'Sector Size',
90
                                          'regex' => '(\d+)'
128
                                          'regex' => '(\d+)'
91
                                      },
129
                                      },
92
                  'Rotation Rate:' => { 
130
                  'Rotation Rate' => { 
93
                                          'tag' => 'Rotation',
131
                                          'tag' => 'Rotation',
94
                                          'regex' => '(.*)'
132
                                          'regex' => '(.*)'
95
                                      }
133
                                      },
96
               );
134
               );
97
   foreach my $key ( keys %keys ) {
135
   foreach my $key ( keys %keys ) {
98
      my @temp = grep { /^$key/ } @report;
-
 
99
      if ( @temp ) {
-
 
100
         $temp[0] =~ m/^$key\s+(.*)$/;
-
 
101
         my $value = $1;
-
 
102
         $value =~ m/$keys{$key}->{'regex'}/;
136
      if ( defined( $report->{$key} ) && $report->{$key} =~ m/$keys{$key}->{'regex'}/ ) {
103
         $info{$keys{$key}->{'tag'}} = $1;
137
         $info{$keys{$key}->{'tag'}} = $1;
104
      }
138
      }
105
   }
139
   }
106
   # remove comma's from capacity
140
   # remove comma's from capacity
107
   $info{'Capacity'} =~ s/,//g if $info{'Capacity'};
141
   $info{'Capacity'} =~ s/,//g if $info{'Capacity'};
Line 147... Line 181...
147
 
181
 
148
# output the drives and information as tab delimited,
182
# output the drives and information as tab delimited,
149
foreach my $thisDrive ( sort keys %allDrives ) {
183
foreach my $thisDrive ( sort keys %allDrives ) {
150
 #print "$thisDrive\n";
184
 #print "$thisDrive\n";
151
 print "$CATEGORY\t$thisDrive Type\t$allDrives{$thisDrive}\n";
185
 print "$CATEGORY\t$thisDrive Type\t$allDrives{$thisDrive}\n";
152
 my @report = &getSmartReport( $thisDrive, $allDrives{$thisDrive} );
186
 my $informationReport = &getSmartInformationReport( $thisDrive, $allDrives{$thisDrive} );
-
 
187
 my $info = &getInformation( $informationReport );
-
 
188
 # if this is not a virtual device, get smart attributes also
-
 
189
 if ( ! defined( $ignoreDriveTypes{ $info->{'Model'} } ) ) {
153
 #print join( "\n", @report ) . "\n"; die;
190
    #print Dumper( $info ); die;
-
 
191
    my $attributesReport = &getSmartAttributeReport( $thisDrive, $allDrives{$thisDrive} );
154
 my $writes = &getTotalWrites( @report );
192
    my $attributes = &getAttributes( $attributesReport, $info->{'Sector Size'} );
155
 my $info = &getInformation( @report );
193
    #print Dumper( $attributes ); die;
156
 $info->{'writes'} = $writes if $writes > 0;
194
    $info = { %$info, %$attributes };
157
 #print Dumper( $info );
195
    #print Dumper( $info ); die;
-
 
196
 }
158
 foreach my $key ( keys %$info ) {
197
 foreach my $key ( keys %$info ) {
159
    print "$CATEGORY\t$thisDrive $key\t" . $info->{$key} . "\n";
198
    print "$CATEGORY\t$thisDrive $key\t" . $info->{$key} . "\n";
160
 }
199
 }
161
}
200
}
162
 
201