#!/usr/bin/perl -w my $sysinfo_revision = '$Rev: 6993 $ $Date:: 2015-11-06 #$'; # This is an example 'sysinfo' program, for use with SPEC CPU2006. It can help # you get started filling out some important SUT (System Under Test) disclosure # fields, but it does NOT remove the need for a human being to understand the # SUT. #------------------------------------------------------------------------- # Updates # # This program is likely to evolve. To check for updates, see: # http://www.spec.org/cpu2006/Docs/sysinfo #------------------------------------------------------------------------- # Usage # # (1) In your config file, put the following near the top: # # sysinfo_program = specperl $[top]/Docs/sysinfo # # Optional switches: # -f Do not write fields; instead, write comments # -p Do not write platform notes; instead, write comments # # (2) Unless you use the optional -f switch, be sure to search for # "promisedfields", below, to find the list of fields that will # be written by this file. If your config file also sets those fields, # you have several choices for what to do about duplicate fields, which # are described at: # # http://www.spec.org/cpu2006/Docs/config.html#sysinfo #------------------------------------------------------------------------- # Outputs # # Unless one of the above switches is set, writes some free-form platform # notes plus various sw_xx and hw_xx fields. To find the list of fields # output, search for "promisedfields", below. # # If you choose to write comments, these go to the *output* copy of the config # file that goes to the *result* directory. For more info on this point, See # the sysinfo documentation: # # http://www.spec.org/cpu2006/Docs/config.html#sysinfo #------------------------------------------------------------------------- # Structure of this script # # The main routine detects the OS, and dispatches to a system-specific # subroutine. # # The system-specific subroutine talks to useful utilities and as it does # so, (1) calls notesout() to format platform notes, and (2) builds the # global data structure # # $hw_fields{fieldname} # # where the "fieldnames" are the familiar fields such as "hw_model", # "sw_os" and so forth. # # After visiting the system-specific subroutine, # # write_fields() # # actually writes them. #------------------------------------------------------------------------- # Changing or customizing this script # # To add free-form information: # - In the OS-specific routine, visit the system utility that you are # interested in, capture its output, and just send it to notesout() # - Notice that notesout() doesn't mind if you hand it one line or # multiple lines. # # To add a field: # - (1) add code that assigns to $hw_fields{newfield} # - (2) add newfield to the data structure promisedfields # # To delete a field: # - (1) remove (or comment out) the assignment to $hw_fields{whatever} # - (2) remove it from the data structure promisedfields #------------------------------------------------------------------------- # j.henning jun 2011 # Copyright 2011 Standard Performance Evaluation Corporation # $Id: sysinfo 6993 2015-11-06 22:07:26Z CloyceS $ # update 11-Oct-2011: for Linux, get memory info from 'dmidecode' # if it is available. For Solaris, pick up # the MHz; prefer 'kstat' for core info # ###################### start of main routine ############### use strict; use Text::Tabs; use Cwd; my $scriptdir = cwd; # globals my $notes_section = "notes_plat_sysinfo"; # which notes setion to use my $punt = "could not determine"; # the last, last resort my $fieldsok = 1; # If this is 1, some output goes to hw_xxx/sw_xxx my $notesok = 1; # If this is 1, some output goes to notes section my $fnwidth = 14; # (minimum) width of field names, to align # when pretty-printing. This is used for # both sw_xx, hw_xx, and within some notes my $desired_line_width = 80; # wrap notes here my $notenum = 0; # global to recall what notenum we are on my %fields; # global for any fields we figure out sub notesout; sub write_fields; # process arguments while (my $arg = shift) { if ($arg eq "-f") { $fieldsok = 0; } elsif ($arg eq "-p") { $notesok = 0; } else { print "# unrecognized argument '$arg' given to $0\n"; } } # Do we know this OS? If so, dispatch sysinfo_header(); my $os = ""; # canonical spelling for key to field list if ($^O =~ /mswin/i) { $os = "mswin"; sysinfo_mswin(); } elsif ($^O =~ /linux/i) { $os = "linux"; sysinfo_linux(); } elsif ($^O =~ /solaris/i) { $os = "solaris"; sysinfo_solaris(); } elsif ($^O =~ /darwin/i) { $os = "macosx"; sysinfo_macosx(); } else { notesout("\nSorry, $^O is not supported by $0\n"); } notesout "\n(End of data from sysinfo program)"; write_fields(); exit; ###################### end of main routine ############### #============================================ # Utility subroutines #============================================ #--------------------------------- sub sysinfo_header { my $hostname = `hostname`; chomp $hostname; my $date = localtime(); my $selfsum = ""; my $try; if (defined $ENV{"SPEC"}) { $try = "$ENV{'SPEC'}/bin/specmd5sum"; } else { $try = "$scriptdir/../bin/specmd5sum"; } $try = $try . ".exe" if ! -e $try; if (-e $try && -x $try) { ($selfsum) = split " ", `$try "$0"`; $selfsum = "($selfsum)"; } # Make $sysinfo_revision immune to the effects of expand_notes $sysinfo_revision =~ s/Rev:/Revision/; $sysinfo_revision =~ s/[:\$]\s*//g; $sysinfo_revision =~ s/Date/of /; $sysinfo_revision =~ s/\s*#$//; notesout < $desired_line_width) { my $lastblank = rindex $line, " ", $desired_line_width; unless ($lastblank < 4 || $lastblank <= $nspace) { # don't bother if just creates a widow my $rest = substr $line, $lastblank; $rest =~ s/^\s+//; # get rid of blank we wrapped on $rest = " " x $nspace . $rest; # insert right number of them unshift @lines, $rest; $line = substr $line, 0, $lastblank; } } # and actually print it, preceded by note number if ($notesok) { printf "%s_%03d = ", $notes_section, ($notenum * 5); $notenum++; } else { printf "# "; } print "$line\n"; } } } #--------------------------------- sub numerically { $a <=> $b; } #--------------------------------- sub simplify_cpu_name { my $cpu = shift; $cpu =~ s/\((R|tm)\)//ig; $cpu =~ s/CPU//g; $cpu =~ s/processor//ig; $cpu =~ s/\@\s+[\d\.]+\s*GHz//i; # at best nominal speed $cpu =~ s/^\s+//; $cpu =~ s/\s+/ /g; return $cpu; } #--------------------------------- sub write_fields { # # This subroutine actually writes the fields. It also serves as a # backstop, in case the OS-specific subroutines somehow fail to come up # with information about some field(s) that were promised: if we do not # have useful information, then insert at least a minimal template. # my %promisedfields; $promisedfields{"mswin"} = < "99999 (integer, actual MHz)", hw_cpu_name => "cpu name", hw_disk => "size, type, other perf-relevant char of SPEC disk", hw_memory => "format is 'n GB (n x n GB nRxn PCn-nnnnnR-n, ECC)'", hw_model => "model name", hw_nchips => "number chips enabled", hw_ncores => "number cores enabled", hw_ncoresperchip => "number cores manufactured into each chip", hw_nthreadspercore => "number threads enabled per core", hw_scache => "size, type, location: e.g. 99 MB I+D on chip per chip", hw_tcache => "size, type, location: e.g. 99 MB I+D off chip per system board", hw_vendor => "hardware manufacturer", sw_os => "operating system", sw_other => "Other performance relevant sw", sw_state => "software state (e.g runlevel)", ); # Verify that we have *something* for all promised fields unless (!defined $promisedfields{$os}) { for my $f (split " ", $promisedfields{$os}) { if (!defined $fields{$f}) { if (defined $templatef{$f}) { $fields{$f} = $templatef{$f}; } else { if ($f =~ m/^([^0-9]+)([0-9]+)$/) { my $basef = $1; my $fnum = $2; if (defined $templatef{$basef}) { $fields{$f} = $templatef{$basef} . " part $fnum"; } else { $fields{$f} = $punt; } } else { $fields{$f} = $punt; } } } } } print "\n"; # use fnwidth global as the minimum, but expand if needed for my $key (sort keys %fields) { $fnwidth = length $key if (length($key) > $fnwidth); } for my $key (sort keys %fields) { print "# " if ! $fieldsok; $fields{$key} =~ s/^\s+//; $fields{$key} =~ s/\s+$//; printf "%-${fnwidth}s = %s\n", $key, $fields{$key}; } } #============================================ # sysinfo for Solaris # relies on: psrinfo, prtconf, /etc/release, uname #============================================ sub sysinfo_solaris { #--------- cpu name ---- # Seen at least three formats output # #The physical processor has 1 virtual processor (0) # UltraSPARC-III (portid 0 impl 0x14 ver 0x34 clock 750 MHz) # #The physical processor has 4 virtual processors (0 4 8 12) # x86 (GenuineIntel 6FB family 6 model 15 step 11 clock 2933 MHz) # Intel(r) Xeon(r) CPU X7350 @ 2.93GHz # #The physical processor has 8 cores and 64 virtual processors (0-63) # The core has 8 virtual processors (0-7) # The core has 8 virtual processors (8-15) # ... notesout "From /usr/sbin/psrinfo \n"; my @cpuname = `/usr/sbin/psrinfo -pv | grep -v "processor has" | grep -v "core has" | sort | uniq`; for my $c (@cpuname) { $c =~ s/\s+/ /g; # compress blanks notesout " $c"; } if ($#cpuname == -1) { $cpuname[0] = "Did not find cpu model name"; } # try to reduce the number by ignoring stuff not needed my @newcpuname; for my $c (@cpuname) { next if $c =~ m/^\s*x86\s+\(.*MHz\)\s*$/; # skip lines that say x86 (mumble) $c =~ s/\((chipid|portid).*MHz\)//; # remove port/chip numbers my $seenit = 0; for my $new (@newcpuname) { $seenit = 1 if $new eq $c; } push (@newcpuname, $c) unless $seenit; } @cpuname = @newcpuname; my $cpu; if ($#cpuname > 0 ) { $cpu = "more than one type"; } elsif ($#cpuname < 0) { $cpu = "none found"; } else { $cpu = $cpuname[0]; } $fields{"hw_cpu_name"} = simplify_cpu_name($cpu); #--------- nchips ---- my $cmd = "/usr/sbin/psrinfo -p"; my $nchips = `$cmd`; chomp $nchips; #notesout "\n$cmd: $nchips chips\n"; notesout " $nchips chips\n"; $fields{"hw_nchips"} = $nchips; #--------- threads ---- $cmd = "/usr/sbin/psrinfo | wc -l"; my $nthreads = `$cmd`; chomp $nthreads; $nthreads =~ s/^\s+//; $nthreads =~ s/\s+$//; #notesout "$cmd: $nthreads threads\n"; notesout " $nthreads threads\n"; #--------- MHz ---- $cmd = "/usr/sbin/psrinfo -v | grep processor | grep MHz | sort | uniq"; my @mhz_lines = `$cmd`; if ((@mhz_lines == 1) && ($mhz_lines[0] =~ m/(\d+)\s+MHz/)) { my $mhz = $1; notesout " $mhz MHz"; $fields{"hw_cpu_mhz"} = $mhz; } elsif (@mhz_lines > 1) { notesout "\nMore than one MHz found!\n$cmd"; notesout join "\n ", @mhz_lines; $fields{"hw_cpu_mhz"} = "mixed!"; } #--------- cores ---- $cmd = "/usr/bin/kstat cpu_info | grep -w core_id | sort -u | wc -l"; my $ncores = `$cmd`; chomp $ncores; if ($ncores != 0) { notesout "\nFrom kstat: $ncores cores\n"; $fields{"hw_ncores"} = $ncores; } #--------- threads/core, cores/chip: do some division if we can ---- if (($nthreads != 0) && ($ncores != 0)) { $fields{"hw_nthreadspercore"} = $nthreads/$ncores; } if (($nchips != 0) && ($ncores != 0)) { $fields{"hw_ncoresperchip"} = $ncores / $nchips; } #--------- memory ---- $cmd = "/usr/sbin/prtconf | grep \"Memory size:\""; my $memsize = `$cmd`; chomp $memsize; $memsize =~ s/Memory size:\s*//; if ($memsize =~ m/\d+/) { #notesout "\n$cmd: $memsize\n"; notesout "\nFrom prtconf: $memsize\n"; if ($memsize =~ /(\d+) Megabytes/) { my $m = $1; $memsize = $m . " MB"; $fields{"hw_memory"} = $memsize . " fixme: format is: 'n GB (n x n GB nRxn PCn-nnnnnR-n, ECC)'" } } #--------- sw OS ---- if (-e "/etc/release") { my $release = `head -1 /etc/release`; $release =~ s/^\s+/ /; notesout "\n/etc/release:\n $release"; if ($release =~ /Solaris/) { $release =~ s/(Oracle|Sun)//; $release =~ s/(SPARC|X86)//i; $release =~ s/\s+/ /g; $release =~ s/^\s//; $fields{"sw_os"} = $release . " fixme: probably ok to shorten\n", } } $cmd = "uname -a"; my $uname = `$cmd`; notesout "$cmd:\n $uname"; #--------- disk ---- # is -h likely to be supported? system "df -h / >/dev/null 2>/dev/null"; if ($? == 0) { $cmd = "df -h "; } else { $cmd = "df -k "; } if (defined $ENV{"SPEC"}) { my $s = $ENV{"SPEC"}; notesout "\nSPEC is set to: $s"; $cmd .= " $s"; } else { $cmd .= ' .'; } notesout "\ndisk: $cmd"; my @dlines = `$cmd`; notesout @dlines; #--------- prepared by ---- my $who; $who = $ENV{"LOGNAME"}; chomp $who; $fields{"prepared_by"} = "$who (is never output, only tags rawfile)"; } #============================================ # sysinfo for Windows # relies on: 'systeminfo' and 'wmic' #============================================ sub sysinfo_mswin { my $processor_next; my $nchips = 0; my $ncores = 0; notesout "Trying 'systeminfo'\n"; my $path = $ENV{'PATH'}; if ($path !~ /Wbem/i) { my $root = $ENV{'SYSTEMROOT'}; $ENV{'PATH'} = "$root\\System32\\Wbem;" . $ENV{'PATH'}; } #--------- talk to 'systeminfo' ----- open T, "systeminfo|"; # OS Name: Microsoft Windows 7 Professional # OS Version: 6.1.7600 N/A Build 7600 # System Manufacturer: LENOVO # System Model: 2537LB8 # Processor(s): 1 Processor(s) Installed. # [01]: Intel64 Family 6 Model 37 Stepping 5 GenuineIntel ~1320 Mhz # BIOS Version: LENOVO 6IET75WW (1.35 ), 2/1/2011 # Total Physical Memory: 3,892 MB while (my $aline = ) { if ($aline =~ /^\s/) { # blank in col. 1 for continuing fields if ($processor_next) { $nchips++; $aline =~ s/^\s+/ /; notesout $aline; } } else { # non-blank in column 1 is a field name $processor_next = 0; (my $fname, my $fcontent) = split(":", $aline, 2); $fcontent =~ s/^\s+//; # no leading space $fcontent =~ s/\s+/ /g; # compress sequences of space to single if ($fname =~ m/^OS Name$/) { notesout sprintf "%-${fnwidth}s: %s\n", $fname, $fcontent; $fields{"sw_os001"} = $fcontent; } elsif ($fname =~ m/^OS Version$/) { notesout sprintf "%-${fnwidth}s: %s\n", $fname, $fcontent; $fields{"sw_os002"} = $fcontent; } elsif ($fname =~ m/^System Manufacturer$/) { notesout sprintf "%-${fnwidth}s: %s\n", $fname, $fcontent; $fields{"hw_vendor"} = $fcontent; } elsif ($fname =~ m/^System Model$/) { notesout sprintf "%-${fnwidth}s: %s\n", $fname, $fcontent; $fields{"hw_model"} = $fcontent; } elsif ($fname =~ m/^Processor\(s\)$/) { $processor_next = 1; notesout sprintf "%-${fnwidth}s: %s\n", $fname, $fcontent; } elsif ($fname =~ m/^BIOS Version$/) { notesout sprintf "%-${fnwidth}s: %s\n", $fname, $fcontent; } elsif ($fname =~ m/^Total Physical Memory$/) { notesout sprintf "%-${fnwidth}s: %s\n", $fname, $fcontent; $fields{"hw_memory001"} = $fcontent . " fixme: format is:"; $fields{"hw_memory002"} = "'n GB (n x n GB nRxn PCn-nnnnnR-n, ECC)'"; } } } if ($nchips > 0) { $fields{"hw_nchips"} = $nchips; } #--------- talk to 'wmic' ----- my $cmd = "wmic cpu get /value"; notesout "\nTrying '$cmd'\n"; my @wmicout = `$cmd 2>&1`; if (@wmicout < 3 || $wmicout[0] =~ m/not recognized/) { my $tryhere = "$ENV{'SystemRoot'}/System32/Wbem/WMIC.exe"; if (-e $tryhere) { $cmd =~ s/^wmic/$tryhere/; @wmicout = `$cmd 2>&1`; } } for my $aline (@wmicout) { # DeviceID=CPU0 # L2CacheSize=256 # L3CacheSize=3072 # MaxClockSpeed=2400 # Name=Intel(R) Core(TM) i5 CPU M 520 @ 2.40GHz # NumberOfCores=2 # NumberOfLogicalProcessors=4 # $aline =~ tr/\015\012//d; # Universal, OS-agnostic chomp $aline =~ s/\s+/ /g; $aline =~ s/\s+$//; next if $aline !~ m/=/; (my $fname, my $fcontent) = split("=", $aline, 2); if ($fname =~ m/^DeviceID$/) { notesout sprintf "%-${fnwidth}s: %s\n", $fname, $fcontent; } elsif ($fname =~ m/^L2CacheSize$/) { notesout sprintf "%-${fnwidth}s: %s\n", $fname, $fcontent; $fields{"hw_scache"} = "$fcontent KB I+D on/off chip per ____"; } elsif ($fname =~ m/^L3CacheSize$/) { notesout sprintf "%-${fnwidth}s: %s\n", $fname, $fcontent; $fields{"hw_tcache"} = "$fcontent KB I+D on/off chip per ____"; } elsif ($fname =~ m/^MaxClockSpeed$/) { notesout sprintf "%-${fnwidth}s: %s\n", $fname, $fcontent; $fields{"hw_cpu_mhz"} = $fcontent; } elsif ($fname =~ m/^Name$/) { notesout sprintf "%-${fnwidth}s: %s\n", $fname, $fcontent; $fields{"hw_cpu_name"} = simplify_cpu_name($fcontent); } elsif ($fname =~ m/^NumberOfCores$/) { notesout sprintf "%-${fnwidth}s: %s\n", $fname, $fcontent; $ncores = $fcontent; $fields{"hw_ncores"} = $fcontent; } elsif ($fname =~ m/^NumberOfLogicalProcessors$/) { notesout sprintf "%-${fnwidth}s: %s\n", $fname, $fcontent; if ($ncores != 0) { $fields{"hw_nthreadspercore"} = $fcontent / $ncores; } } } if (($nchips != 0) && ($ncores != 0)) { $fields{"hw_ncoresperchip"} = $ncores / $nchips; } #--------- prepared by---- my $who; $who = $ENV{"USERNAME"}; chomp $who; $fields{"prepared_by"} = "$who (is never output, only tags rawfile)"; } #===================================================== # sysinfo for Mac OS X # relies on: system_profiler #===================================================== sub sysinfo_macosx { #--------- talk to system_profiler ---- my $profile_app = "/usr/sbin/system_profiler"; if (! -e $profile_app || ! -x $profile_app) { notesout "could not access system profiler"; return; } my $cmd = "$profile_app SPHardwareDataType SPSoftwareDataType " . "SPMemoryDataType SPDeveloperToolsDataType"; my @profile_lines = qx{$cmd 2>/dev/null}; if (! @profile_lines) { notesout "no info returned by system profiler"; return; } notesout @profile_lines; for my $line (@profile_lines) { chomp $line; if ($line =~ m/Model Name:\s+(.*)/) { # a good thing to find $fields{"hw_model"} = $1; } elsif ($line =~ m/Model Identifier:\s+(.*)/) { # even better $fields{"hw_model"} = $1; } elsif ($line =~ m/Processor Name:\s+(.*)/) { $fields{"hw_cpu_name"} = $1; } elsif ($line =~ m/Processor Speed:\s+(.*)\s*GHz/) { my $ghz = $1; my $mhz = $1 * 1000; $fields{"hw_cpu_mhz"} = $mhz; } elsif ($line =~ m/Number Of Processors:\s+(.*)/i) { $fields{"hw_nchips"} = $1; } elsif ($line =~ m/Total Number Of Cores:\s+(.*)/i) { $fields{"hw_ncores"} = $1; } elsif ($line =~ m/L2 Cache(?:\s+\(([^)]+)\))?:\s+(.*)/) { $fields{"hw_scache"} = $2; if (defined($1) && $1 ne '') { $fields{"hw_scache"} .= " $1"; } } elsif ($line =~ m/L3 Cache(?:\s+\(([^)]+)\))?:\s+(.*)/) { $fields{"hw_tcache"} = $1; if (defined($2) && $2 ne '') { $fields{"hw_tcache"} .= $2; } } elsif ($line =~ m/Memory:\s+(\d+)\s*(.*)/) { my $memory = $1; my $unit = $2; $fields{"hw_memory001"} = sprintf "%.1f %s fixme: If using DDR3, format is:", $memory, $unit; $fields{"hw_memory002"} = "'N GB (M x N GB nRxn PCn-nnnnnR-n, ECC)'"; } elsif ($line =~ m/System Version:\s+(.*)/) { $fields{"sw_os"} = $1; } elsif ($line =~ m/Xcode:\s+(.*)/) { $fields{"sw_other"} = $1; } } #--------- hw_disk ---- $cmd = "/bin/df -H "; if (defined $ENV{"SPEC"}) { my $s = $ENV{"SPEC"}; notesout "\nSPEC is set to: $s"; $cmd .= " $s"; } else { notesout "\ndf -h ."; $cmd .= ' .'; } my @dlines = `$cmd`; for my $d (@dlines) { notesout " $d"; } # expecting: # Filesystem Size Used Avail Capacity Mounted on # /dev/disk0s2 320G 161G 158G 51% / if ((scalar @dlines == 2) && ($dlines[0] =~ m/Filesystem/)) { my $fssize = (split " ", $dlines[1])[1]; $fssize =~ s{(\d+)(M|G|T)$}{$1 $2B}; if (defined $ENV{"SPEC"}) { $fields{"hw_disk"} = ""; } else { $fields{"hw_disk"} .= "SPEC not defined; current disk has: "; } $fields{"hw_disk"} .= "$fssize add more disk info here"; } else { $fields{"hw_disk"} = " add disk info here"; } #--------- prepared by ---- my $who; $who = $ENV{"LOGNAME"}; chomp $who; $fields{"prepared_by"} = "$who (is never output, only tags rawfile)"; } #===================================================== # sysinfo for Linux # relies on: /proc, /etc/*release*, uname, df, who -r #===================================================== sub sysinfo_linux { # There is code below that looks for various possible matches in /etc for # possible release or version info. If there are multiple hits, then the # first match from this list wins. my @prefer_id = qw( /etc/enterprise-release /etc/redhat-release /etc/SuSE-release /etc/sles-release /etc/debian_version /etc/mandrake-release /etc/UnitedLinux-release /etc/gentoo-release /etc/linuxppc-release /etc/nld-release /etc/slackware-version /etc/yellowdog-release ); my %prefer_id; for (my $i=0; $i <= $#prefer_id; $i++) { $prefer_id{$prefer_id[$i]} = $i; } # after the above loop, $prefer_id{OS} contains a number indicating its priority #--------- cpu name ---- notesout "From /proc/cpuinfo"; my @cpuname = qx'grep "model name" /proc/cpuinfo | sort | uniq'; if (@cpuname == 0) { # hmmm... maybe power? @cpuname = qx'grep -P "^cpu\s+:" /proc/cpuinfo | grep -i power | sort | uniq'; if (@cpuname == 1) { # # small diversion into POWER here. We won't try to figure out how to # decipher these, just tucking them away # my @powerinfo = qx'grep -P "(clock|revision|platform|model|machine)\s+" /proc/cpuinfo | sort | uniq'; for my $p (@powerinfo) { $p =~ s/\s+/ /g; notesout " $p"; } notesout ""; } } for my $c (@cpuname) { $c =~ s/\s+/ /g; # make multiple spaces one $c =~ s/^\s*/ /; # but do indent a little notesout $c; } my $cpu; if (@cpuname == 0) { notesout < 1 ) { $cpu = "more than one type"; } else { (my $ignore, $cpu) = split ":", $cpuname[0]; chomp $cpu; $cpu = simplify_cpu_name($cpu); } $fields{"hw_cpu_name"} = $cpu; #--------- nchips ---- my $cmd = 'grep "physical id" /proc/cpuinfo | sort | uniq | wc -l'; my $nchips = `$cmd`; chomp $nchips; if ($nchips == 0) { notesout </dev/null`; if (@rfiles < 1 && $sw_os1 eq "") { notesout "Did not find /etc/*release* nor /etc/*version*/"; } my $printed_rlshdr = 0; for my $rfile (@rfiles) { chomp $rfile; # plain file, readable, nonzero, text next unless (-f $rfile && -r $rfile && -s $rfile && -T $rfile); next if $rfile eq "/etc/lsb-release"; notesout "From /etc/*release* /etc/*version*" unless $printed_rlshdr; $printed_rlshdr = 1; my $this_rank; if (defined $prefer_id{$rfile}) { $this_rank = $prefer_id{$rfile}; } else { $this_rank = 9999; } my @rlines = `head -8 $rfile`; my $rs = $rfile; #shorter handle $rs =~ s{/etc/}{}; if (@rlines == 1) { my $l = $rlines[0]; $l =~ s/\s+/ /; $l =~ s/^\s*//; notesout " $rs: $l"; } else { notesout " $rs:\n"; for my $l (@rlines) { $l =~ s/\s+/ /; $l =~ s/^\s*/ /; notesout $l; } } if (($sw_os1 eq "") || ($sw_os1_filled_by > $this_rank)) { chomp $rlines[0]; $rlines[0] = "debian " . $rlines[0] if $rfile =~ m/debian/; $sw_os1 = $rlines[0]; $sw_os1_filled_by = $this_rank; } } #--------- sw_os2 ---- $cmd = "uname -a"; my $un = `$cmd`; chomp $un; notesout "\nuname -a:\n $un"; my $sw_os2 = `uname -r`; chomp $sw_os2; $sw_os1 =~ s/^\s+//; $sw_os2 =~ s/^\s+//; $fields{"sw_os001"} = $sw_os1; $fields{"sw_os002"} = $sw_os2; #--------- runlevel ---- $cmd = "who -r"; #notesout "\nrunlevel: $cmd: "; my $rline = `$cmd`; chomp $rline; $rline =~ s/\s+/ /g; $rline =~ s/^\s+//; notesout "\n$rline"; if ($rline =~ m/^\s*run-level\s(\S)/) { my $rl = $1; $fields{"sw_state"} = "Run level $1 (add definition here)"; } else { $fields{"sw_state"} = "Run level N (add definition here)"; } #--------- disk ---- $cmd = "df -Th "; if (defined $ENV{"SPEC"}) { my $s = $ENV{"SPEC"}; notesout "\nSPEC is set to: $s"; $cmd .= " $s"; } else { notesout "\ndf -h ."; $cmd .= ' .'; } my @dlines = `$cmd`; for my $d (@dlines) { notesout " $d"; } # expecting a header line plus a data line, which might be split over # 2 actual lines if (((@dlines) <= 3) && ($dlines[0] =~ m/^Filesystem/)) { my $dl = $dlines[1]; $dl .= " $dlines[2]" if defined $dlines[2]; (my $ignore, my $fstype, my $fssize) = split " ", $dl; $fields{"sw_file"} = $fstype; $fssize =~ s{(\d+)(G|T)$}{$1 $2B}; if (defined $ENV{"SPEC"}) { $fields{"hw_disk"} = ""; } else { $fields{"hw_disk"} .= "SPEC not defined; current disk has: "; } $fields{"hw_disk"} .= "$fssize add more disk info here"; } else { $fields{"hw_disk"} = " add disk info here"; } #--------- prepared by ---- my $who; $who = $ENV{"LOGNAME"}; chomp $who; $fields{"prepared_by"} = "$who (is never output, only tags rawfile)"; # # ------- sorta bonus: is dmidecode available? -------- # my @dmidecode; my $dmidecode_loc = "/usr/sbin/dmidecode"; if (-x $dmidecode_loc) { @dmidecode = `$dmidecode_loc 2>&1`; if ((scalar @dmidecode < 3) && (grep /Permission denied/, @dmidecode)) { notesout "\nCannot run dmidecode; consider saying 'chmod +s $dmidecode_loc'"; } else { notesout <