File Coverage

blib/lib/FusionInventory/Agent/Task/Inventory/Virtualization/Vmsystem.pm
Criterion Covered Total %
statement 15 94 15.9
branch 0 80 0.0
condition 0 16 0.0
subroutine 5 9 55.5
pod 0 2 0.0
total 20 201 9.9


line stmt bran cond sub pod time code
1             package FusionInventory::Agent::Task::Inventory::Virtualization::Vmsystem;
2              
3 1     1   44169952 use strict;
  1         4  
  1         38  
4 1     1   5 use warnings;
  1         1  
  1         52  
5              
6 1     1   424 use FusionInventory::Agent::Tools;
  1         2  
  1         124  
7 1     1   550 use FusionInventory::Agent::Tools::Solaris;
  1         2  
  1         864  
8              
9             my @vmware_patterns = (
10             'VMware vmxnet virtual NIC driver',
11             'Vendor: VMware\s+Model: Virtual disk',
12             'Vendor: VMware,\s+Model: VMware Virtual ',
13             ': VMware Virtual IDE CDROM Drive'
14             );
15             my $vmware_pattern = _assemblePatterns(@vmware_patterns);
16              
17             my @qemu_patterns = (
18             ' QEMUAPIC ',
19             'QEMU Virtual CPU',
20             ': QEMU HARDDISK,',
21             ': QEMU CD-ROM,'
22             );
23             my $qemu_pattern = _assemblePatterns(@qemu_patterns);
24              
25             my @virtual_machine_patterns = (
26             ': Virtual HD,',
27             ': Virtual CD,'
28             );
29             my $virtual_machine_pattern = _assemblePatterns(@virtual_machine_patterns);
30              
31             my @virtualbox_patterns = (
32             ' VBOXBIOS ',
33             ': VBOX HARDDISK,',
34             ': VBOX CD-ROM,',
35             );
36             my $virtualbox_pattern = _assemblePatterns(@virtualbox_patterns);
37              
38             my @xen_patterns = (
39             'Hypervisor signature: xen',
40             'Xen virtual console successfully installed',
41             'Xen reported:',
42             'Xen: \d+ - \d+',
43             'xen-vbd: registered block device',
44             'ACPI: [A-Z]{4} \(v\d+\s+Xen ',
45             );
46             my $xen_pattern = _assemblePatterns(@xen_patterns);
47              
48             my %module_patterns = (
49             '^vmxnet\s' => 'VMware',
50             '^xen_\w+front\s' => 'Xen',
51             );
52              
53             sub isEnabled {
54 0     0 0 0 return 1;
55             }
56              
57             sub doInventory {
58 0     0 0 0 my (%params) = @_;
59              
60 0         0 my $inventory = $params{inventory};
61 0         0 my $logger = $params{logger};
62              
63 0         0 my $type = _getType($inventory->getSection('BIOS'), $logger);
64              
65             # for consistency with HVM domU
66 0 0 0     0 if ($type eq 'Xen' && !$inventory->getBios('SMANUFACTURER')) {
67 0         0 $inventory->setBios({
68             SMANUFACTURER => 'Xen',
69             SMODEL => 'PVM domU'
70             });
71             }
72              
73             # compute a compound identifier, as Virtuozzo uses the same identifier
74             # for the host and for the guests
75 0 0       0 if ($type eq 'Virtuozzo') {
76 0   0     0 my $hostID = $inventory->getHardware('UUID') || '';
77 0   0     0 my $guestID = getFirstMatch(
78             file => '/proc/self/status',
79             pattern => qr/^envID:\s*(\d+)/
80             ) || '';
81 0         0 $inventory->setHardware({ UUID => $hostID . '-' . $guestID });
82             }
83              
84             $inventory->setHardware({
85 0         0 VMSYSTEM => $type,
86             });
87             }
88              
89             sub _getType {
90 0     0   0 my ($bios, $logger) = @_;
91              
92 0 0       0 if ($bios->{SMANUFACTURER}) {
93 0 0       0 return 'Hyper-V' if $bios->{SMANUFACTURER} =~ /Microsoft/;
94 0 0       0 return 'VMware' if $bios->{SMANUFACTURER} =~ /VMware/;
95             }
96 0 0       0 if ($bios->{BMANUFACTURER}) {
97 0 0       0 return 'QEMU' if $bios->{BMANUFACTURER} =~ /(QEMU|Bochs)/;
98 0 0       0 return 'VirtualBox' if $bios->{BMANUFACTURER} =~ /(VirtualBox|innotek)/;
99 0 0       0 return 'Xen' if $bios->{BMANUFACTURER} =~ /^Xen/;
100             }
101 0 0       0 if ($bios->{SMODEL}) {
102 0 0       0 return 'VMware' if $bios->{SMODEL} =~ /VMware/;
103 0 0       0 return 'Virtual Machine' if $bios->{SMODEL} =~ /Virtual Machine/;
104             }
105 0 0       0 if ($bios->{BVERSION}) {
106 0 0       0 return 'VirtualBox' if $bios->{BVERSION} =~ /VirtualBox/;
107             }
108              
109 0 0       0 if (-f '/.dockerinit') {
110 0         0 return 'Docker';
111             }
112              
113             # Solaris zones
114 0 0       0 if (canRun('/usr/sbin/zoneadm')) {
115 0         0 my $zone = getZone();
116 0 0       0 return 'SolarisZone' if $zone ne 'global';
117             }
118              
119             # Xen PV host
120 0 0 0     0 if (
121             -d '/proc/xen' ||
122             getFirstMatch(
123             file => '/sys/devices/system/clocksource/clocksource0/available_clocksource',
124             pattern => qr/xen/
125             )
126             ) {
127 0 0       0 if (getFirstMatch(
128             file => '/proc/xen/capabilities',
129             pattern => qr/control_d/
130             )) {
131             # dom0 host
132 0         0 return 'Physical';
133             } else {
134             # domU PV host
135 0         0 return 'Xen';
136             }
137             }
138              
139 0         0 my $result;
140              
141 0 0       0 if (canRun('/sbin/sysctl')) {
142 0         0 my $handle = getFileHandle(
143             command => '/sbin/sysctl -n security.jail.jailed',
144             logger => $logger
145             );
146 0         0 my $line = <$handle>;
147 0         0 close $handle;
148 0 0 0     0 return 'BSDJail' if $line && $line == 1;
149             }
150              
151             # loaded modules
152              
153 0 0       0 if (-f '/proc/modules') {
154 0         0 my $handle = getFileHandle(
155             file => '/proc/modules',
156             logger => $logger
157             );
158 0         0 while (my $line = <$handle>) {
159 0         0 foreach my $pattern (keys %module_patterns) {
160 0 0       0 next unless $line =~ /$pattern/;
161 0         0 $result = $module_patterns{$pattern};
162 0         0 last;
163             }
164             }
165 0         0 close $handle;
166             }
167 0 0       0 return $result if $result;
168              
169             # dmesg
170              
171 0         0 my $handle;
172 0 0       0 if (-r '/var/log/dmesg') {
    0          
    0          
173 0         0 $handle = getFileHandle(file => '/var/log/dmesg', logger => $logger);
174             } elsif (-x '/bin/dmesg') {
175 0         0 $handle = getFileHandle(command => '/bin/dmesg', logger => $logger);
176             } elsif (-x '/sbin/dmesg') {
177             # On OpenBSD, dmesg is in sbin
178             # http://forge.fusioninventory.org/issues/402
179 0         0 $handle = getFileHandle(command => '/sbin/dmesg', logger => $logger);
180             }
181              
182 0 0       0 if ($handle) {
183 0         0 $result = _matchPatterns($handle);
184 0         0 close $handle;
185 0 0       0 return $result if $result;
186             }
187              
188             # scsi
189              
190 0 0       0 if (-f '/proc/scsi/scsi') {
191 0         0 my $handle = getFileHandle(
192             file => '/proc/scsi/scsi',
193             logger => $logger
194             );
195 0         0 $result = _matchPatterns($handle);
196 0         0 close $handle;
197             }
198 0 0       0 return $result if $result;
199              
200 0 0       0 if (getFirstMatch(
201             file => '/proc/1/environ',
202             pattern => qr/container=lxc/
203             )) {
204 0         0 return 'lxc';
205             }
206              
207             # OpenVZ
208 0 0       0 if (-f '/proc/self/status') {
209 0         0 my $handle = getFileHandle(
210             file => '/proc/self/status',
211             logger => $logger
212             );
213 0         0 while (my $line = <$handle>) {
214 0         0 my ($key, $value) = split(/:/, $line);
215 0 0 0     0 $result = "Virtuozzo" if $key eq 'envID' && $value > 0;
216             }
217             }
218 0 0       0 return $result if $result;
219              
220 0         0 return 'Physical';
221             }
222              
223             sub _assemblePatterns {
224 5     5   8 my (@patterns) = @_;
225              
226 5         12 my $pattern = '(?:' . join('|', @patterns) . ')';
227 5         185 return qr/$pattern/;
228             }
229              
230             sub _matchPatterns {
231 0     0     my ($handle) = @_;
232              
233 0           while (my $line = <$handle>) {
234 0 0         return 'VMware' if $line =~ $vmware_pattern;
235 0 0         return 'QEMU' if $line =~ $qemu_pattern;
236 0 0         return 'Virtual Machine' if $line =~ $virtual_machine_pattern;
237 0 0         return 'VirtualBox' if $line =~ $virtualbox_pattern;
238 0 0         return 'Xen' if $line =~ $xen_pattern;
239             }
240             }
241              
242             1;