File Coverage

blib/lib/FusionInventory/Agent/Task/Inventory/HPUX/Drives.pm
Criterion Covered Total %
statement 15 60 25.0
branch 0 26 0.0
condition 0 3 0.0
subroutine 5 10 50.0
pod 0 2 0.0
total 20 101 19.8


line stmt bran cond sub pod time code
1             package FusionInventory::Agent::Task::Inventory::HPUX::Drives;
2              
3 1     1   70489597 use strict;
  1         6  
  1         69  
4 1     1   13 use warnings;
  1         1  
  1         72  
5              
6 1     1   4 use English qw(-no_match_vars);
  1         32  
  1         24  
7 1     1   1235 use POSIX qw(strftime);
  1         8706  
  1         5  
8              
9 1     1   1321 use FusionInventory::Agent::Tools;
  1         3  
  1         688  
10              
11             sub isEnabled {
12 0     0 0   my (%params) = @_;
13 0 0         return 0 if $params{no_category}->{drive};
14             return
15 0   0       canRun('fstyp') &&
16             canRun('bdf');
17             }
18              
19             sub doInventory {
20 0     0 0   my (%params) = @_;
21              
22 0           my $inventory = $params{inventory};
23 0           my $logger = $params{logger};
24              
25             # get filesystem types
26 0           my @types = getAllLines(
27             command => 'fstyp -l',
28             logger => $logger
29             );
30              
31             # get filesystems for each type
32 0           foreach my $type (@types) {
33 0           foreach my $drive (_getDrives(type => $type, logger => $logger)) {
34 0           $inventory->addEntry(section => 'DRIVES', entry => $drive);
35             }
36             }
37             }
38              
39             sub _getDrives {
40 0     0     my (%params) = @_;
41              
42 0           my @drives = _parseBdf(
43             command => "bdf -t $params{type}", logger => $params{logger}
44             );
45              
46 0           foreach my $drive (@drives) {
47 0           $drive->{FILESYSTEM} = $params{type};
48 0 0         $drive->{CREATEDATE} = _getVxFSctime($drive->{VOLUMN}, $params{logger})
49             if $params{type} eq 'vxfs';
50             }
51              
52 0           return @drives;
53             }
54              
55             sub _parseBdf {
56 0     0     my $handle = getFileHandle(@_);
57 0 0         return unless $handle;
58              
59 0           my @drives;
60              
61             # skip header
62 0           my $line = <$handle>;
63              
64 0           my $device;
65 0           while (my $line = <$handle>) {
66 0 0         if ($line =~ /^(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+%)\s+(\S+)/) {
67 0           push @drives, {
68             VOLUMN => $1,
69             TOTAL => $2,
70             FREE => $3,
71             TYPE => $6,
72             };
73 0           next;
74             }
75              
76 0 0         if ($line =~ /^(\S+)\s/) {
77 0           $device = $1;
78 0           next;
79             }
80              
81 0 0         if ($line =~ /(\d+)\s+(\d+)\s+(\d+)\s+(\d+%)\s+(\S+)/) {
82 0           push @drives, {
83             VOLUMN => $device,
84             TOTAL => $1,
85             FREE => $3,
86             TYPE => $5,
87             };
88 0           next;
89             }
90             }
91 0           close $handle;
92              
93 0           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;