Commit 9457013f authored by Dan Reading's avatar Dan Reading
Browse files

diskspeedcheck working - at least on FreeBSD

parent 475d8592
# set -u should done before calling
# return a list of the drives on the system
# use smartctl, /dev, df, fstab, dmesg etc.
# arg1 - filename to hold logging info
# arg2 - filename to hold runtime output
# returns space sperated list of drive names IN "smartctl --scan" format
NOSM="echo"
SMARTCTL=$(which smartctl)
if [ -z "${SMARTCTL}" ] ; then
if [ -x "/usr/sbin/smartctl" ]; then
SMARTCTL="/usr/sbin/smartctl"
else
SMARTCTL=$NOSM
findSmartctl() {
local NOSM="echo"
SMARTCTL=$(which smartctl)
if [ -z "${SMARTCTL}" ] ; then
if [ -x "/usr/sbin/smartctl" ]; then
SMARTCTL="/usr/sbin/smartctl"
else
SMARTCTL=$NOSM
fi
fi
fi
}
getdriveinfo () {
#need to make sure smartcrl is installed
findSmartctl
{
# echo -n "${FUNCNAME[0]}:${LINENO} " ; echo "args::$@::"
declare buildscan=""
......@@ -105,3 +98,57 @@ esac
echo -n "${scan[@]}"
}
# The timesys function terminates its script unless it terminates earlier on its own
# args: max_time output_file command command_args
timesys() {
maxtime="$1"; shift;
out="$1" ; shift;
command="$1"; shift;
args="$*"
me_pid=$$;
sleep $maxtime &
timer_pid=$!
{
$command $args &
command_pid=$!
wait ${timer_pid}
kill -2 ${command_pid}
} > $out 2>&1
}
# Internally used
declare FUNCDEBUG=n
declare ECHOCMDS=n
#TOUPPER() { $(echo $@ |tr 'a-z' 'A-Z') }
#TOLOWER() { $(echo ${@,,}) }
# Function Tracing
funcdebug ()
{
[[ $FUNCDEBUG = y ]] && echo -e " ====> $(/bin/date +%k:%M:%S) $@" >&2
return 0
}
# command debugging
runCmd ()
{
if [[ $ECHOCMDS = y ]] ; then
echo " =CMD> $@" >&2
fi
eval $@
return $?
}
# skeleton function
functionSkel ()
{
funcdebug $FUNCNAME:$LINENO enter $@
printf "PROGRAMMING ERROR $FUNCNAME $LINENO \n" && exit 1
funcdebug $FUNCNAME:$LINENO leave
return 0
}
......@@ -7,19 +7,18 @@ echo -n ' Starting diskcheck..'
# first arg is the log output file, if not set then /tmp/...
#Global
declare SMARTCTL=''
declare failed=""
declare error=""
declare err=""
source getfromtb.sh
source hbis.sh
source checkutils.sh
SMARTCTL=""
failed=""
error=""
err=""
os=`uname -s`
host=`hostname`
if [ -e "/var/emulab/boot/realname" ]; then
host=`cat /var/emulab/boot/realname`
fi
# setup logging
if [ $1 ] ; then
......@@ -27,93 +26,41 @@ if [ $1 ] ; then
else
logfile="/tmp/nodecheck.log"
fi
#exit on unbound var, set after sourcing files
set -u
os=`uname -s`
host=`hostname`
if [ -e "/var/emulab/boot/realname" ]; then
host=`cat /var/emulab/boot/realname`
fi
tmplog=/tmp/.$$.log
cat /dev/null > ${tmplog}
#exit on unbound var
set -u
tmpout=/tmp/.$$tmpout.log ; touch ${tmpout}
logout=/tmp/.$$logout.log ; touch ${logout}
#need to make sure smartcrl is installed - not by default on our linux images
{
SMARTCTL=$(which smartctl)
if [ -z "${SMARTCTL}" ] ; then
if [ -x "/usr/sbin/smartctl" ]; then
SMARTCTL="/usr/sbin/smartctl"
fi
fi
if [ -x "${SMARTCTL}" ] ; then
rtn=$($SMARTCTL --scan)
# unrecongnized
if [ -n "$(echo $rtn | grep 'UNRECOGNIZED OPTION')" ] ; then
error="(smartctl option '--scan' not supported. Attempt alternet method) "
err=scan
elif [ -n "$(echo $rtn | grep -v 'device')" ] ; then
# output in unexpected format - missing deliminator "device"
error="(smartctl option '--scan' strange ouput. Attempt alternet method) "
err=scan
# empty
elif [ -z "$rtn" ] ; then
dt=$(df / | grep /dev)
dt=${dt:5}
dt=${dt%% *}
error="(smartctl device_type '$dt' not supported"
err=device
fi
[[ $error ]] && echo "$error"
else
error="smartmontools missing."
err="missing"
echo "$error. FAIL"
fi
} > ${tmplog} 2>&1
disknames=$(getdriveinfo ${logout} ${tmpout})
cat ${tmpout} ; rm -f ${tmpout}
echo "diskcheck `date`" >> ${logfile}
cat ${tmplog} >> ${logfile}
cat ${logout} >> ${logfile} ; rm -f ${logout}
#echo "" ; echo -n "$0:${LINENO} " ; echo disknames:${disknames}:
if [ -z "$disknames" ] ; then
echo "No drives found. exit"
exit 1
fi
unset -v scan; declare -a scan=(${disknames// / })
echo -n "$0:${LINENO} " ; echo scan:"${scan[@]}":
# the index into dirveinv array
name=0; driver=1; type=2; size=3; temp=4; model=5; serial=6;
unset -v driveinv ; declare -a driveinv=()
# put smartctl --scan into driveinv array
# a better control flow control could be used
case $err in
scan )
placeholder=" . . . . . device"
case $os in
Linux )
list="a b c d e f g h i j k l m n o p"
for i in $list
do
if [ -b /dev/sd${i} ] ; then
buildscan+="/dev/sd${i} $placeholder"
fi
done
;;
FreeBSD )
list="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"
for i in $list
do
[[ -b /dev/da${i} ]] && buildscan+="/dev/da${i} $placeholder "
[[ -c /dev/ad${i} ]] && buildscan+="/dev/ad${i} $placeholder "
done
;;
* )
echo "Internal error"
exit
;;
esac
declare -a scan=($buildscan)
;;
missing | device )
echo "$error. FAIL"
exit
;;
* )
# get the output of --scan into array scan
unset -v scan ; declare -a scan=($rtn)
;;
esac
#now split up each line using 'device' into the array drivescan
# This is an example of the string we are parsing:
# '/dev/sdb -d scsi # /dev/sdb, SCSI device'
......@@ -125,8 +72,6 @@ for elm in ${scan[@]} ; do
[[ "${elm}" == "device" ]] && ((++y))
set -u
done
#echo ------------------- ${drivescan[@]}
for ((idx=0; idx<${#drivescan[*]}; idx++)) ; do
unset -v d ; declare -a d=(${drivescan[$idx]})
lend=${#d[*]} ; x=$((lend - 2))
......@@ -137,20 +82,20 @@ for ((idx=0; idx<${#drivescan[*]}; idx++)) ; do
sname="${lname:5}"
[[ "$sname" == "pass2" ]] && break # /dev/pass2 on freebsd is tape device, skip
driveinv[$idx]="$sname"
#if we did not get any info then fill in value meaning unknown.
[[ ${#driveinv[*]} -eq $cnt ]] && driveinv[$idx]="MissingCMD"
#if we did not get any info then fillin value meaning unknown.
[[ ${#driveinv[*]} -eq $cnt ]] && driveinv[$idx]="MissingDRIVE"
driveinv[$idx]+=" "
#driver
cnt=${#driveinv[$idx]}
driveinv[$idx]+="${d[2]}"
[[ ${#driveinv[idx]} -eq $cnt ]] && driveinv[$idx]+="UKN"
[[ ${#driveinv[idx]} -eq $cnt ]] && driveinv[$idx]+="UNK"
driveinv[$idx]+=" "
#type
cnt=${#driveinv[$idx]}
driveinv[$idx]+="${d[$x]}"
[[ ${#driveinv[idx]} -eq $cnt ]] && driveinv[$idx]+="UKN"
[[ ${#driveinv[idx]} -eq $cnt ]] && driveinv[$idx]+="UNK"
driveinv[$idx]+=" "
#size
......@@ -160,10 +105,10 @@ for ((idx=0; idx<${#drivescan[*]}; idx++)) ; do
driveinv[$idx]+="$sz"
else
x=$($SMARTCTL -i ${d[0]} | grep -i "capacity" | awk '{print $3}' | sed s/,//g)
[[ $x ]] && sz=$(hbis $x) || sz="UKN"
[[ $x ]] && sz=$(hbis $x) || sz="UNK"
driveinv[$idx]+="$sz"
fi
[[ ${#driveinv[idx]} -eq $cnt ]] && driveinv[$idx]+="UKN"
[[ ${#driveinv[idx]} -eq $cnt ]] && driveinv[$idx]+="UNK"
driveinv[$idx]+=" "
#temp
......@@ -174,7 +119,7 @@ for ((idx=0; idx<${#drivescan[*]}; idx++)) ; do
#type 2
driveinv[$idx]+="$($SMARTCTL -a ${d[0]} | grep -i "Current Drive Temperature:" | awk '{print $4}')"
fi
[[ ${#driveinv[idx]} -eq $cnt ]] && driveinv[$idx]+="UKN"
[[ ${#driveinv[idx]} -eq $cnt ]] && driveinv[$idx]+="UNK"
driveinv[$idx]+=" "
#vendor product
......@@ -185,12 +130,13 @@ for ((idx=0; idx<${#drivescan[*]}; idx++)) ; do
#type 2
driveinv[$idx]+="$($SMARTCTL -i ${d[0]} | grep -i "Product:" | awk '{print $2}')"
fi
[[ ${#driveinv[idx]} -eq $cnt ]] && driveinv[$idx]+="UKN"
[[ ${#driveinv[idx]} -eq $cnt ]] && driveinv[$idx]+="UNK"
driveinv[$idx]+=" "
# serial number
cnt=${#driveinv[$idx]}
driveinv[$idx]+="$($SMARTCTL -i ${d[0]} | grep -i "Serial Number:" | awk '{print $3}')"
[[ ${#driveinv[idx]} -eq $cnt ]] && driveinv[$idx]+="UKN"
[[ ${#driveinv[idx]} -eq $cnt ]] && driveinv[$idx]+="UNK"
driveinv[$idx]+=" "
done
......@@ -211,6 +157,7 @@ done
} > ${tmplog} 2>&1
cat ${tmplog} >> ${logfile}
driveinfo=""
# echo name,size and serial to stdout, addr serialnumber
......
#! /bin/bash
#!/bin/bash
echo -n '. . . Starting diskspeedcheck'
# find the read and write speed of the disks on the system
# error out if referencing unset variable, better safe then sorry
set -u
# stop if any error
#set -e
# GLOBAL DEFINEDs
# startdir
declare startdir=$(pwd)
# need this much space free
declare os host failed
declare logfile tmplog tmplog2
# max time the dd will run
declare -r maxddtime=4
# need this much space free, how many K's can be written in maxddtime assuming 600Mb/sec
declare -r needsize=$((600 * 1024 * $maxddtime))
# directory were speed test file will be written
declare -r tempwkdir="/var/tmp"
# results
declare wkps rkps
#helper functions
source getfromtb.sh
source checkutils.sh
source hbis.sh
os=`uname`
host=`hostname`
failed=""
if [ -e "/var/emulab/boot/realname" ]; then
host=`cat /var/emulab/boot/realname`
fi
# setup logging
if [ $1 ] ; then
logfile=$1
else
logfile="/tmp/nodecheck.log"
fi
tmplog=/tmp/.$$.log
cat /dev/null > ${tmplog}
set +x
#exit on unbound var
set -u
FUNCDEBUG=n
main() {
funcdebug $FUNCNAME:$LINENO enter: $@
echo -n ' Starting diskspeedcheck.. '
initalize "$@"
doit
checkwithdb
finished
}
# args: if of max_time
ddspeed() {
funcdebug $FUNCNAME:$LINENO enter: $@
local if of time res
ifile=$1
ofile=$2
time=$3
res=/tmp/.$$ddresult
$(timesys $time $res dd if=$ifile of=$ofile bs=4k)
declare -a ary=($(grep bytes $res))
numelm=${#ary[*]}
[[ ${numelm} -ne 8 ]] && printf "PROGRAMMING ERROR $FUNCNAME $LINENO \n" && exit 1
numelm=$(($numelm - 2))
#debug
#numelm=6
s=${ary[$numelm]}
s=${s#(}
speed=$(hbis $s)
rm -f $res
echo $speed
return 0
}
initalize() {
funcdebug $FUNCNAME:$LINENO enter: $@
startdir=$(pwd)
os=`uname`
host=`hostname`
failed=""
if [ -e "/var/emulab/boot/realname" ]; then
host=`cat /var/emulab/boot/realname`
fi
# setup logging
[[ $# -gt 0 ]] && logfile=$1 || logfile="/tmp/nodecheck.log"
tmplog=/tmp/.$$.log
tmplog2=/tmp/.2tmp
cat /dev/null > ${tmplog}
touch $logfile
}
finished() {
funcdebug $FUNCNAME:$LINENO enter: $@
echo "diskspeedcheck `date`" >> ${logfile}
cat ${tmplog} >> ${logfile}
if [ -r ${tmplog2} ] ; then
# cat ${tmplog2}
cat ${tmplog2} >> ${logfile}
rm -f ${tmplog2}
fi
[[ -z ${failed} ]] && exit 1 || exit 0
}
doit() {
funcdebug $FUNCNAME:$LINENO enter: $@
local err=0
# 4 seconds at 200MB/s == 800MB
# make sure we have at least 1G avail, 1024000 k blocks
cd $tempwkdir
# hardcoded name to copies don't stack up
tempfile=${tempwkdir}/dskspdchckwrt
declare -a df=($(df -k . | grep / | tail -1 ))
havesize=${df[3]}
if [[ $havesize -gt $needsize ]] ; then
# tempfile to hold writes
$(rm -f $tempfile) ; $(sync ; sync)
# write speed time limited
wkps=$(ddspeed "/dev/zero" "$tempfile" $maxddtime)
# read speed
rkps=$(ddspeed "$tempfile" "/dev/null" $maxddtime)
$(rm $tempfile)
else
echo "not enough space"
failed="not enough space"
err=1
fi
cd ${startdir}
return $err
}
checkwithdb() {
funcdebug $FUNCNAME:$LINENO enter: $@
local testsays="Write_Speed ${wkps}/sec Read_Speed ${rkps}/sec"
local tbreturn
local err=''
echo -n ${testsays}
echo ${testsays} >> $tmplog
tbreturn=$(getfromtb diskspeedinfo $host)
if [ -z "$tbreturn" ] ; then
failed="TBmiss no info"
echo " $failed FAILED"
$(echo "TBmiss empty info returned." >> ${tmplog2})
return 1
elif [ "${tbreturn}" != "${tbreturn/unknown_node/}" ] ; then
failed=$tbreturn
echo " $failed FAILED"
$(echo "$failed" >> ${tmplog2})
return 1
fi
#lowercase
tbreturn=${tbreturn,,}
#turn space seperated string into array
unset -v tbinfo; declare -a tbinfo=(${tbreturn// / })
dskstring="$wkps $rkps"
dskstring=${dskstring,,}
unset -v dskspdinfo; declare -a dskspdinfo=(${dskstring// / })
# strip letters
x=${tbinfo[0]} ; x=${x%%[a-z]*} ; tbinfo[0]=$x
x=${tbinfo[1]} ; x=${x%%[a-z]*} ; tbinfo[1]=$x
x=${dskspdinfo[0]} ; x=${x%%[a-z]*} ; dskspdinfo[0]=$x
x=${dskspdinfo[1]} ; x=${x%%[a-z]*} ; dskspdinfo[1]=$x
logfile=$1
halfwritespeed=$((${tbinfo[0]} / 2))
halfreadspeed=$((${tbinfo[1]} / 2))
doublewritespeed=$((${tbinfo[0]} * 2))
doublereadspeed=$((${tbinfo[1]} * 2))
{
echo ""
} >> ${tmplog} 2>&1
if (( ${dskspdinfo[0]} < $halfwritespeed )) ; then
$(echo "write speed slow" >> ${tmplog2})
err="WriteSlow"
fi
if (( ${dskspdinfo[1]} < $halfreadspeed )) ; then
$(echo "read speed slow" >> ${tmplog2})
err="$err ReadSlow"
fi
if (( ${dskspdinfo[0]} > $doublewritespeed )) ; then
$(echo "write speed fast" >> ${tmplog2})
err="$err WriteFast"
fi
if (( ${dskspdinfo[1]} > $doublereadspeed )) ; then
$(echo "read speed fast" >> ${tmplog2})
err="$err ReadFast"
fi
[[ $err ]] && echo " $err FAILED" || echo " OK"
echo "diskspeedcheck `date`" >> ${logfile}
cat ${tmplog} >> ${logfile}
}
failed=FAIL
[[ -z ${failed} ]] && echo ". . . OK" || echo ". . . FAILED"
main "$@"
exit 0
......
......@@ -23,6 +23,12 @@ getfromtb() {
* ) echo "tb ${d[1]} unknown_node" ;;
esac
;;
diskspeedinfo )
case ${d[1]} in
boss.emulab.net) echo "100mib 400mib";;
* ) echo "tb ${d[1]} unknown_node" ;;
esac
;;
cpuinfo )
# echo "asked for cpuinfo node:${d[0]}:"
#Architecture Sockets Cores_socket Threads_core MHz {HT}{x64}{VIRT}
......@@ -44,6 +50,7 @@ getfromtb() {
diskinfo )
# echo "asked for diskinfo node:${d[0]}:"
case ${d[1]} in
pc4 | pc133 ) echo "UNK" ;;
pc7 ) echo "JHYJHT7R523" ;;
pc137 ) echo "SX0SXM24424" ;;
pc207 ) echo "3KS0XJW1 3KS0XJK4";;
......
#! /bin/sh
#!/bin/bash
echo -n ' Starting niccheck.. '
......
......@@ -17,13 +17,13 @@ bsd=""
#echo "linux||$linux||"
utils="diskcheck diskspeedcheck memcheck cpucheck getfromtb.sh hbis.sh timecheck niccheck"
utils="diskcheck diskspeedcheck memcheck cpucheck checkutils.sh getfromtb.sh hbis.sh timecheck niccheck"
arg=${arg=""} # use var if set else use ""
case $arg in
# don't need OS if not
disk | mem | cpu | diskspeed | time | nic | Ngetlogs | clearlogs | help | -help | -h | ? ) machines=$list ;;
drive | disk | mem | cpu | diskspeed | time | nic | Ngetlogs | clearlogs | help | -help | -h | ? ) machines=$list ;;
* )
for i in $list
do
......@@ -40,7 +40,8 @@ case $arg in
esac
case $arg in
disk | mem | cpu | diskspeed | time | nic)
drive | disk | mem | cpu | diskspeed | time | nic)
[[ "$arg" == "drive" ]] && arg=disk
for i in $machines ; do