Subversion Repositories camp_sysinfo_client_3

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
152 rodolico 1
#!/usr/bin/env perl
2
use warnings;
3
use strict;  
4
 
5
# Description: Use smartctl to get disk information
6
 
7
our $VERSION = '1.0';
8
 
9
# R. W. Rodolico
10
# grabs smart readings from all drives in system
157 rodolico 11
# 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
# controller where each physical drive is also a single logical drive.
152 rodolico 14
 
15
BEGIN {
16
   push @INC, shift;
17
}
18
 
19
use library;
20
 
21
exit 0 unless checkDate( 'w' ); # run this only on Mondays
22
 
23
sub trim {
24
 my $value = shift;
25
 $value =~ s/^\s+|\s+$//g;
26
 return $value;
27
}
28
 
29
sub getSmartReport {
157 rodolico 30
   my ($drive, $type) = @_;
31
   my @report = `smartctl -a $drive $type`;
32
   chomp @report;
152 rodolico 33
   return @report;
34
}
35
 
36
 
37
sub getTotalWrites {
38
 my @report = @_;
39
 return -2 unless grep{ /(Solid State Device)|(SSD)/ } @report;
40
 my @temp = grep{ /^Sector Size:/ } @report;
41
 my $sectors = shift @temp;
42
#   print "The Value is [$sectors]\n"; die;
43
 if ( $sectors =~ m/^Sector Size\:\s+(\d+)\s+bytes/ ) {
44
    $sectors = $1;
45
    # print "Sectors is $sectors\n"; die;
46
    @temp =  grep{ /^241/ } @report;
47
    my $lbas = $temp[0];
48
    if ( $lbas =~ m/(\d+)\s*$/ ) {
49
       $lbas = $1;
50
       return $lbas * $sectors;
51
    } else {
52
       return -3;
53
    }
54
 } else { 
55
    return -4; 
56
 }
57
 return -1; # we could not find something
58
}
59
 
60
sub getInformation {
61
   my @report = @_;
62
   my %info;
63
   my %keys = ( 
64
                  'Model Family:'  => { 
65
                                          'tag' => 'Make',
66
                                          'regex' => '(.*)'
67
                                      },
68
                  'Device Model:'  => { 
69
                                          'tag' => 'Model',
70
                                          'regex' => '(.*)'
71
                                      },
157 rodolico 72
                  'Serial number:' => { 
73
                                          'tag' => 'Serial',
74
                                          'regex' => '(.*)'
75
                                      },
152 rodolico 76
                  'Serial Number:' => { 
77
                                          'tag' => 'Serial',
78
                                          'regex' => '(.*)'
79
                                      },
80
                  'User Capacity:' => { 
81
                                          'tag' => 'Capacity',
82
                                          'regex' => '([0-9,]+)'
83
                                      },
157 rodolico 84
                  'Logical block size:' =>{ 
85
                                          'tag' => 'Sector Size',
86
                                          'regex' => '(\d+)'
87
                                      },
152 rodolico 88
                  'Sector Size:'   => { 
89
                                          'tag' => 'Sector Size',
90
                                          'regex' => '(\d+)'
91
                                      },
92
                  'Rotation Rate:' => { 
93
                                          'tag' => 'Rotation',
94
                                          'regex' => '(.*)'
95
                                      }
96
               );
97
   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'}/;
103
         $info{$keys{$key}->{'tag'}} = $1;
104
      }
105
   }
106
   # remove comma's from capacity
107
   $info{'Capacity'} =~ s/,//g if $info{'Capacity'};
108
   return \%info;
109
}
110
 
111
 
112
 
113
# category we will use for all values found
114
# see sysinfo for a list of valid categories
157 rodolico 115
my $CATEGORY = 'attributes';
152 rodolico 116
 
117
# run the commands necessary to do whatever you want to do
118
# The library entered above has some helper routines
119
# validCommandOnSystem -- passed a name, returns the fully qualified path or '' if it does not exist
120
# cleanUp - passed a delimiter and a string, does the following (delimiter can be '')
121
#           chomps the string (removes trailing newlines)
122
#           removes all text BEFORE the delimiter, the delimiter, and any whitespace
123
#           thus, the string 'xxI Am x  a weird string' with a newline will become
124
#           'a weird string' with no newline
125
 
126
# now, return the tab delimited output (to STDOUT). $CATEGORY is the first
127
# item, name as recognized by sysinfo is the second and the value is
128
# the last one. For multiple entries, place on separate lines (ie, newline separated)
129
 
130
# check for commands we want to run
131
my %commands = ( 
132
                  'smartctl' => '',
133
               );
134
 
135
# check the commands for validity
136
foreach my $command ( keys %commands ) {
137
   $commands{$command} = &validCommandOnSystem( $command );
138
}
139
 
140
# bail if we don't have the commands we need
157 rodolico 141
exit 1 unless $commands{'smartctl'};
152 rodolico 142
 
143
# Get all the drives on the system
157 rodolico 144
my %allDrives = map { $_ =~ '(^[a-z0-9/]+)\s+(.*)\#'; ($1,$2) } `smartctl --scan`;
152 rodolico 145
 
157 rodolico 146
#foreach my $key ( keys %allDrives ) { print "$key\t$allDrives{$key}\n"; } die;
152 rodolico 147
 
148
# output the drives and information as tab delimited,
149
foreach my $thisDrive ( sort keys %allDrives ) {
153 rodolico 150
 #print "$thisDrive\n";
157 rodolico 151
 print "$CATEGORY\t$thisDrive Type\t$allDrives{$thisDrive}\n";
152
 my @report = &getSmartReport( $thisDrive, $allDrives{$thisDrive} );
153
 #print join( "\n", @report ) . "\n"; die;
152 rodolico 154
 my $writes = &getTotalWrites( @report );
155
 my $info = &getInformation( @report );
156
 $info->{'writes'} = $writes if $writes > 0;
157
 #print Dumper( $info );
158
 foreach my $key ( keys %$info ) {
159
    print "$CATEGORY\t$thisDrive $key\t" . $info->{$key} . "\n";
160
 }
161
}
162
 
163
exit 0;