File Coverage

blib/lib/FusionInventory/Agent/Task/Inventory/HPUX/Drives.pm
Criterion Covered Total %
statement 32 60 53.3
branch 6 26 23.0
condition 0 3 0.0
subroutine 6 10 60.0
pod 0 2 0.0
total 44 101 43.5


line stmt bran cond sub pod time code
1             package FusionInventory::Agent::Task::Inventory::HPUX::Drives;
2              
3 2     2   94154339 use strict;
  2         11  
  2         89  
4 2     2   11 use warnings;
  2         19  
  2         131  
5              
6 2     2   10 use English qw(-no_match_vars);
  2         79  
  2         29  
7 2     2   3220 use POSIX qw(strftime);
  2         15161  
  2         10  
8              
9 2     2   3546 use FusionInventory::Agent::Tools;
  2         6  
  2         1977  
10              
11             sub isEnabled {
12 0     0 0 0 my (%params) = @_;
13 0 0       0 return 0 if $params{no_category}->{drive};
14             return
15 0   0     0 canRun('fstyp') &&
16             canRun('bdf');
17             }
18              
19             sub doInventory {
20 0     0 0 0 my (%params) = @_;
21              
22 0         0 my $inventory = $params{inventory};
23 0         0 my $logger = $params{logger};
24              
25             # get filesystem types
26 0         0 my @types = getAllLines(
27             command => 'fstyp -l',
28             logger => $logger
29             );
30              
31             # get filesystems for each type
32 0         0 foreach my $type (@types) {
33 0         0 foreach my $drive (_getDrives(type => $type, logger => $logger)) {
34 0         0 $inventory->addEntry(section => 'DRIVES', entry => $drive);
35             }
36             }
37             }
38              
39             sub _getDrives {
40 0     0   0 my (%params) = @_;
41              
42             my @drives = _parseBdf(
43             command => "bdf -t $params{type}", logger => $params{logger}
44 0         0 );
45              
46 0         0 foreach my $drive (@drives) {
47 0         0 $drive->{FILESYSTEM} = $params{type};
48             $drive->{CREATEDATE} = _getVxFSctime($drive->{VOLUMN}, $params{logger})
49 0 0       0 if $params{type} eq 'vxfs';
50             }
51              
52 0         0 return @drives;
53             }
54              
55             sub _parseBdf {
56 4     4   887 my $handle = getFileHandle(@_);
57 4 50       10 return unless $handle;
58              
59 4         6 my @drives;
60              
61             # skip header
62 4         52 my $line = <$handle>;
63              
64 4         6 my $device;
65 4         13 while (my $line = <$handle>) {
66 25 100       117 if ($line =~ /^(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+%)\s+(\S+)/) {
67 19         111 push @drives, {
68             VOLUMN => $1,
69             TOTAL => $2,
70             FREE => $3,
71             TYPE => $6,
72             };
73 19         77 next;
74             }
75              
76 6 100       22 if ($line =~ /^(\S+)\s/) {
77 3         8 $device = $1;
78 3         11 next;
79             }
80              
81 3 50       18 if ($line =~ /(\d+)\s+(\d+)\s+(\d+)\s+(\d+%)\s+(\S+)/) {
82 3         18 push @drives, {
83             VOLUMN => $device,
84             TOTAL => $1,
85             FREE => $3,
86             TYPE => $5,
87             };
88 3         17 next;
89             }
90             }
91 4         96 close $handle;
92              
93 4         24 return @drives;
94             }
95              
96             # get filesystem creation time by reading binary value directly on the device
97             sub _getVxFSctime {
98 0     0     my ($device, $logger) = @_;
99              
100             # compute version-dependant read offset
101              
102             # Output of 'fstyp' should be something like the following:
103             # $ fstyp -v /dev/vg00/lvol3
104             # vxfs
105             # version: 5
106             # .
107             # .
108 0           my $version = getFirstMatch(
109             command => "fstyp -v $device",
110             logger => $logger,
111             pattern => qr/^version:\s+(\d+)$/
112             );
113              
114 0 0         my $offset =
    0          
    0          
115             $version == 5 ? 8200 :
116             $version == 6 ? 8208 :
117             $version == 7 ? 8208 :
118             undef;
119              
120 0 0         if (!$offset) {
121 0           $logger->error("unable to compute offset from fstyp output ($device)");
122 0           return;
123             }
124              
125             # read value
126 0 0         open (my $handle, "<:raw:bytes", $device)
127             or die "Can't open $device in raw mode: $ERRNO";
128 0 0         seek($handle, $offset, 0)
129             or die "Can't seek offset $offset on device $device: $ERRNO";
130 0           my $raw;
131 0 0         read($handle, $raw, 4)
132             or die "Can't read 4 bytes on device $device: $ERRNO";
133 0           close($handle);
134              
135             # Convert the 4-byte raw data to long integer and
136             # return a string representation of this time stamp
137 0           return strftime("%Y/%m/%d %T", localtime(unpack('L', $raw)));
138             }
139              
140             1;