Skip to main content

iotest script

# print usage
usage ()
{
        echo ""
        echo "<<USAGE>>  ${PROG} -i <iterations> -t <target filesystem> -b <block count> -s <block size>"
        echo ""
        echo "  function run current dd write and read tests to a SAS filesystem to test thruput"
        echo "           where results will be stored in ${PROG}.results.<iterations>"
        echo ""
        echo "  where    iterations are the number of concurrent tests to run"
        echo "           target filesystem is the SAS read/write filesystem to test"
        echo "           block count is the number of block you want dd to process (eg: 20000)"
        echo "           block size is the size of the blocks you want dd to process in K (eg: 64)"
}
# validate input parameters for iterations and writeable target directory
validateinput ()
{
        UNAME=`uname`
        TMPNAME=tmpfile.$$
        TMPFILE=${TARGETDIR}/${TMPNAME}
        rm -f ${PROG}-readtest.out.* ${PROG}-writetest.out.* >/dev/null 2>&1
        if [ -z "${ITERATIONS}" ]
          then  echo "<<ERROR>>  iteration count not provided"
                RC=1
        fi
        if [  ! -d  "${TARGETDIR}" ]
          then  echo "<<ERROR>>  target directory not provided or does not exist"
                RC=1
          else  touch ${TMPFILE} >/dev/null 2>&1
                if [ $? -ne 0 ]
                  then  echo "<<ERROR>>  target directory not writeable"
                        RC=1
                  else  dd if=/dev/zero of=/dev/null bs=1k count=1 2>${TMPFILE}
                        if [ $? -ne 0 ]
                          then  echo "<<ERROR>> cannot execute dd command"
                                cat ${TMPFILE}
                                rm -f ${TMPFILE} >/dev/null 2>&1
                                RC=1
                        fi
                fi
                rm -f ${TMPFILE} >/dev/null 2>&1
        fi
        if [ -z "${BLOCKS}" ]
          then  echo "<<ERROR>>  block count not provided"
                RC=1
        fi
        if [ -z "${BLOCKSIZE}" ]
          then  echo "<<ERROR>>  block size not provided"
                RC=1
        fi
}
# process dd based writes and reads
processwriteread ()
{
        echo "<<STATUS>> executing write testing"
        sync
        ((COUNT=0))
        while [ ${COUNT} -lt ${ITERATIONS} ]
          do
                ((COUNT=COUNT+1))
                echo "           launching iteration: ${COUNT}"
                (/usr/bin/time -p dd if=/dev/zero of=${TARGETDIR}/${PROG}-dd-write.${COUNT} bs=${BLOCKSIZE}k count=${BLOCKS}) > ${PROG}-writetest.out.${COUNT} 2>&1 &
          done
        echo "           waiting for all write tests to complete"
        wait
        ((COUNT=1))
        while [ ${COUNT} -lt ${ITERATIONS} ]
          do
                SIZE1=`ls -lt ${TARGETDIR}/${PROG}-dd-write.${COUNT} | awk '{ print $5 }'`
                ((COUNT=COUNT+1))
                SIZE2=`ls -lt ${TARGETDIR}/${PROG}-dd-write.${COUNT} | awk '{ print $5 }'`
                if [ ${SIZE1} -ne ${SIZE2} ]
                  then  echo ""
                        echo "<<STATUS>> target filesystem [${TARGETDIR}] does not have an adequate amount of free disk space to complete the test"
                        echo ""
                        echo "<<STATUS>> results of df on target filesystem [${TARGETDIR}]"
                        echo ""
                        df ${TARGETDIR}
                        echo ""
                        echo ""
                        echo "<<STATUS>> file size of write attempts"
                        echo ""
                        ls -lt ${TARGETDIR}/${PROG}-dd-write.*
                        echo ""
                        echo ""
                        echo "<<STATUS>> cleaning up filesystem [${TARGETDIR}]"
                        echo ""
                        echo "<<ERROR>> ${PROG}: failed to execute write test successfully"
                        rm -f ${TARGETDIR}/${PROG}-dd-* >/dev/null 2>&1
                        RC=1
                        break
                fi
          done
        if [ ${RC} -eq 0 ]
          then  echo "           write test complete"
                echo "<<STATUS>> executing read testing"
                sync
                ((COUNT=0))
                while [ ${COUNT} -lt ${ITERATIONS} ]
                  do
                        ((COUNT=COUNT+1))
                        echo "           launching iteration: ${COUNT}"
                        (/usr/bin/time -p dd if=${TARGETDIR}/${PROG}-dd-write.${COUNT} of=/dev/null bs=${BLOCKSIZE}k count=${BLOCKS}) \
                         > ${PROG}-readtest.out.${COUNT} 2>&1 &
                  done
                echo "           waiting for all read tests to complete"
                wait
                echo "           read test complete"
        fi
}
# create output file and cleanup
cleanup ()
{
        echo "<<STATUS>> creating file: ${PROG}.results.${ITERATIONS} with results"
        #egrep -i "real" ${PROG}-*out* > ${PROG}.results.${ITERATIONS}
        grep -i "real" ${PROG}-*out* > ${PROG}.results.${ITERATIONS}
        rm -f ${TARGETDIR}/${PROG}-dd-* >/dev/null 2>&1
        TRR=0
        TWR=0
        while read RECORD
          do
                TYPE=`echo ${RECORD} | awk -F\: '{ print $1 }'`
                case "${UNAME}" in
                 HP-UX) TIME=`echo ${RECORD} | awk '{ print $NF }'`
                        COUNT=`echo ${TIME} | awk -F\: '{ print NF }'`
                        if [ ${COUNT} -eq 3 ]
                          then  H=`echo ${TIME} | awk -F\: '{ print $1*60*60 }'`
                                M=`echo ${TIME} | awk -F\: '{ print $2*60 }'`
                                S=`echo ${TIME} | awk -F\: '{ print $3 }'`
                          else  H=0
                                if [ ${COUNT} -eq 2 ]
                                  then  M=`echo ${TIME} | awk -F\: '{ print $1*60 }'`
                                        S=`echo ${TIME} | awk -F\: '{ print $2 }'`
                                  else  M=0
                                        S=`echo ${TIME} | awk '{ print $1 }'`
                                fi
                        fi
                        S=`echo "scale=2;${S} + ${M} + ${H}" | bc -l`
                        ;;
                 *)     S=`echo ${RECORD} | awk '{ print $NF }'`
                        ;;
                esac
                case ${TYPE} in
                  ${PROG}-read*)        TRR=`echo "scale=2;${TRR} + ${S}" | bc -l`
                                        ;;
                  ${PROG}-write*)       TWR=`echo "scale=2;${TWR} + ${S}" | bc -l`
                                        ;;
                esac
          done < ${PROG}.results.${ITERATIONS}
        #((FS=BLOCKS*BLOCKSIZE*1024))
        FS=`echo "${BLOCKS}*${BLOCKSIZE}*1024" | bc -l`
        MB=`echo "scale=2;${FS} / 1024 / 1024" | bc -l`
        ARR=`echo "scale=2;${TRR} / ${ITERATIONS}" | bc -l`
        AWR=`echo "scale=2;${TWR} / ${ITERATIONS}" | bc -l`
        ART=`echo "scale=2;${MB} / ${ARR}" | bc -l`
        AGR=`echo "scale=2;${ART} * ${ITERATIONS}" | bc -l`
        AWT=`echo "scale=2;${MB} / ${AWR}" | bc -l`
        AGW=`echo "scale=2;${AWT} * ${ITERATIONS}" | bc -l`
        echo ""  | tee -a ${PROG}.results.${ITERATIONS}
        echo ""  | tee -a ${PROG}.results.${ITERATIONS}
        echo ""  | tee -a ${PROG}.results.${ITERATIONS}
        #echo "RESULTS"  | tee -a ${PROG}.results.${ITERATIONS}
        echo "RESULTS"  | tee ${PROG}.results.${ITERATIONS}
        echo "-------"  | tee -a ${PROG}.results.${ITERATIONS}
        echo ""  | tee -a ${PROG}.results.${ITERATIONS}
        echo "INVOCATION            : ${PROG} ${OPTIONS}" | tee -a ${PROG}.results.${ITERATIONS}
        echo ""  | tee -a ${PROG}.results.${ITERATIONS}
        echo ""  | tee -a ${PROG}.results.${ITERATIONS}
        echo "TARGET DETAILS" | tee -a ${PROG}.results.${ITERATIONS}
        echo "  directory           : ${TARGETDIR}" | tee -a ${PROG}.results.${ITERATIONS}
        case "${UNAME}" in
           AIX)         echo "  df                  : `df -P ${TARGETDIR} 2>/dev/null | tail -1`" | tee -a ${PROG}.results.${ITERATIONS}
                        MP=`df -P ${TARGETDIR} 2>/dev/null | tail -1 | awk '{ print $NF }'`
                        echo "  mount point         :" `/usr/sbin/mount 2>/dev/null | grep ${MP} 2>/dev/null | tail -1 | sed "s;        ;;g"` | tee -a ${PROG}.results.${ITERATIONS}
                        ;;
          HP-UX)        MP=`df -P ${TARGETDIR} 2>/dev/null | awk '{ print $NF }' | tail -1`
                        echo "  mount point         : `/sbin/mount 2>/dev/null | grep ${MP} 2>/dev/null | tail -1`" | tee -a ${PROG}.results.${ITERATIONS}
                        ;;
          SunOS)        echo "  df                  : `df ${TARGETDIR} 2>/dev/null | tail -1`" | tee -a ${PROG}.results.${ITERATIONS}
                        MP=`df ${TARGETDIR} 2>/dev/null | tail -1 | awk '{ print $NF }'`
                        echo "  mount point         : `/usr/sbin/mount 2>/dev/null | grep ${MP} 2>/dev/null | tail -1`" | tee -a ${PROG}.results.${ITERATIONS}
                        ;;
          Linux)        echo "  df                  : `df  -P ${TARGETDIR} 2>/dev/null | tail -1`" | tee -a ${PROG}.results.${ITERATIONS}
                        MP=`df -P ${TARGETDIR} 2>/dev/null | tail -1 | awk '{ print $NF }'`
                        echo "  mount point         : `/bin/mount 2>/dev/null | grep ${MP} 2>/dev/null | tail -1`" | tee -a ${PROG}.results.${ITERATIONS}
                        ;;
        esac
        echo "  filesize            : ${FS} bytes or ${MB} megabytes" | tee -a ${PROG}.results.${ITERATIONS}
        echo ""  | tee -a ${PROG}.results.${ITERATIONS}
        echo ""  | tee -a ${PROG}.results.${ITERATIONS}
        echo "STATISTICS"  | tee -a ${PROG}.results.${ITERATIONS}
        printf '%36s %8s %20s\n' "  average read time in seconds     :" "${ARR}" "                    " | tee -a ${PROG}.results.${ITERATIONS}
        printf '%36s %8s %20s\n' "  average read throughput rate     :" "${ART}" "megabytes per second" | tee -a ${PROG}.results.${ITERATIONS}
        #printf '%36s %8s %20s\n' "  aggregate read throughput rate   :" "${AGR}" "megabytes per second" | tee -a ${PROG}.results.${ITERATIONS}
        printf '%36s %8s %20s\n' "  average write time in seconds    :" "${AWR}" "                    " | tee -a ${PROG}.results.${ITERATIONS}
        printf '%36s %8s %20s\n' "  average write throughput rate    :" "${AWT}" "megabytes per second" | tee -a ${PROG}.results.${ITERATIONS}
        #printf '%36s %8s %20s\n' "  aggregate write throughput rate  :" "${AGW}" "megabytes per second" | tee -a ${PROG}.results.${ITERATIONS}
        echo ""  | tee -a ${PROG}.results.${ITERATIONS}
        echo ""  | tee -a ${PROG}.results.${ITERATIONS}
        echo "<<STATUS>> processing complete"
}
# main
RC=0
PROG=${0##*/}
export LANG=en_US
OPTIONS=${*}
while getopts ":i:t:b:s:" opt
  do
        case $opt in
          i)    ITERATIONS=${OPTARG}
                ;;
          t)    TARGETDIR=${OPTARG}
                ;;
          b)    BLOCKS=${OPTARG}
                ;;
          s)    BLOCKSIZE=${OPTARG}
                ;;
          \?)   echo "<<ERROR>> Invalid option: -$OPTARG" >&2
                RC=1
                ;;
          :)    echo "<<ERROR>> Option -$OPTARG requires an argument." >&2
                RC=1
                ;;
        esac
  done
