186 lines
6.2 KiB
Plaintext
186 lines
6.2 KiB
Plaintext
|
#!/usr/bin/perl -w
|
||
|
# Louis Abel <tucklesepk@gmail.com>
|
||
|
use strict;
|
||
|
|
||
|
# Check for version of dmidecode
|
||
|
my $dmi_test = `dmidecode -q 2>/dev/null; echo \$?`;
|
||
|
chomp($dmi_test);
|
||
|
our $dmi_ver = "rhel8";
|
||
|
our $dmidecode_cmd = "dmidecode -q";
|
||
|
if( $dmi_test eq "1" ) { $dmi_ver = "rhel4"; $dmidecode_cmd = "dmidecode"; }
|
||
|
|
||
|
# Figure out number of cores per cpu
|
||
|
my $c_cpuinfo = `grep -c processor /proc/cpuinfo`;
|
||
|
chomp($c_cpuinfo);
|
||
|
my $c_dmidecode = `$dmidecode_cmd | grep -c 'Processor Information'`;
|
||
|
chomp($c_dmidecode);
|
||
|
|
||
|
# Figure out hyperthreaded cores
|
||
|
my $htt;
|
||
|
my $lscpu_test = `lscpu 2>/dev/null; echo \$?`;
|
||
|
chomp($lscpu_test);
|
||
|
if( $lscpu_test eq "127" ) {
|
||
|
$htt = "Cannot Detect Threads";
|
||
|
} else {
|
||
|
$htt = `lscpu | awk -F':' '/Thread/ {print \$2}'`;
|
||
|
chomp($htt);
|
||
|
}
|
||
|
$htt =~ s/^\s+|\s+$//g;
|
||
|
|
||
|
my $cores;
|
||
|
if( $c_cpuinfo eq $c_dmidecode ) {
|
||
|
$cores = "single core";
|
||
|
} elsif ( $c_cpuinfo > $c_dmidecode ) {
|
||
|
my $num_cores = $c_cpuinfo / $c_dmidecode / $htt;
|
||
|
$cores = "$num_cores cores";
|
||
|
} else {
|
||
|
$cores = "failed to determine number of cores";
|
||
|
}
|
||
|
|
||
|
# Parse dmidecode output
|
||
|
our %manufacturer;
|
||
|
our %cpu;
|
||
|
our %memory;
|
||
|
our %network;
|
||
|
|
||
|
open( FH, "$dmidecode_cmd |") or die "Couldn't run $dmidecode_cmd: $!\n\n";
|
||
|
my ($section, $dim, $dim_size);
|
||
|
my $dims_used = 0;
|
||
|
my $dims_total = 0;
|
||
|
my $eths_section = 0;
|
||
|
my $eths_total = 0;
|
||
|
while( my $line = <FH> ) {
|
||
|
chomp($line);
|
||
|
|
||
|
# Store section information
|
||
|
if( $line =~ /^\S+/ ) { $section = $line; }
|
||
|
|
||
|
# Print Bios Information
|
||
|
if( $section eq "BIOS Information" || $section =~ /Handle 0x0000/ ) {
|
||
|
if( $line =~ /^\s+Version:\s+(.+)\s*$/ ) { $manufacturer{bios} = $1; }
|
||
|
}
|
||
|
|
||
|
# Print System Information
|
||
|
if( $section eq "System Information" || $section =~ /Handle 0x0100/ ) {
|
||
|
if( $line =~ /^\s+Manufacturer:\s+(.+)\s*$/ ) { if( $1 =~ /Dell Computer Corporation/ ) { $manufacturer{make} = "Dell Inc."; } else { $manufacturer{make} = $1; } }
|
||
|
if( $line =~ /^\s+Product Name:\s+(.+)\s*$/ ) { my $tmp = $1; $tmp =~ s/\s+$//g; $manufacturer{model} = $tmp; }
|
||
|
if( $line =~ /^\s+Serial Number:\s+(.+)\s*$/ ) { $manufacturer{serial} = $1; }
|
||
|
}
|
||
|
|
||
|
# Print Chassis Information
|
||
|
if( $section eq "Chassis Information" || $section =~ /Handle 0x0300/ ) {
|
||
|
if( $line =~ /^\s+Type:\s+(.+)\s*$/ ) { $manufacturer{chassis_type} = $1; }
|
||
|
if( $line =~ /^\s+Height:\s+(.+)\s*$/ ) { $manufacturer{chassis_height} = $1; }
|
||
|
}
|
||
|
|
||
|
# Print Processor Information
|
||
|
if( $section eq "Processor Information" || $section =~ /Handle 0x040/ ) {
|
||
|
if( $line =~ /^\s+Version:\s+(.+)\s*$/ ) {
|
||
|
my $cpu_model = $1;
|
||
|
|
||
|
if( $cpu_model =~ /Not Specified/ ) {
|
||
|
$cpu_model = `cat /proc/cpuinfo | grep 'model name' | awk -F: {'print \$2'} | head -n 1`;
|
||
|
chomp( $cpu_model );
|
||
|
$cpu_model =~ s/^\s*//g;
|
||
|
}
|
||
|
|
||
|
$cpu_model =~ s/\s+/ /g;
|
||
|
|
||
|
$cpu{physical} = $c_dmidecode;
|
||
|
$cpu{virtual} = $c_cpuinfo;
|
||
|
$cpu{model} = "$cpu_model ($cores) (Threads: $htt)";
|
||
|
}
|
||
|
|
||
|
if( $line =~ /^\s+Speed:\s+(.+)\s*$/ ) { $cpu{speed} = $1; }
|
||
|
|
||
|
}
|
||
|
|
||
|
# Print Physical Memory Array
|
||
|
if( $section eq "Physical Memory Array" || $section =~ /Handle 0x1000/ ) {
|
||
|
if( $line =~ /^\s+Error Correction Type:\s+(.+)\s*$/ ) { $memory{error} = $1; }
|
||
|
if( $line =~ /^\s+Maximum Capacity:\s+(.+)\s*$/ ) { $memory{max} = $1; }
|
||
|
if( $line =~ /^\s+Number Of Devices:\s+(.+)\s*$/ ) { $memory{count} = $1; }
|
||
|
}
|
||
|
|
||
|
# Print Memory Device
|
||
|
if( $section eq "Memory Device" || $section =~ /Handle 0x110/ ) {
|
||
|
if( $line =~ /^\s+Locator:\s+(.+)\s*$/ ) { $dim = $1; $dim =~ s/\s+//g; $dims_total++}
|
||
|
if( $line =~ /^\s+Size:\s+(.+)\s*$/ ) { $dim_size = $1; }
|
||
|
if( $line =~ /^\s+Speed:\s+(.+)\s*$/ ) { next if( $dim_size =~ /No Module Installed/ ); $memory{$dims_total}{location} = $dim; $memory{$dims_total}{size} = $dim_size; $memory{$dims_total}{speed} = $1; $dims_used++; }
|
||
|
if( $line =~ /^\s+Type:\s+(.+)\s*$/ ) { $memory{type} = $1; }
|
||
|
}
|
||
|
|
||
|
# Print Ethernet Devices
|
||
|
$network{total} = 0;
|
||
|
if( $section =~ /^On Board Device/ || $section =~ /Handle 0x0A00/ || $section =~ /^Onboard Device/ ) {
|
||
|
if( $line =~ /^\s+Type:\s+Ethernet\s*$/ ) { $eths_section = 1; $eths_total++; $network{total} = $eths_total; }
|
||
|
next if( $eths_section == 0 );
|
||
|
|
||
|
if( $line =~ /^\s+Status:\s+(.+)\s*$/ ) { $network{$eths_total}{status} = $1; }
|
||
|
if( $line =~ /^\s+Description:\s+(.+)\s*$/ ) { $network{$eths_total}{desc} = $1; }
|
||
|
}
|
||
|
}
|
||
|
close(FH);
|
||
|
|
||
|
|
||
|
# Clean up missing data
|
||
|
$manufacturer{chassis_height} = "<UNKNOWN>" unless( defined($manufacturer{chassis_height}) );
|
||
|
$memory{used} = $dims_total;
|
||
|
|
||
|
#Print Data
|
||
|
print "Make: $manufacturer{make}\n";
|
||
|
print "Model: $manufacturer{model}\n";
|
||
|
print "Serial: $manufacturer{serial}\n";
|
||
|
print "Bios Rev: $manufacturer{bios}\n";
|
||
|
print "Chassis Type: $manufacturer{chassis_type}\n";
|
||
|
print "Chassis Height: $manufacturer{chassis_height}\n";
|
||
|
print "$cpu{physical} x $cpu{model}\n";
|
||
|
print_memory_info();
|
||
|
print_network_info();
|
||
|
|
||
|
|
||
|
#### Functions ####
|
||
|
|
||
|
sub print_memory_info {
|
||
|
my ($maxsize, $max_unit) = $memory{max} =~ /^\s*(\d+)\s*(\w+)\s*$/;
|
||
|
my $dim_count = $memory{count};
|
||
|
my $max_per_dim = $maxsize / $dim_count;
|
||
|
|
||
|
my $size_error = "";
|
||
|
my $speed_error = "";
|
||
|
my $common_size;
|
||
|
my $common_speed;
|
||
|
for( my $i = 1; $i < $dims_used + 1; $i++ ) {
|
||
|
my $size = $memory{$i}{size} || 0;
|
||
|
my $speed = $memory{$i}{speed} || 0;
|
||
|
|
||
|
if( defined($common_size) && $common_size ne $size ) { $size_error = 1; }
|
||
|
else { $common_size = $size; }
|
||
|
if( defined($common_speed) && $common_speed ne $speed ) { $speed_error = 2; }
|
||
|
else { $common_speed = $speed; }
|
||
|
}
|
||
|
|
||
|
my ($mem_size, $mem_unit) = $common_size =~ /^\s*(\d+)\s*(\w+)\s*$/;
|
||
|
my $total_mem_unit = "MB";
|
||
|
if( $mem_unit eq "MB" ) { $total_mem_unit = "GB"; }
|
||
|
my $mem_total = ($mem_size * $dims_used) * 1024 ;
|
||
|
|
||
|
if( $common_size =~ /(\d+\.\d{2})\d+/ ) { $common_size = $1; }
|
||
|
if( $mem_size >= 1024 ) { my $gb_size = $mem_size / 1024; $common_size = "$gb_size GB"; }
|
||
|
|
||
|
print "$common_size @ $common_speed x $dims_used = $mem_total $total_mem_unit";
|
||
|
if( $size_error || $speed_error ) { print " $size_error$speed_error"; }
|
||
|
print "\n";
|
||
|
|
||
|
if( $max_per_dim =~ /(\d+\.\d{2})\d+/ ) { $max_per_dim = $1; }
|
||
|
print "$max_per_dim $max_unit x $dim_count dims = $maxsize $max_unit maximum capacity\n";
|
||
|
print "$memory{type}\n$memory{error}\n";
|
||
|
}
|
||
|
|
||
|
sub print_network_info {
|
||
|
my $num_devices = $network{total};
|
||
|
for( my $i=1; $i < $num_devices + 1; $i++ ) {
|
||
|
print "$network{$i}{desc} [$network{$i}{status}]\n";
|
||
|
}
|
||
|
}
|