#!/bin/csh

### parses "-serial", "-bythree", and a few other args
### locally... otherwise passes them all off to the diskscrub
### subprocess

set part      = "s1e"
set extraargs = "-t `hostname` -X"
set log       = "./log_twe/`hostname`"
set passcnt   = 2
set slammer   = 0
set delay     = 0
set bays      = `isi_drivenum -Mb`
set parallel  = $bays
set pid       = "$$_`date`"
set skipcheck = 0
set check     = "/tmp/ds_bad_procs_check"
set pubtype   = ''
set forcepub  = 0
set pub       = 0
set scrubtype = "ds|bf|3d|sp"
set allowedprocs = "(grep|drive_scrub|isi_i2c|isi_sel_kthread)"
set plotspdthresh = 0 

### figure out what dir this program was found/run in (but if there
### was no path mentioned, don't just assume "./")
if ( "X$0" !~ */* ) then
    set rundir = "";
else
    set rundir = "`dirname $0`/"
endif

while ($#)
    set linearg = $1;
    shift;

    switch ($linearg)
    case "-help":
    case "-h":
	echo "usage: $0 [-serial|-bythree|-parallel] [-part s1X] [-delay mins]"
        echo "         [-log dir] [-onepass|-twopass] [-slam|-slamcol|-noslam]"
        echo "         [-pubtype [$scrubtype] [-forcepub]] [-plotspdthresh]"
        echo "         [-forcestart] ..."
	echo "  any unrecognized args are passed to diskscrub"
	echo "  default: -parallel -twopass -noslam -part $part -log $log -delay $delay"
	exit;
	breaksw;
    case "-serial":
	set parallel = 1;
	breaksw;
    case "-bythree":
	set parallel = 3;
	breaksw;
    case "-parallel":
	set parallel = $bays;
	breaksw;
    case "-part":
	set part = $1;
	shift;
	breaksw;
    case "-log":
	set log = $1;
	shift;
	breaksw;
    case "-onepass":
	set passcnt = 1;
	breaksw;
    case "-twopass":
	set passcnt = 2;
	breaksw;
    case "-slam":
    case "-slammer":
	set slammer = 1;
	breaksw;
    case "-slamcol":
    case "-slamcolumn":
	set slammer = 2;
	breaksw;
    case "-noslam":
    case "-noslammer":
	set slammer = 0;
	breaksw;
    case "-delay":
	set delay = $1;
	shift;
	breaksw;
    case "-forcestart":
    	set skipcheck = 1;
	breaksw;
    case "-forcepub":
    	set forcepub = 1;
	set pub = 1;
	breaksw;
    case "-pubtype":
    	set pubtype = $1;
	set pub = 1;
	shift;
	breaksw;
    case "-plotspdthresh":
	set plotspdthresh = 1;
	breaksw;
    default:
	set extraargs = "$extraargs $linearg"
	breaksw;
    endsw
end

if ( $skipcheck == 0 ) then
    ### check that programs that can interfere with diskscrub aren't running
    ps axwwo pid,command | grep -E "(cron|smbd|ntpd)" | grep -v grep > $check
    ps axwwo pid,command | grep isi_ | grep -vE "$allowedprocs" >> $check
    mount | grep " /ifs" | grep -v grep >> $check

    if ( -s $check ) then
	echo ""
	echo "  ##### Refusing to start diskscrub #####"
	echo ""
	echo "Current settings will mess up testing.  Please kill offending processes and "
	echo "unmount /ifs.  Cut-n-paste of the following should do it:"
	echo "   ps auxw | grep -E '(cron|smbd|ntpd|isi_)' | awk '"'{print $2}'"'| xargs kill"
	echo "   umount /ifs"
	echo "[if you _truly_ want to run with these processes, use the -forcestart flag]"
	echo
	echo "The following processes were still running (pid and command shown):"
	echo " "
	cat $check
	rm -f $check
	exit(0)
    endif
    rm -f $check
endif

logger diskscrub start_${pid}

### back up the last run for safety
test ! -e ${log} || test ! -e ${log}~ || rm -rf ${log}~
test ! -e ${log} || mv ${log} ${log}~
### and prep for a new run
mkdir -p ${log}/pass1
if ($passcnt >= 2) then
    mkdir -p ${log}/pass2
endif
chmod -R go+w ${log}

## protect against driver interference... we handle all this ourselves.
sysctl hw.twe0.try_twereset=0
sysctl hw.twe0.try_ecc_recover=0
sysctl hw.twe0.bio_permafail=0
sysctl hw.twe0.pthru_permafail=0

echo "starting diskscrub with extra args $extraargs"

# make a date file for the staring time of the test
date > ${log}/date

echo "getting pre diskscrub isi_radish dump of all available info"
/usr/bin/isi_radish -a > ${log}/radish_all


set noslamlist = ""

## if we don't want slammers, make sure there are none running now
if ($slammer == 0) then
  ${rundir}drive_slam #none slamming
endif

@ BAY = 1
while ( $BAY <= $bays )
  set DEV = "`isi_drivenum -t ${BAY} | sed -e 's~/dev/~~'`"
  set dowait = 0
  if ( ($BAY == $bays) || ($parallel == 0) || \
	 ( ($BAY % $parallel) == 0 )  ) then
    set dowait = 1
  endif
  if ( -e /dev/${DEV}${part} ) then
    set nowcmd = "${rundir}diskscrub -s ${log}/pass1/log_${DEV}"
    if ($passcnt >= 2) then
	set nowcmd = "${nowcmd} -s ${log}/pass2/log_${DEV}"
    endif
    if ($plotspdthresh == 1) then 
	set nowcmd = "${nowcmd} -D ${log}/pass1/log_${DEV}thresh"
    	set plotspdthresh = 0;
    endif
    isi_radish -q $BAY > ${log}/diskreport_${BAY}
    set nowcmd = "${nowcmd} ${extraargs} /dev/${DEV}${part}"
    set nowcmd = "${nowcmd} >> ${log}/diskreport_${BAY} &"
    eval $nowcmd

    set noslamlist = "$noslamlist -x $BAY"

    if ($slammer != 0) then
      ## start slammer if appropriate

      ## we must make sure these slammers don't count as our
      ## children for the "wait".  Fortunately that seems to work
      ## just fine as is.
      if ($slammer == 1) then
	  set yesslamlist = "-a"  #slam all drives
      else
	  set yesslamlist = "-c $BAY"  #slam all drives in same column as bay
      endif
      ${rundir}drive_slam $yesslamlist $noslamlist
      set noslamlist = ""
    endif

    ## do per-drive delay, if appropriate.  This lets us start up our
    ## drives staggered, if we want.
    if ($delay != 0) then
      @ delaymins = ( $delay * 60 );
      sleep $delaymins
    endif
  endif

  if ($dowait == 1) then
    ## wait for all to finish.  This serializes our tests as desired
    echo "started $parallel diskscrubs -- waiting for completion"
    wait
  endif

  @ BAY = ($BAY + 1)
end

## concatenate from smallest to largest bay number
ls ${log}/diskreport_* | sort -t_ +1 -n | xargs cat > ${log}/diskreport

## if we were running slammers, turn them all off now
if ($slammer != 0) then
  ${rundir}drive_slam #none slamming
endif

## save /var/log/messages and filter for messages logged during the diskscrub
logger diskscrub stop_${pid}
cp /var/log/messages ${log}/messages.orig
sed -n "/start_$pid/,/stop_$pid/p" /var/log/messages > ${log}/messages

## publish the nodeburn results 
##   - enforce a naming convention
##	scrubtype-nodename
##	ie: ds-hbox100
##     unless these args are received: -forcepub or -type testdevel
##   - output any publish errors, messages, etc to stdout
if ($pub == 1) then
    # invalidname and nottestdevel are each false if have zero length string
    set invalidname 	= `echo $log | grep -vE "($scrubtype)-"`
    set nottestdevel	= `echo $pubtype | grep -viE "testdevel"`
    set pubcmd    	= "/usr/bin/isi_hwtools/isi_burnin"

    if ($forcepub == 1 || $nottestdevel == "" || $invalidname == "") then
	if ($pubtype != '') then
  		set pubcmd = "$pubcmd -type $pubtype"	
	endif
	set pubcmd = "$pubcmd -np $log"
	eval $pubcmd;
    else
	echo "Log dir name does not follow convention of "
	echo
	echo "  <$scrubtype>-<hostname>"
	echo
	echo -n "To ignore convention and publish, include "
	echo    "-forcepub or use publish type testdevel"
    endif
endif

echo "finished.  you may want to reset your twe sysctls"
