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   50489762 use strict;
  1         3  
  1         63  
4 1     1   6 use warnings;
  1         8  
  1         75  
5              
6 1     1   655 use FusionInventory::Agent::Tools;
  1         3  
  1         204  
7 1     1   673 use FusionInventory::Agent::Tools::Solaris;
  1         3  
  1         1363  
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->{content}->{BIOS}, $logger);
64              
65             # for consistency with HVM domU
66 0 0 0     0 if (
67             $type eq 'Xen' &&
68             !$inventory->{h}{CONTENT}{BIOS}{SMANUFACTURER}
69             ) {
70 0         0 $inventory->setBios({
71             SMANUFACTURER => 'Xen',
72             SMODEL => 'PVM domU'
73             });
74             }
75              
76             # compute a compound identifier, as Virtuozzo uses the same identifier
77             # for the host and for the guests
78 0 0       0 if ($type eq 'Virtuozzo') {
79 0   0     0 my $hostID = $inventory->getHardware('UUID') || '';
80 0   0     0 my $guestID = getFirstMatch(
81             file => '/proc/self/status',
82             pattern => qr/^envID:\s*(\d+)/
83             ) || '';
84 0         0 $inventory->setHardware({ UUID => $hostID . '-' . $guestID });
85             }
86              
87             $inventory->setHardware({
88 0         0 VMSYSTEM => $type,
89             });
90             }
91              
92             sub _getType {
93 0     0   0 my ($bios, $logger) = @_;
94              
95 0 0       0 if ($bios->{SMANUFACTURER}) {
96 0 0       0 return 'Hyper-V' if $bios->{SMANUFACTURER} =~ /Microsoft/;
97 0 0       0 return 'VMware' if $bios->{SMANUFACTURER} =~ /VMware/;
98             }
99 0 0       0 if ($bios->{BMANUFACTURER}) {
100 0 0       0 return 'QEMU' if $bios->{BMANUFACTURER} =~ /(QEMU|Bochs)/;
101 0 0       0 return 'VirtualBox' if $bios->{BMANUFACTURER} =~ /(VirtualBox|innotek)/;
102 0 0       0 return 'Xen' if $bios->{BMANUFACTURER} =~ /^Xen/;
103             }
104 0 0       0 if ($bios->{SMODEL}) {
105 0 0       0 return 'VMware' if $bios->{SMODEL} =~ /VMware/;
106 0 0       0 return 'Virtual Machine' if $bios->{SMODEL} =~ /Virtual Machine/;
107             }
108 0 0       0 if ($bios->{BVERSION}) {
109 0 0       0 return 'VirtualBox' if $bios->{BVERSION} =~ /VirtualBox/;
110             }
111              
112 0 0       0 if (-f '/.dockerinit') {
113 0         0 return 'Docker';
114             }
115              
116             # Solaris zones
117 0 0       0 if (canRun('/usr/sbin/zoneadm')) {
118 0         0 my $zone = getZone();
119 0 0       0 return 'SolarisZone' if $zone ne 'global';
120             }
121              
122             # Xen PV host
123 0 0 0     0 if (
124             -d '/proc/xen' ||
125             getFirstMatch(
126             file => '/sys/devices/system/clocksource/clocksource0/available_clocksource',
127             pattern => qr/xen/
128             )
129             ) {
130 0 0       0 if (getFirstMatch(
131             file => '/proc/xen/capabilities',
132             pattern => qr/control_d/
133             )) {
134             # dom0 host
135 0         0 return 'Physical';
136             } else {
137             # domU PV host
138 0         0 return 'Xen';
139             }
140             }
141              
142 0         0 my $result;
143              
144 0 0       0 if (canRun('/sbin/sysctl')) {
145 0         0 my $handle = getFileHandle(
146             command => '/sbin/sysctl -n security.jail.jailed',
147             logger => $logger
148             );
149 0         0 my $line = <$handle>;
150 0         0 close $handle;
151 0 0 0     0 return 'BSDJail' if $line && $line == 1;
152             }
153              
154             # loaded modules
155              
156 0 0       0 if (-f '/proc/modules') {
157 0         0 my $handle = getFileHandle(
158             file => '/proc/modules',
159             logger => $logger
160             );
161 0         0 while (my $line = <$handle>) {
162 0         0 foreach my $pattern (keys %module_patterns) {
163 0 0       0 next unless $line =~ /$pattern/;
164 0         0 $result = $module_patterns{$pattern};
165 0         0 last;
166             }
167             }
168 0         0 close $handle;
169             }
170 0 0       0 return $result if $result;
171              
172             # dmesg
173              
174 0         0 my $handle;
175 0 0       0 if (-r '/var/log/dmesg') {
    0          
    0          
176 0         0 $handle = getFileHandle(file => '/var/log/dmesg', logger => $logger);
177             } elsif (-x '/bin/dmesg') {
178 0         0 $handle = getFileHandle(command => '/bin/dmesg', logger => $logger);
179             } elsif (-x '/sbin/dmesg') {
180             # On OpenBSD, dmesg is in sbin
181             # http://forge.fusioninventory.org/issues/402
182 0         0 $handle = getFileHandle(command => '/sbin/dmesg', logger => $logger);
183             }
184              
185 0 0       0 if ($handle) {
186 0         0 $result = _matchPatterns($handle);
187 0         0 close $handle;
188 0 0       0 return $result if $result;
189             }
190              
191             # scsi
192              
193 0 0       0 if (-f '/proc/scsi/scsi') {
194 0         0 my $handle = getFileHandle(
195             file => '/proc/scsi/scsi',
196             logger => $logger
197             );
198 0         0 $result = _matchPatterns($handle);
199 0         0 close $handle;
200             }
201 0 0       0 return $result if $result;
202              
203 0 0       0 if (getFirstMatch(
204             file => '/proc/1/environ',
205             pattern => qr/container=lxc/
206             )) {
207 0         0 return 'lxc';
208             }
209              
210             # OpenVZ
211 0 0       0 if (-f '/proc/self/status') {
212 0         0 my $handle = getFileHandle(
213             file => '/proc/self/status',
214             logger => $logger
215             );
216 0         0 while (my $line = <$handle>) {
217 0         0 my ($key, $value) = split(/:/, $line);
218 0 0 0     0 $result = "Virtuozzo" if $key eq 'envID' && $value > 0;
219             }
220             }
221 0 0       0 return $result if $result;
222              
223 0         0 return 'Physical';
224             }
225              
226             sub _assemblePatterns {
227 5     5   13 my (@patterns) = @_;
228              
229 5         18 my $pattern = '(?:' . join('|', @patterns) . ')';
230 5         262 return qr/$pattern/;
231             }
232              
233             sub _matchPatterns {
234 0     0     my ($handle) = @_;
235              
236 0           while (my $line = <$handle>) {
237 0 0         return 'VMware' if $line =~ $vmware_pattern;
238 0 0         return 'QEMU' if $line =~ $qemu_pattern;
239 0 0         return 'Virtual Machine' if $line =~ $virtual_machine_pattern;
240 0 0         return 'VirtualBox' if $line =~ $virtualbox_pattern;
241 0 0         return 'Xen' if $line =~ $xen_pattern;
242             }
243             }
244              
245             1;