#!/bin/bash
# This script installs writeback and runs the regression tests

P=writeback-bench
VERSION=0.1
MEMTOTAL_BYTES=`free -b | grep Mem: | awk '{print $2}'`
NUMCPUS=`grep processor /proc/cpuinfo | wc -l`
CPU_FACTOR=1
MAX_CPU_FACTOR=64
BS=1048576
ITERATIONS=1
CONV=
FILESIZE=$((MEMTOTAL_BYTES*4))

# Basic args parser
while [ "$1" != "" ]; do
	case "$1" in
		-v)
			VERSION=$2
			shift 2;;
		--filesize)
			FILESIZE=$2
			shift 2;;
		--min-cpu-factor)
			CPU_FACTOR=$2
			shift 2;;
		--max-cpu-factor)
			MAX_CPU_FACTOR=$2
			shift 2;;
		--diskdir)
			TESTDISK_DIR=$2
			shift 2;;
		--bs)
			BS=$2
			shift 2;;
		--conv)
			CONV="conv=$SIMPLE_WRITEBACK_CONV"
			shift 2;;
		--iterations)
			ITERATIONS=$2
			shift 2;;
		--install-only)
			INSTALL_ONLY=yes; shift;;
		*)	echo Unrecognised option: $1; shift
	esac
done

. $SHELLPACK_INCLUDE/include-monitor.sh

