#!/bin/ksh
#< Highly detailed Solaris system information gathering script
# Description:
# Display various groups of system inforamtion. The script is designed to be
# easily extendable by adding process_command "command" directives, and appending
# filenames to the list of FILES to check
#
# Kevin Waldron 2006
BASENAME="/usr/bin/basename"
CAT="/usr/bin/cat"
CENTRE_STRING="/home/kevin/bin/centre_string"
DATE="/usr/bin/date"
ECHO="/usr/bin/echo"
GREP="/usr/bin/grep"
HOSTNAME="/usr/bin/hostname"
LAST="/usr/bin/last"
TR="/usr/bin/tr"
HEAD="/usr/bin/head"
UNAME="/usr/bin/uname"
PRTDIAG="/usr/platform/$( ${UNAME} -i )/sbin/prtdiag"
EEPROM="/usr/platform/$( ${UNAME} -i )/sbin/eeprom"
ISAINFO="/usr/bin/isainfo"
PSRINFO="/usr/sbin/psrinfo"
PRTCONF="/usr/sbin/prtconf"
SYSDEF="/usr/sbin/sysdef"
WHO="/usr/bin/who"
WHODO="/usr/sbin/whodo"
W="/usr/bin/w"
IFCONFIG="/usr/sbin/ifconfig"
NETSTAT="/usr/bin/netstat"
NDD="/usr/sbin/ndd"
LS="/usr/bin/ls"
SED="/usr/bin/sed"
AWK="/usr/bin/awk"
PRINTF="/usr/bin/printf"
WHOAMI="/usr/ucb/whoami"
FORMAT="/usr/sbin/format"
SWAP="/usr/sbin/swap"
DF="/usr/sbin/df"
PRSTAT="/usr/bin/prstat"
IOSTAT="/usr/bin/iostat"
MPSTAT="/usr/bin/mpstat"
VMSTAT="/usr/bin/mpstat"
PS="/usr/bin/ps"
EGREP="/usr/bin/egrep"
DMESG="/usr/sbin/dmesg"
SHOWREV="/usr/bin/showrev"
PKGINFO="/usr/bin/pkginfo"
UPTIME="/usr/bin/uptime"
METASTAT="/usr/sbin/metastat"
METADB="/usr/sbin/metadb"
VXDISK="/usr/sbin/vxdisk"
VXPRINT="/usr/sbin/vxprint"
VXDG="/usr/sbin/vxdg"
PRTVTOC="/usr/sbin/prtvtoc"
SVCS="/usr/bin/svcs"
INETADM="/usr/sbin/inetadm"
THISPROG=$( ${BASENAME} $0 )
VERBOSE=0
CS_WIDTH=80
CS_CHAR_1="-"
CS_CHAR_2="*"
HTML=0
VALID_GROUPS="all system network disk vxvm capacity files logs snapshot user software"
MAJOR_VERSION=0
MINOR_VERSION=1
VERSION="${MAJOR_VERSION}.${MINOR_VERSION}"
echo_debug() {
echo "-[debug]- $@" >&2
}
echo_stderr() {
echo "$@" >&2
}
usage() {
echo_stderr "${THISPROG} [-v] [-g group_1[,group_2,...]] [-H]"
echo_stderr " -g group_1,group_2 Display specific info groups"
echo_stderr " -l List available info groups then exit"
echo_stderr " -H Output in HTML"
echo_stderr " -v Print development debug messages"
exit 1
}
list_info_groups() {
echo_stderr "Valid info groups are: ${VALID_GROUPS}"
exit 6
}
display_header() {
(( HTML )) && {
HEADER=$( ${ECHO} "$1" | ${SED} -e 's/\&/\&/' -e 's/</\</g' -e 's/>/\>/g' )
${ECHO} "<h2>${HEADER}</h2>"
} || {
${ECHO}
${CENTRE_STRING} ${CS_WIDTH} "${CS_CHAR_2}" ""
${CENTRE_STRING} ${CS_WIDTH} "${CS_CHAR_1}" "$1"
${CENTRE_STRING} ${CS_WIDTH} "${CS_CHAR_2}" ""
${ECHO}
}
}
display_command_syntax() {
(( HTML )) && {
${ECHO} "<h3><tt>$@</tt></h3>"
} || {
${ECHO}
${ECHO} "###### $@"
${ECHO}
}
}
display_intro() {
(( HTML )) && {
${ECHO} "<html>"
${ECHO} "<head>"
${ECHO} "<title>SYSTEM INFORMATION REPORT FOR $( ${HOSTNAME} )</title>"
${ECHO} "</head>"
${ECHO} "<body>"
${ECHO} "<h2>SYSTEM INFORMATION REPORT FOR $( ${HOSTNAME} )<br>$( ${DATE} )</h2>"
} || {
display_header " SYSTEM INFORMATION REPORT FOR $( ${HOSTNAME} ) - $( ${DATE} ) "
}
}
process_command() {
COMMAND_BUFFER="$@"
display_command_syntax "${COMMAND_BUFFER}"
BINARY=$( ${ECHO} "${COMMAND_BUFFER}" | ${AWK} '{print $1}' )
if [ ! -e "${BINARY}" ]; then
echo_stderr "Error: ${BINARY} does not exist"
elif [ ! -x "${BINARY}" ]; then
echo_stderr "Error: ${BINARY} is not executable"
else
(( HTML )) && echo "<pre>"
(( HTML )) && {
eval ${COMMAND_BUFFER} | ${SED} -e 's/\&/\&/' -e 's/</\</g' -e 's/>/\>/g'
} || {
eval ${COMMAND_BUFFER}
}
(( HTML )) && echo "</pre>"
fi
}
display_system_info() {
(( VERBOSE )) && echo_debug "display_system_info()"
display_header "< SYSTEM INFORMATION >"
process_command "${UNAME} -a"
display_command_syntax "${ECHO} \$TZ"
COMMAND_BUFFER="${ECHO} ${TZ}"
eval ${COMMAND_BUFFER}
process_command "${UPTIME}"
process_command "${WHO} -r"
process_command "${PRTDIAG} -v"
process_command "${EEPROM}"
process_command "${ISAINFO} -kv"
process_command "${PSRINFO}"
process_command "${PSRINFO} -v"
process_command "${PRTCONF} -v"
process_command "${PRTCONF} -V"
process_command "${SYSDEF}"
RELEASE=$( ${UNAME} -r )
if [ "${RELEASE}" = "5.10" ]; then
process_command "${SVCS} -a"
process_command "${INETADM}"
fi
}
display_network_info() {
(( VERBOSE )) && echo_debug "display_network_info()"
display_header "< NETWORK INFORMATION >"
process_command "${IFCONFIG} -a"
process_command "${NETSTAT} -ivn"
process_command "${NETSTAT} -rn"
process_command "${NETSTAT} -an"
if [ "$( ${WHOAMI} )" = "root" ]; then
${LS} /etc/hostname* | ${SED} 's/^[^.]*\.\([^.]*\)$/\1/' | while read INTERFACE; do
${ECHO} ${INTERFACE} | ${GREP} ":" >/dev/null 2>&1
if [ "$?" -eq "0" ]; then
echo_stderr "Skipping interface ${INTERFACE}"
else
${ECHO} ${INTERFACE} | grep "bge" >/dev/null 2>&1
if [ "$?" -ne "0" ]; then
instance=`${ECHO} ${INTERFACE} | ${SED} 's/^[a-z][a-z]*\([0-9]\)$/\1/'`
INTERFACE=`${ECHO} ${INTERFACE} | ${SED} 's/^\([a-z][a-z]*\)[0-9]$/\1/'`
process_command "${NDD} -set /dev/${INTERFACE} instance ${instance}"
fi
(( HTML )) && {
${ECHO} "<pre>"
}
${NDD} -get /dev/${INTERFACE} \? |\
${AWK} '/^adv/ {print $1}' | while read param; do
setting=`${NDD} -get /dev/${INTERFACE} ${param}`
${PRINTF} "%25s:\t%s\n" "${param}" "${setting}"
done
(( HTML )) && {
${ECHO} "</pre>"
}
fi
done
fi
}
display_disk_info() {
(( VERBOSE )) && echo_debug "display_disk_info()"
display_header "< DISK INFORMATION >"
if [ "$( ${WHOAMI} )" = "root" ]; then
process_command "${FORMAT} < /dev/null"
${LS} /dev/rdsk | ${GREP} "s2" | while read RAW; do
process_command "${PRTVTOC} /dev/rdsk/${RAW}"
done
fi
process_command "${METASTAT}"
process_command "${METASTAT} -p"
process_command "${METADB}"
process_command "${IOSTAT} -En"
}
display_vxvm_info() {
(( VERBOSE )) && echo_debug "display_vxvm_info()"
display_header "< VXVM INFORMATION >"
if [ ! -d "/etc/vx" ]; then
echo_stderr "Error: It doesn't look like Veritas Volume Manager is installed!"
return
fi
if [ "$( ${WHOAMI} )" = "root" ]; then
process_command "${VXDISK} list"
${VXDISK} list | ${SED} '1d' | ${AWK} '{print $3}' | while read DISK; do
process_command "${VXDISK} list ${DISK}"
done
process_command "${VXDG} list"
${VXDG} list | ${SED} '1d' | ${AWK} '{print $3}' | while read DISK; do
process_command "${VXDG} list ${DISK}"
done
fi
process_command "${VXPRINT}"
}
display_capacity_info() {
(( VERBOSE )) && echo_debug "display_capacity_info()"
display_header "< CAPACITY INFORMATION >"
process_command "${SWAP} -l"
process_command "${DF} -k"
}
display_files_info() {
(( VERBOSE )) && echo_debug "display_files_info()"
display_header "< SYSTEM FILES INFORMATION >"
HOSTNAME_FILES=`eval ${ECHO} /etc/hostname*`
FILES="/etc/release /etc/hosts ${HOSTNAME_FILES} /etc/defaultrouter /etc/netmasks /etc/vfstab /etc/system /etc/inet/ntp.
conf"
FILES="${FILES} /etc/inittab"
for FILENAME in ${FILES}; do
if [ -e "${FILENAME}" ]; then
COMMAND_BUFFER="${CAT} ${FILENAME}"
display_command_syntax "${COMMAND_BUFFER}"
(( HTML )) && ${ECHO} "<pre>"
eval ${COMMAND_BUFFER} | ${SED} -e 's/\&/\&/' -e 's/</\</g' -e 's/>/\>/g'
(( HTML )) && ${ECHO} "</pre>"
else
echo_stderr "Error: ${FILENAME} does not exist"
fi
done
}
display_logs_info() {
(( VERBOSE )) && echo_debug "display_logs_info()"
display_header "< LOGFILE INFORMATION >"
MESSAGES="/var/adm/messages"
process_command "${EGREP} -i 'error|warn' ${MESSAGES}"
process_command "${DMESG}"
}
display_user_info() {
(( VERBOSE )) && echo_debug "display_user_info()"
display_header "< USER INFORMATION >"
process_command "${WHO}"
process_command "${W}"
process_command "${WHODO}"
process_command "${LAST} | ${HEAD} -50"
process_command "${CAT} /etc/passwd"
process_command "${CAT} /etc/group"
}
display_software_info() {
(( VERBOSE )) && echo_debug "display_user_info()"
display_header "< SOFTWARE INFORMATION >"
process_command "${PKGINFO}"
process_command "${SHOWREV} -p"
}
display_snapshot() {
(( VERBOSE )) && echo_debug "display_snapshot()"
display_header "< SYSTEM ACTIVITY SNAPSHOT >"
process_command "${PRSTAT} 1 1"
process_command "${VMSTAT} 1 10"
process_command "${MPSTAT} 1 10"
process_command "${IOSTAT} 1 10"
process_command "${PS} -ef"
}
display_all_info() {
(( VERBOSE )) && echo_debug "display_all_info()"
display_system_info
display_network_info
display_disk_info
display_vxvm_info
display_capacity_info
display_files_info
display_logs_info
display_user_info
display_snapshot
display_software_info
}
while getopts ":lg:Hvh" ARG; do
case "${ARG}" in
"g") INFO_GROUPS="${OPTARG}"
;;
"l") list_info_groups
;;
"v") VERBOSE=1
;;
"H") HTML=1
;;
"h"|*) usage
;;
esac
done
shift $(( ${OPTIND} - 1 ))
if [ "$#" -ne "0" ]; then
usage
fi
if [ ! -e "${CENTRE_STRING}" ]; then
echo_stderr "Error: centre_string cannot be found!"
exit 3
fi
if [ "$( ${UNAME} -s )" != "SunOS" ]; then
echo_stderr "Error: this script is designed to run on Solaris systems only!"
# no solaris 10 functionality yet, alas!
exit 4
fi
if [ -z "${INFO_GROUPS}" ]; then
INFO_GROUPS="all"
fi
COUNTER=0
${ECHO} "${INFO_GROUPS}" | tr "," "\n" | while read TMP_GROUP; do
INFO_GROUP[${COUNTER}]=${TMP_GROUP}
(( COUNTER = COUNTER + 1 ))
done
COUNTER=0
NUM_GROUPS=${#INFO_GROUP[@]}
display_intro
while [[ "${COUNTER}" -lt "${NUM_GROUPS}" ]]; do
${ECHO} "${VALID_GROUPS}" | ${GREP} "${INFO_GROUP[${COUNTER}]}" >/dev/null 2>&1
if [ "$?" -ne "0" ]; then
echo_stderr "Error: ${INFO_GROUP[${COUNTER}]} is not a valid info group"
echo_stderr "Valid info groups are: ${VALID_GROUPS}"
exit 2
fi
ACTION_GROUP="${INFO_GROUP[${COUNTER}]}"
case "${ACTION_GROUP}" in
"all") display_all_info ;;
"system") display_system_info ;;
"network") display_network_info ;;
"disk") display_disk_info ;;
"vxvm") display_vxvm_info ;;
"capacity") display_capacity_info ;;
"files") display_files_info ;;
"logs") display_logs_info ;;
"user") display_user_info ;;
"snapshot") display_snapshot ;;
"software") display_software ;;
esac
(( COUNTER = COUNTER + 1 ))
done
(( HTML )) && {
echo "</body>"
echo "</html>"
}
exit 0