validateinput
if [ ${RC} -eq 0 ]
  then  processwriteread
        if [ ${RC} -eq 0 ]
          then  cleanup
        fi
  else  usage
fi
exit ${RC}



 ./iotest.sh -i 3 -t /test/saswork/ -b 2064834 -s 64

Comments

Post a Comment

Popular posts from this blog

Insufficient authorization to access PIPE error in SAS EG

Issue: When I tried to run SAS code in SAS Enterprise Guide it throws following errors: ERROR: Insufficient authorization to access PIPE. ERROR: Error in the FILENAME statement. Screenshot of error: Solution: This error occurs when you try to run OS commands in SAS code. To run the OS commands in SAS code you need to enable XCMD option. You check it in SAS Management Console by following below steps.   Open SMC -> Expand Servers -> Expand   In SASApp , expand Logical Workspace Server -> right click on Workspace Server. Click properties -> option tab -> advanced options -> launch properties. Check whether Allow XCMD is checked. The issue arises if the Allow XCMD is not checked. In above image, Allow XCMD option is not checked. It should be checked to run OS commands from SAS code. In Unix /Linux machines, this XCMD option can be enabled by using system option XCMD in sasv9 config file or workspaceserver.sh script f...

SAS - CLI error trying to establish connection

Issue: User asked me to make a database connectivity to SQL Server. They provided following details SQL server hostname and ip address Database/DSN name Username Password I made entry in ODBC.ini file. You know, SQL Server entries were made in ODBC.ini and Oracle entries were made in TNS.ora file. Everything went fine, took back up of odbc.ini, made entry and saved the file. So to test this connection I ran the libname statement in SAS Enterprise Guide 6.1. It throwed following error. Error Message: My DB team showed that they are able to login   14 GOPTIONS ACCESSIBLE; 15 LIBNAME test ODBC DATASRC=SGE_DS SCHEMA=VST USER=sales PASSWORD=XXXXXXXXX; ERROR: CLI error trying to establish connection: [SAS/ACCESS to SQL Server][ODBC SQL Server Legacy Driver][SQL Server]Login failed for user 'sales'. Solution: First I suspected that Login failed for user 'sales' meant the password provided by DB team was wrong. They responded that they were able to login wi...

Insufficient authorization to access prgramname.lst

Issue: I had an issue with batch server. The code runs fine in SAS EG and SAS DI Studio but fails when I run with batchserver. Error seems to be ERROR: Insufficient authorization to access /opt/sasinside/Lev1/SASApp/Sas_Program.lst. NOTE: The SAS System stopped processing this step because of errors. Solution: When you execute on batch mode sas tries to save the output file (Sas_Program.lst) under /opt/sasinside/Lev1/SASApp where is no permission to write. We should add two system options to sasv9_usermods.cfg file to redirect this outputs to another directory. The options are following: -altprint <directory>  -print <directory> Where directory is a directory where you have access to write. You must provide this directory. The directory can be some shared location like: /share/sas/lst. If you decide to add this options these are the steps to follow: 1. Create or choose a driectory where your userid have write access. The userid is the ...