FILESYSTEM=`stat -f $TESTDISK_DIR | grep Namelen | awk '{print $NF}' | sed -e 's/\//_/'`
while [ $CPU_FACTOR -le $MAX_CPU_FACTOR ]; do
	if [ $CPU_FACTOR -eq 0 ]; then
		NR_JOBS=1
	else
		NR_JOBS=$((NUMCPUS*CPU_FACTOR))
	fi
	FILESIZE_JOB=$((FILESIZE/NR_JOBS))
	FILESIZE_JOB_CHUNKS=$((FILESIZE/NR_JOBS/$BS))
	PRINT_NR_JOBS=`printf "%05d" $NR_JOBS`

	echo
	echo Test Parameters
	echo "o CPU Factor        $CPU_FACTOR / $MAX_CPU_FACTOR"
	echo "o Number jobs:      $NR_JOBS"
	echo "o Physical memory:  $MEMTOTAL_BYTES"
	echo "o Filesize per job: $FILESIZE_JOB"
	echo "o Total filesize:   $FILESIZE"
	echo "o Filesystem:       $FILESYSTEM"

	echo
	echo Launching vmstat
	vmstat -n 1 > $LOGDIR_RESULTS/vmstat-$PRINT_NR_JOBS.log &
	PIDVMSTAT=$!

	echo Reading /proc/vmstat
	NR_WRITEBACK_START=`grep nr_vmscan_write /proc/vmstat | awk '{print $2}'`
	NR_SCAN_DIRECT_START=0
	NR_SCAN_KSWAPD_START=0
	NR_SCAN_DIRECT_END=0
	NR_SCAN_KSWAPD_END=0
	for ENTRY in `grep pgscan_direct_ /proc/vmstat | awk '{print $2}'`; do
		NR_SCAN_DIRECT_START=$((NR_SCAN_DIRECT_START+$ENTRY))
	done
	for ENTRY in `grep pgscan_kswapd_ /proc/vmstat | awk '{print $2}'`; do
		NR_SCAN_KSWAPD_START=$((NR_SCAN_KSWAPD_START+$ENTRY))
	done

	for JOB in `seq 1 $NR_JOBS`; do
		echo -n > $LOGDIR_RESULTS/job-$JOB-of-$NR_JOBS.log
	done
	for ITER in `seq 1 $ITERATIONS`; do
		echo Launching dd instance iteration $ITER
		mkdir -p $LOGDIR_RESULTS
		monitor_pre_hook $LOGDIR_RESULTS $SIZE
		for JOB in `seq 1 $NR_JOBS`; do
			/usr/bin/time -f "iteration $ITER : %U user %S system %e elapsed" \
				dd if=/dev/zero of=$TESTDISK_DIR/file-$JOB ibs=$BS obs=$BS count=$FILESIZE_JOB_CHUNKS $CONV >> $LOGDIR_RESULTS/job-$JOB-of-$NR_JOBS.log 2>&1 &
				echo $! > $LOGDIR_RESULTS/job-$JOB.pid
		done

		echo Waiting on jobs to finish
		for JOB in `seq 1 $NR_JOBS`; do
			JOBPID=`cat $LOGDIR_RESULTS/job-$JOB.pid`
			echo Job $JOBPID
			wait $JOBPID
			rm $LOGDIR_RESULTS/job-$JOB.pid
			rm $TESTDISK_DIR/file-$JOB
		done
	done
	echo Re-reading vmstat
	NR_WRITEBACK_END=`grep nr_vmscan_write /proc/vmstat | awk '{print $2}'`
	for ENTRY in `grep pgscan_direct_ /proc/vmstat | awk '{print $2}'`; do
		NR_SCAN_DIRECT_END=$((NR_SCAN_DIRECT_END+$ENTRY))
	done
	for ENTRY in `grep pgscan_kswapd_ /proc/vmstat | awk '{print $2}'`; do
		NR_SCAN_KSWAPD_END=$((NR_SCAN_KSWAPD_END+$ENTRY))
	done
	monitor_post_hook $LOGDIR_RESULTS $RECORD_LEN

	kill $PIDVMSTAT
	echo
	sleep 1
	echo Job times and IO Rates
	echo -n > $LOGDIR_RESULTS/result-$PRINT_NR_JOBS.txt
	for JOB in `seq 1 $NR_JOBS`; do
		for ITER in `seq 1 $ITERATIONS`; do
			JOB_TIME=`grep elapsed $LOGDIR_RESULTS/job-$JOB-of-$NR_JOBS.log | head -$ITER | tail -1`
			RATE=`grep copied, $LOGDIR_RESULTS/job-$JOB-of-$NR_JOBS.log | awk '{print $9}' | head -$ITER | tail -1`
			IO_RATE=`grep copied, $LOGDIR_RESULTS/job-$JOB-of-$NR_JOBS.log | awk '{print $8}' | head -$ITER | tail -1`
			case $RATE in
			GB/s)
				IO_RATE=`perl -e "print ($IO_RATE*1024*1048576)"`
				;;
			MB/s)
				IO_RATE=`perl -e "print ($IO_RATE*1048576)"`
				;;
			kB/s)
				IO_RATE=`perl -e "print ($IO_RATE*1024)"`
				;;
			esac
			echo job $JOB $JOB_TIME $IO_RATE bytes/sec >> $LOGDIR_RESULTS/result-$PRINT_NR_JOBS.txt
		done
	done
	echo "nr_vmscan_write $((NR_WRITEBACK_END-NR_WRITEBACK_START))" >> $LOGDIR_RESULTS/result-$PRINT_NR_JOBS.txt
	echo "nr_scan_direct  $((NR_SCAN_DIRECT_END-NR_SCAN_DIRECT_START))" >> $LOGDIR_RESULTS/result-$PRINT_NR_JOBS.txt
	echo "nr_scan_kswapd  $((NR_SCAN_KSWAPD_END-NR_SCAN_KSWAPD_START))" >> $LOGDIR_RESULTS/result-$PRINT_NR_JOBS.txt

	if [ $CPU_FACTOR -eq 0 ]; then
		CPU_FACTOR=1
	else
		CPU_FACTOR=$((CPU_FACTOR*2))
	fi
done

echo
echo simple-writeback completed successfully
exit $SHELLPACK_TEST
#### Description Basic test for page writeback
#### Details simple-writeback-bench 4
