#!/bin/ksh93 # # $Id: prtdiag,v 1.11 2007/01/08 01:28:07 elkner Exp $ # # Author: jens elkner # # NOTE: # ksh means "AT&T ksh93" aka "the real thing" and NOT pdksh or similar crap! unset POSIXLY_CORRECT typeset -ft $(typeset +f) export LC_ALL=C function PrintVersion { print "prtdiag 2.0.4 Copyright 2006 Jens Elkner. Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. " } function Usage { print -u2 "Usage: prtdiag [-f] [-h] [-H] [-V] [-t types ] Display diagnostic information about the current system. -f .. display temperature values in °F instead of °C -h .. display this help and exit -H .. do not print the report header (i.e. hostname and time of report) -V .. display the version of this tool and exit -t types .. a string of letters, which dictate, what information should be displayed. Following types are available: g .. general information c .. information about CPUs p .. PCI/Input/Output devices related information i .. IDE devices information s .. SCSI devices information m .. memory related information e .. environmental status (fan/temperature/voltage) b .. BIOS information a .. display everything (i.e. cpmebisg) " } CELSIUS=1 SH_RHEAD=1 SH_TYPES="gcpismeba" while getopts "fhHVt:" opt; do case $opt in f) CELSIUS="" ;; h) Usage ; exit 1 ;; H) SH_RHEAD="" ;; V) PrintVersion ; exit 1 ;; t) [ "$OPTARG" = "a" ] || SH_TYPES="$OPTARG" ;; esac done shift $(($OPTIND-1)) ARCHTYPE=${ uname -m ; } function LoadCustomizations { [[ -r /etc/prtdiag.conf ]] && . /etc/prtdiag.conf [[ -r ~/.prtdiag.conf ]] && . ~/.prtdiag.conf } function CheckEnvironment { PATH="${PATH}:/usr/sbin:/usr/local/sbin:/sbin" P=${ pkgparam LNFdmidecode BASEDIR 2>/dev/null ; } if [[ -z $P ]] ; then DMIDECODE=${ whence dmidecode 2>/dev/null ; } BIOSDECODE=${ whence biosdecode 2>/dev/null ; } else DMIDECODE="$P/sbin/dmidecode" BIOSDECODE="$P/sbin/biosdecode" fi P=${ pkgparam LNFstatic-pciutils BASEDIR 2>/dev/null ; } [[ -n $P ]] || P=${ pkgparam LNFpciutils BASEDIR 2>/dev/null ; } if [[ -n $P ]]; then LSPCI="$P/sbin/lspci" else LSPCI=${ whence lspci 2>/dev/null ; } fi EXIT="" P=${ pkgparam LNFsed BASEDIR 2>/dev/null ; } if [[ -z $P ]] ; then SED=${ whence sed 2>/dev/null ; } [[ -n ${SED} ]] || EXIT="$EXIT sed" else SED="$P/bin/sed" fi P=${ pkgparam LNFawk BASEDIR 2>/dev/null ; } if [[ -z $P ]] ; then AWK=${ whence awk 2>/dev/null ; } [[ -n ${AWK} ]] || EXIT="$EXIT awk" else AWK="$P/bin/awk" fi P=${ pkgparam LNFgrep BASEDIR 2>/dev/null ; } if [[ -z "$P" ]] ; then GREP=${ whence grep 2>/dev/null ; } EGREP=${ whence egrep 2>/dev/null ; } [[ -n ${GREP} ]] || EXIT="$EXIT grep" [[ -n ${EGREP} ]] || EXIT="$EXIT egrep" else GREP="$P/bin/grep" EGREP="$P/bin/egrep" fi if [[ -n ${EXIT} ]]; then print -u2 "ERROR: Unable to find the programs $EXIT\n * Aborting *" exit 1 fi # Make sure /proc and /sys is mounted. if [[ ! -f /proc/cpuinfo ]]; then print -u2 " ERROR: It seems, that procfs isn't mounted on /proc. Do a '/sbin/mount -t proc -n procfs /proc' as root and try again. * Aborting *" exit 0 fi if [[ ! -d /sys/devices/system/cpu ]]; then print -u2 " WARNING: It seems, that sysfs isn't mounted on /sys Do a 'mount -t sysfs -n sysfs /sys' as root and try again. * System information (especially wrt. SCSI and environment) will be limited *" fi # If we're a sparc, make sure /proc/openprom is mounted. if [[ ${ARCHTYPE} == 'sparc' || ${ARCHTYPE} == 'sparc64' ]]; then if [[ ! -f /proc/openprom/name ]]; then print -u2 " ERROR: Can't find /proc/openprom/name! This means that /proc/openprom isn't mounted. Mount /proc/openprom and try again. * Aborting *" exit 0 fi fi if [[ ${ARCHTYPE} == 'sparc' || ${ARCHTYPE} == 'sparc64' \ || ${ARCHTYPE} == 'alpha' || ${ARCHTYPE} == 's390' ]] then DMIDECODE='' BIOSDECODE='' else if [[ -z ${DMIDECODE} || ! -x ${DMIDECODE} ]]; then DMIDECODE='' print -u2 " WARNING: A usable 'dmidecode' (package LNFdmidecode) was NOT found. * System information will be limited *" fi if [[ -z ${BIOSDECODE} || ! -x ${BIOSDECODE} ]]; then BIOSDECODE='' print -u2 " WARNING: A usable 'biosdecode' (package LNFdmidecode) was NOT found. * System information will be limited *" fi if [[ -n ${DMIDECODE} || -n ${BIOSDECODE} ]] && \ [[ ${ whoami ; } != 'root' ]] then DMIDECODE='' BIOSDECODE='' print -u2 " WARNING: prtdiag should be run as root. * System information will be limited *" fi fi if [[ -n ${LSPCI} && -x ${LSPCI} ]]; then : else print -u2 " WARNING: A usable 'lspci' (package LNFstatic-pciutils) was NOT found. * System information will be limited *" LSPCI='' fi if [[ ${SH_TYPES/e} != ${SH_TYPES} && ! -d /sys/class/hwmon ]]; then print -u2 " WARNING: NO hardware monitor found This means, that the system hasn't loaded any sensors module up to now. You may use 'sensors-detect' (package LNFlm-sensors) to find out the modules supported by your system. modprobe them manually or add their name to your /etc/default/modules file, so that they get loaded at the system startup automatically. * System information will be limited *" fi } function PrintReportHead { SYSTEMHOSTNAME=${ uname -n ; } TIMEOFREPORT=${ date ; } OS=${ uname -r -v ; } HEADFMT="%-17s: %s\n" printf "\n${HEADFMT}" 'System Hostname' "${SYSTEMHOSTNAME}" printf "${HEADFMT}" 'Time of Report' "${TIMEOFREPORT}" printf "${HEADFMT}" 'Operating System' "${OS}" } function PrintGeneralInfos { integer I print ' ============================= General Information ============================' HEADFMT='%-23s: %s\n' if [[ ${ARCHTYPE} == 'sparc' || ${ARCHTYPE} == 'sparc64' ]]; then SVENDOR='Oracle/Sun Microsystems' SMODEL=$(/dev/null ; } SVENDOR="${T#*Manufacturer: }" SVENDOR="${SVENDOR%%$'\n'*}" SMODEL="${T#*Product Name: }" SMODEL="${SMODEL%%$'\n'*}" fi [[ -n ${SVENDOR} ]] || SVENDOR='Unknown Vendor' [[ ${SVENDOR} != 'System Manufacturer' ]] || SVENDOR='Unknown Vendor' [[ -n ${SMODEL} ]] || SMODEL="Unknown Model" [[ ${SMODEL} != 'System Name' ]] || SMODEL='Unknown Model' fi printf "${HEADFMT}" 'System Configuration' \ "'${SVENDOR}' '${ARCHTYPE}' '${SMODEL}'" # System board info if [[ -n ${DMIDECODE} ]]; then typeset BVENDOR='' BMODEL='' BVERS='' BSN='' ${DMIDECODE} -t baseboard 2>/dev/null | while read T ; do if [[ ${T:0:13} == 'Manufacturer:' ]]; then BVENDOR="${T:14}" (( I++ )) elif [[ ${T:0:13} == 'Product Name:' ]]; then BMODEL="${T:14}" (( I++ )) elif [[ ${T:0:8} == 'Version:' ]]; then BVERS="${T:9}" (( I++ )) elif [[ ${T:0:14} == 'Serial Number:' ]]; then BSN="${T:15}" (( I++ )) fi done (( I )) && printf "${HEADFMT}" 'System board' \ "'${BMODEL}' '${BVERS}' '${BSN}' '${BVENDOR}'" fi # System clock - dmesg output might be large, that's why grep FREQ=${ dmesg |${GREP} 'System clock frequency' | cut -d " " -f 7 ; } if [[ -z ${FREQ} && -n ${DMIDECODE} ]]; then ${DMIDECODE} -t processor 2>/dev/null | while read T ; do [[ ${T:0:15} == 'External Clock:' ]] && FREQ=${T:16} && break done fi [[ -z ${FREQ} ]] && FREQ='???' printf "${HEADFMT}" 'System clock frequency' "${FREQ% MHz} MHz" integer MEM # Physical Memory if [[ -n $DMIDECODE ]]; then ${DMIDECODE} -t 6 2>/dev/null | while read T ; do if [[ ${T:0:15} == 'Installed Size:' ]]; then T=${T:16} I=${T%% *} (( MEM+=I )) fi done fi typeset Y='' if (( ! MEM )); then while read T ; do if [[ ${T:0:9} == 'MemTotal:' ]]; then T=${T:10} T=${T##*([[:space:]])} I=${T%%[[:space:]]*} (( MEM+=(I/1024) )) Y='~' break fi done < /proc/meminfo fi (( MEM )) && printf "${HEADFMT}" 'Memory size' "${Y}${MEM} MB" } function printCpuInfo { typeset -n LST=$1 typeset -n I=$2 typeset -n FMT=$3 if [[ -n ${I[id]} ]]; then LST+=${ printf "${FMT}" "${I[id]}" "${I[mhz]}" "${I[cache]}" \ "${I[bogo]}" "${I[model]}" ; }'\n' fi typeset X for X in ${!I[@]} ; do I[$X]='' done } function PrintCpuInfo { print ' ==================================== CPUs ====================================' OUT='' typeset -A INFO integer COUNT I typeset FMT='%3s %-8s %-8s %-8s %s' T X if [[ ${ARCHTYPE:0:5} == 'sparc' ]]; then while read T ; do [[ -z $T ]] && printCpuInfo OUT INFO FMT if [[ ${T:0:3} == 'cpu' ]]; then T=${T#*: } INFO[model]=${T%% *} elif [[ $T =~ ^Cpu[0-9]*Bogo ]]; then X=${T#*: } T=${.sh.match%%Bogo*} INFO[bogo]=${X%%.*} INFO[id]=${T:3} elif [[ $T =~ ^Cpu[0-9]*ClkTck ]]; then I=16#${T#*: } (( I/=1000000 )) INFO[mhz]=$I fi done < /proc/cpuinfo elif [[ ${ARCHTYPE:0:5} == 'alpha' ]]; then while read T ; do # only 1 KEY=${T%%+(\s):*} if [[ ${KEY} == 'cpu' ]]; then T="${T#*: }" INFO[model]="${T%% *}" (( COUNT++ )) elif [[ ${KEY} == 'cpu model' ]]; then INFO[model]+=" ${T#*: }" elif [[ ${KEY:15} == 'cycle frequency' ]]; then I=${T#*: } (( I/=1000000 )) INFO[mhz]=$I elif [[ ${KEY} == 'BogoMIPS' ]]; then X="${T#*: }" INFO[bogo]=${X%%.*} elif [[ ${KEY} == 'cpus detected' ]]; then INFO[id]=${T#*: } fi done < /proc/cpuinfo elif [[ ${ARCHTYPE:0:5} == 's390' ]]; then while read T ; do # only 1 KEY=${T%%+(\s):*} if [[ ${KEY} == '# processors' ]]; then INFO[id]=${T#*: } INFO[mhz]='variable' elif [[ ${KEY} == 'bogomips per cpu' ]]; then X="${T#*: }" INFO[bogo]=${X%%.*} elif [[ ${KEY} == 'version' ]]; then INFO[model]="${T#*: }" fi done < /proc/cpuinfo else # x86 while read T ; do [[ -z $T ]] && printCpuInfo OUT INFO FMT KEY=${T%%+(\s):*} if [[ ${KEY} == 'processor' ]]; then INFO[id]="${T#*: }" elif [[ ${KEY} == 'model name' ]]; then X=( ${T#*: } ) INFO[model]="${X[@]}" elif [[ ${KEY} == 'cpu MHz' ]]; then INFO[mhz]="${T#*: }" elif [[ ${KEY} == 'cache size' ]]; then INFO[cache]="${T#*: }" elif [[ ${KEY} == 'bogomips' ]]; then X="${T#*: }" INFO[bogo]=${X%%.*} fi done < /proc/cpuinfo fi if [[ ${ARCHTYPE:0:4} == 's390' || ${ARCHTYPE:0:5} == 'alpha' ]]; then COUNT=${INFO[id]} for (( I=0; I < COUNT; I++ )); do INFO[id]=$I printCpuInfo OUT INFO FMT done else printCpuInfo OUT INFO FMT fi if [[ -z ${OUT} ]]; then print '*** No CPU info found ***' exit 0 fi printf "${FMT}\n" 'CPU' 'Freq' 'Cache' 'Bogomips' 'CPU Implementation' printf "${FMT}\n" '---' '--------' '--------' '--------' '--------------------------------' print "${OUT}" } PrintPciInfo() { print " ================================= IO Devices =================================" if [ -n "$BIOSDECODE" ]; then SLOTINFO=`$BIOSDECODE 2>/dev/null | $GREP 'Slot Entry' | \ $SED -e 's,^.*ID ,SlotNum:,' -e 's/, slot number /:/' \ -e 's/, on-board/:MB/'` fi if [ -n "$LSPCI" ]; then PCIINFO=`$LSPCI -vmm 2>/dev/null | \ $EGREP '^(Slot|Class|Vendor|Device|ProgIf):' | \ $SED -r -e 's,:[[:space:]]*,:,' \ -e '/^Class:/ { s,[[:space:]]*controller,,i ; s,Multimedia[[:space:]]*([a-zA-Z][a-zA-Z]*),\1, ; s,audio,Audio, ; s,video,Video,}' \ -e '/^Class:(RAM|SCSI|VGA|FireWire)/ s,[[:space:]].*,,' \ -e '/^Device:[0-9][0-9]:/ s,^Device,Slot,'` CAPA=`$LSPCI -v 2>/dev/null | $SED -e 's,^[[:space:]]*,,' \ -e '/^[0-9a-f][0-9a-f]:/ { s,^,Slot:, ; s,[[:space:]],: , }' \ -e '/^Slot:/ { s,:[[:space:]].*prog-if[^[]*\[,:, ; s,].*$,:, ; s,[[:space:]].*,, }' \ -e '/^Capabilities:/ s,:[[:space:]]*\[[^]]*\][[:space:]]*,:,' \ -e 's,:[[:space:]]*,:,' | \ $EGREP '^(Slot|Flags|Capabilities):'` fi if [ -z "$SLOTINFO" -a -z "$PCIINFO" -a -z "$CAPA" ]; then print "***** Nothing found! *****" else print "${SLOTINFO}\n${PCIINFO}\n${CAPA}" | $AWK -F: ' function rep(c, n) { S="" ; for (i=1; i<=n; i++) { S = S "" c } ; return S } BEGIN { SLOT="-1" ; COUNT=0 ; SLOTCOUNT=0 } { if ($1 == "SlotNum") { SNO[$2 ":" $3] = $4 ; SLOTCOUNT++ } else if ($1 == "Slot") { SLOT=$2 ":" $3 if (MEM[SLOT] != 1) { SLOTS[COUNT] = SLOT COUNT++ MEM[SLOT] = 1 } else if ( NF > 3 && $4 ) { PIF[SLOT] = $4 } } else if ($1 == "Class") { CLASS[SLOT] = $2 } else if ($1 == "Vendor") { VENDOR[SLOT] = $2 } else if ($1 == "Device") { DEVICE[SLOT] = $2 } else if ($1 == "Flags") { if ( $2 ~ "66MHz" ) { MHZ[SLOT] = "66" } else { MHZ[SLOT] = "33" } } else if ($1 == "Capabilities" && ( $2 ~ "AGP" || DEVICE[SLOT] ~ "AGP")) { BUS[SLOT] = "AGP" } } END { if (COUNT < 1) { exit 0 } FMT="%-4s %-4s %-6s %-13s %s\n" printf(FMT, "Bus" , "Freq", "Slot", "Class +", "Vendor +") printf(FMT, "Type", "MHz" , "" , "ID" , "Model") printf(FMT, rep("-",4), rep("-",4) , rep("-",6), rep("-",13), rep("-",32)) for (i=0 ; i < COUNT; i++) { SLOT = SLOTS[i] if (CLASS[SLOT] ~ " bridge|RAM") { continue } if ( BUS[SLOT] == "AGP" ) { TYPE="agp" } else { TYPE="pci" } if ( MHZ[SLOT] == "" ) { MHZ[SLOT] = "??" } IDX=substr(SLOT,0,5) if ( SNO[IDX] ) { if ( SNO[IDX] == "MB" ) { SLOTNO="MB" } else { SLOTNO=toupper(TYPE) SNO[IDX] } } else if ( TYPE == "agp" ) { SLOTNO="AGP" } else if (SLOTCOUNT > 0) { SLOTNO="MB" } else { # probably permission for biosdecode denied SLOTNO="" } if ( CLASS[SLOT] == "SMBus" ) { TYPE="sm" SLOTNO="MB" } if (PIF[SLOT] ~ "HCI") { TYPE2=PIF[SLOT] } else { TYPE2="" } # tbd resolve PIF and add to CLASS printf(FMT, TYPE , MHZ[SLOT] , SLOTNO, CLASS[SLOT], VENDOR[SLOT]) printf(FMT, TYPE2 , "" , "" , SLOT , DEVICE[SLOT]) print "" } }' fi } PrintIdeInfo() { print " ================================ IDE Devices =================================" # sysfs is missing major information - so we need to use procfs [ -d /proc/ide ] && \ MODELS=`find /proc/ide -type f -name model | $EGREP '/hd[a-z]' | sort` if [ -z "$MODELS" ]; then print "*** No IDE devices found! ***" else FMT="%-6s %-9s %-6s %-13s %-16s %s\n" printf "$FMT" "Host" "Channel" "Device" "Vendor" "Model" "Type" printf "$FMT" "------" "---------" "------" "-------------" \ "----------------" "----------------" for MODEL in $MODELS ; do ICP=${MODEL%/*} IMEDIA=`cat ${ICP}/media | tr '[[:lower:]]' '[[:upper:]]'` [ "$IMEDIA" = "CDROM" ] && IMEDIA="CD-ROM" [ "$IMEDIA" = "DISK" ] && IMEDIA="PATA HDD" IVENDOR=`cut -d " " -f 1 $MODEL` IMODEL=`cut -d " " -f 2- $MODEL` ICHAN=${ICP##*/} IHOST=${ICP%/*} IHOST=${IHOST##*/} if [ -r "${ICP}/capacity" ]; then ST=$(<${ICP}/capacity) S=$((ST*512)) if [ "$S" -gt 0 ]; then IDX=0 while [ "${S}" -ge 1000.0 ]; do S=$(($S/1024.0)) IDX=$((IDX+1)) done SIZE=$(printf "%1.1f %s " "$S" "${UNITS[$IDX]}" ) else SIZE="" fi else SIZE="" fi # If the model is blank, assume the model is the vendor if [ -z "$IMODEL" ]; then IMODEL="$IVENDOR" IVENDOR="" fi # If the model == vendor, assume the model is the vendor if [ "$IMODEL" = "$IVENDOR" ]; then IMODEL="$IVENDOR" IVENDOR="" fi if [ -z "$IVENDOR" ]; then if [ "$IMODEL" != ${IMODEL#ST} ]; then IVENDOR="Seagate" elif [ "$IMODEL" != ${IMODEL#IC} ]; then IVENDOR="IBM" fi fi printf "$FMT" "$IHOST" "$ICHAN" "$ICHAN" \ "$IVENDOR" "$IMODEL" "${SIZE}$IMEDIA" done fi } PrintScsiInfo() { if [ "$ARCHTYPE" = "s390" ]; then print " ================================ DASD Devices ================================" if [ ! -f /proc/dasd/devices ]; then DASDCHANFOUND=false else cat /proc/dasd/devices fi else print " ================================ SCSI Devices ================================" [ -d /sys/class/scsi_device ] && \ SDEVS=$(ls -d /sys/class/scsi_device/*:* 2>/dev/null | sort) if [ -z "$SDEVS" ]; then print "*** No SCSI devices found! ***" else FMT="%-6s %2s %2s %3s %-6s %-13s %-16s %s\n" printf "$FMT" "Host" "Ch" "Id" "LUN" "Device" \ "Vendor" "Model" "Type" printf "$FMT" "------" "--" "--" "---" "------" \ "-------------" "----------------" "----------------" # see /usr/include/scsi/scsi.h: DEVICE TYPES set -A STYPES "SCSI HDD" "TAPE" "" "External Processor/HP Scanner" "WORM" "CD-ROM" "SCANNER" "MOD" "MEDIA CHANGER" for SDEV in $SDEVS ; do TARGET=${SDEV##*/} OLDIFS="$IFS" IFS=':' set -A T $TARGET HOST=${T[0]} CH=${T[1]} ID=${T[2]} LUN=${T[3]} IFS="$OLDIFS" X=$(<$SDEV/device/type) TYPENO=${X%%*( )} if [ "$TYPENO" = "13" ]; then TYPE="ENCLOSURE" else TYPE=${STYPES[$TYPENO]} fi X=$(<$SDEV/device/model) MODEL=${X%%*( )} X=$(<$SDEV/device/vendor) VENDOR=${X%%*( )} if [ "$VENDOR" = "ATA" ]; then VENDOR=${MODEL%% *} if [ "$VENDOR" = "$MODEL" ]; then if [ "$VENDOR" != ${VENDOR#ST} ]; then VENDOR="Seagate" elif [ "$VENDOR" != ${VENDOR#IC} ]; then VENDOR="IBM" fi fi TYPE="SATA HDD" fi # displaying all /dev/* would be e.g. for tapes too much - # one is enough. Also prefer none-generic devices ... X=$(ls -1d $SDEV/device/*:* 2>/dev/null| \ $EGREP -v '/scsi_(device|generic):' | sort|\ head -1) [ -n "$X" ] || X=$(ls -1d $SDEV/device/scsi_generic:* 2>/dev/null | head -1) DEV=${X##*:} if [ -n "$DEV" -a -r "$SDEV/device/block:$DEV/size" ]; then ST=$(<$SDEV/device/block:$DEV/size) S=$((ST*512)) if [ "${S}" -gt 0 ]; then IDX=0 while [ "${S}" -ge 1000.0 ]; do S=$(($S/1024.0)) IDX=$((IDX+1)) done SIZE=$(printf "%1.1f %s " "$S" "${UNITS[$IDX]}" ) else SIZE="" fi else SIZE="" fi MODEL=${MODEL#* } MODULE=$(< /sys/class/scsi_host/host${HOST}/proc_name) case $MODULE in usb-storage) TYPE="USB STORAGE" ;; sata*) TYPE="SATA HDD" ;; esac printf "$FMT" "scsi$HOST" "$CH" "$ID" "$LUN" "$DEV" \ "$VENDOR" "$MODEL" "${SIZE}$TYPE" done fi fi } PrintMemoryInfo() { print "\n============================ Memory Configuration ============================" if [ -n "$DMIDECODE" ]; then $DMIDECODE -t 17 -t 20 | \ $SED -e 's,^[[:space:]]*,,' -e 's,:[[:space:]]*,:,' \ -e 's,[[:space:]]*$,,' | $AWK -F: ' BEGIN { COUNT=0 ; HANDLE="-1" } { # "" may indicate an update problem, displat always if ( $1 ~ "^Handle" && $1 ~ "DMI type 17" ) { HANDLE=substr($1,8,6) HANDLES[COUNT] = HANDLE COUNT++ } else if ( $1 == "Size" ) { SIZE[HANDLE] = $2 } else if ( $1 == "Form Factor" ) { FORM[HANDLE] = $2 } else if ( $1 == "Locator") { LOC[HANDLE] = $2 } else if ( $1 == "Bank Locator" ) { BANK[HANDLE] = $2 } else if ( $1 == "Type" && $2 != "Unknown" && $2 != "Other") { TYPE[HANDLE] = $2 } else if ( $1 == "Type Detail" && $2 != "Unknown" && $2 != "Other" \ && $2 != "None" ) { TYPEDETAIL[HANDLE] = $2 } else if ( $1 == "Starting Address" ) { TSTART=$2 } else if ( $1 == "Ending Address" ) { TEND=$2 } else if ($1 == "Physical Device Handle") { HANDLE=$2 ASTART[HANDLE] = TSTART AEND[HANDLE] = TEND } } END { if (COUNT < 1) { print "*** No memory information available *** " exit 0 } FMT = "%13s %7s %-10s %s\n" printf(FMT, "Base Address ", "Size ", "Location", "Type") printf(FMT, "-------------", "-------", "----------", "----------------") for (i=0; i < COUNT ; i++) { HANDLE=HANDLES[i] if ( SIZE[HANDLE] == "No Module Installed" ) { continue } if (LOC[HANDLE]) { L = LOC[HANDLE] } else { L = BANK[HANDLE] } T="" N=0 if (FORM[HANDLE]) { T=FORM[HANDLE] " " } if (TYPE[HANDLE] ) { T=T TYPE[HANDLE] " " } if (TYPEDETAIL[HANDLE] ) { T=T TYPEDETAIL[HANDLE] } printf(FMT, ASTART[HANDLE], SIZE[HANDLE], L, T) } } ' else print "*** No memory information available *** " fi } PrintSensorInfo() { print " ============================ Environmental Status ============================" OLDIFS="$IFS" # FANs [ -d /sys/class/hwmon ] && \ FANS=$(find /sys/class/hwmon -follow -maxdepth 3 \ -name "fan[[:digit:]]*_input" 2>/dev/null | sort) if [ -z "$FANS" ]; then print "*** No fans found ***" else HFMT="%-10s %6s %s\n" FMT="%-10s %6d %s\n" printf "$HFMT" "Sensor" " RPM " "Source" printf "$HFMT" "----------" "------" "----------------" for FAN in $FANS ; do TPATH=${FAN%/*} SENSOR=$(<$TPATH/name) TARGET=${FAN##*/} NO=${TARGET#fan} NO=${NO%_input} FDIV="$TPATH/fan${NO}_div" NO=$((NO-1)) if [ -n "${FAN_IGNORE[$SENSOR]}" ]; then IFS="," set -A CNAMES ${FAN_IGNORE[$SENSOR]} IFS="$OLDIFS" FACTOR=${CNAMES[$NO]} if [ -n "$FACTOR" ]; then continue fi fi typeset -F SPEED=$(<$FAN) # Not reliable: On some systems it is already taken into account, on others not # Adjust via FAN_FACTOR in prtdiag.conf, if neccesarry # if [ -r "$FDIV" ]; then # D=$(<$FDIV) # [ -n "$D" ] && SPEED=$((SPEED/D)) # fi NAME="Fan $NO" if [ -n "${FAN_SRC[$SENSOR]}" ]; then IFS="," set -A CNAMES ${FAN_SRC[$SENSOR]} IFS="$OLDIFS" CNAME=${CNAMES[$NO]} if [ -n "$CNAME" ]; then NAME=$CNAME fi fi if [ -n "${FAN_FACTOR[$SENSOR]}" ]; then IFS="," set -A CNAMES ${FAN_FACTOR[$SENSOR]} IFS="$OLDIFS" FACTOR=${CNAMES[$NO]} if [ -n "$FACTOR" ]; then SPEED=$((SPEED*FACTOR)) fi fi if [ -n "${FAN_OFFSET[$SENSOR]}" ]; then IFS="," set -A CNAMES ${FAN_OFFSET[$SENSOR]} IFS="$OLDIFS" FACTOR=${CNAMES[$NO]} if [ -n "$FACTOR" ]; then SPEED=$((SPEED+FACTOR)) fi fi printf "$FMT" "$SENSOR" "$SPEED" "$NAME" done fi # Temperatures [ -d /sys/class/hwmon ] && \ TEMPS=$(find /sys/class/hwmon -follow -maxdepth 3 \ -name "temp[[:digit:]]*_input" 2>/dev/null | sort) if [ -z "$TEMPS" ]; then print "*** No temperature sensors found ***" else HFMT="%-10s %-6s %s\n" FMT="%-10s %6.1f %s\n" if [ -z "$CELSIUS" ]; then SUFFIX="°F" else SUFFIX="°C" fi print printf "$HFMT" "Sensor" " $SUFFIX " "Source" printf "$HFMT" "----------" "------" "----------------" for T in $TEMPS ; do TPATH=${T%/*} SENSOR=$(<$TPATH/name) TARGET=${T##*/} NO=${TARGET#temp} NO=${NO%_input} NO=$((NO-1)) if [ -n "${TEMP_IGNORE[$SENSOR]}" ]; then IFS="," set -A CNAMES ${TEMP_IGNORE[$SENSOR]} IFS="$OLDIFS" FACTOR=${CNAMES[$NO]} if [ -n "$FACTOR" ]; then continue fi fi VALUE=$(<$T) if [ -z "$CELSIUS" ]; then typeset -F DEGREES=$((VALUE*9/5000.0+32.0)) else typeset -F DEGREES=$((VALUE/1000.0)) fi NAME="Temp $NO" if [ -n "${TEMP_SRC[$SENSOR]}" ]; then IFS="," set -A CNAMES ${TEMP_SRC[$SENSOR]} IFS="$OLDIFS" CNAME=${CNAMES[$NO]} if [ -n "$CNAME" ]; then NAME=$CNAME fi fi if [ -n "${TEMP_FACTOR[$SENSOR]}" ]; then IFS="," set -A CNAMES ${TEMP_FACTOR[$SENSOR]} IFS="$OLDIFS" FACTOR=${CNAMES[$NO]} if [ -n "$FACTOR" ]; then DEGREES=$((DEGREES*FACTOR)) fi fi if [ -n "${TEMP_OFFSET[$SENSOR]}" ]; then IFS="," set -A CNAMES ${TEMP_OFFSET[$SENSOR]} IFS="$OLDIFS" FACTOR=${CNAMES[$NO]} if [ -n "$FACTOR" ]; then DEGREES=$((DEGREES+FACTOR)) fi fi printf "$FMT" "$SENSOR" "$DEGREES" "$NAME" done fi # Voltage [ -d /sys/class/hwmon ] && \ VOLTS=$(find /sys/class/hwmon -follow -maxdepth 3 \ -name "in[[:digit:]]*_input" 2>/dev/null | sort) if [ -z "$VOLTS" ]; then print "*** No voltage sensors found ***" else set -A SRC "CPU #1 (Vcor1)" "CPU #2 (Vcor2)" "+3.3V" "+5V" "+12V" "-12V" "-5V" "Standby" "Battery" HFMT="%-10s %6s %s\n" FMT="%-10s %6.2f %s\n" print printf "$HFMT" "Sensor" " Volt " "Source" printf "$HFMT" "----------" "------" "----------------" for T in $VOLTS ; do TPATH=${T%/*} SENSOR=$(<$TPATH/name) TARGET=${T##*/} NO=${TARGET#in} NO=${NO%_input} if [ -n "${VOLT_IGNORE[$SENSOR]}" ]; then IFS="," set -A CNAMES ${VOLT_IGNORE[$SENSOR]} IFS="$OLDIFS" FACTOR=${CNAMES[$NO]} if [ -n "$FACTOR" ]; then continue fi fi VALUE=$(<$T) NAME=${SRC[$NO]} [ -n "$NAME" ] || NAME="in$NO" if [ -n "${VOLT_SRC[$SENSOR]}" ]; then IFS="," set -A CNAMES ${VOLT_SRC[$SENSOR]} IFS="$OLDIFS" CNAME=${CNAMES[$NO]} if [ -n "$CNAME" ]; then NAME=$CNAME fi fi typeset -F VOLT=$((VALUE/1000.0)) if [ -n "${VOLT_FACTOR[$SENSOR]}" ]; then IFS="," set -A CNAMES ${VOLT_FACTOR[$SENSOR]} IFS="$OLDIFS" FACTOR=${CNAMES[$NO]} if [ -n "$FACTOR" ]; then VOLT=$((VOLT*FACTOR)) fi fi if [ -n ${VOLT_OFFSET[$SENSOR]} ]; then IFS="," set -A CNAMES ${VOLT_OFFSET[$SENSOR]} IFS="$OLDIFS" FACTOR=${CNAMES[$NO]} if [ -n "$FACTOR" ]; then VOLT=$((VOLT+FACTOR)) fi fi printf "$FMT" "$SENSOR" "$VOLT" "$NAME" done fi } PrintBiosInfo() { print " ============================ BIOS/PROM Information ===========================" if [ -n "$DMIDECODE" ]; then $DMIDECODE -t bios 2>/dev/null | $EGREP '(Vendor|Version|Date):' | \ $SED -e 's,^[[:space:]]*, ,' else print "*** No BIOS information available" fi } VERS="${.sh.version}" if [ "${VERS#*93}" = "${VERS}" ]; then echo " WARNING: This is not a ksh93 from AT&T Research! Neither bash nor pdksh, etc. are kompatible to ksh93. So this program will probably produce errors and may not display the results you want. Download and install the appropriate package from your Linux distribution or direct via http://www.research.att.com/~gsf/download/ ! " fi set -A UNITS "B" "KiB" "MiB" "GiB" "TiB" "PiB" "EiB" "ZiB" "YiB" LoadCustomizations CheckEnvironment [ -z "$SH_RHEAD" ] || PrintReportHead [ "${SH_TYPES//g}" == ${SH_TYPES} ] || PrintGeneralInfos [ "${SH_TYPES//c}" == ${SH_TYPES} ] || PrintCpuInfo [ "${SH_TYPES//p}" == ${SH_TYPES} ] || PrintPciInfo [ "${SH_TYPES//i}" == ${SH_TYPES} ] || PrintIdeInfo [ "${SH_TYPES//s}" == ${SH_TYPES} ] || PrintScsiInfo [ "${SH_TYPES//m}" == ${SH_TYPES} ] || PrintMemoryInfo [ "${SH_TYPES//e}" == ${SH_TYPES} ] || PrintSensorInfo [ "${SH_TYPES//b}" == ${SH_TYPES} ] || PrintBiosInfo print ""