Home | History | Annotate | Download | only in doio
      1 #!/bin/bash
      2 
      3 # Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
      4 #
      5 # This program is free software; you can redistribute it and/or modify it
      6 # under the terms of version 2 of the GNU General Public License as
      7 # published by the Free Software Foundation.
      8 #
      9 # This program is distributed in the hope that it would be useful, but
     10 # WITHOUT ANY WARRANTY; without even the implied warranty of
     11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     12 #
     13 # Further, this software is distributed without any warranty that it is
     14 # free of the rightful claim of any third person regarding infringement
     15 # or the like.  Any license provided herein, whether implied or
     16 # otherwise, applies only to this software file.  Patent licenses, if
     17 # any, provided herein do not apply to combinations of this program with
     18 # other software, or any other product whatsoever.
     19 #
     20 # You should have received a copy of the GNU General Public License along
     21 # with this program; if not, write the Free Software Foundation, Inc.,
     22 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     23 #
     24 # Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
     25 # Mountain View, CA  94043, or:
     26 #
     27 # http://www.sgi.com
     28 #
     29 # For further information regarding this notice, see:
     30 #
     31 # http://oss.sgi.com/projects/GenInfo/NoticeExplan/
     32 
     33 #
     34 # rwtest - a shell wrapper around iogen and doio
     35 #
     36 
     37 trap "exit 0" INT  # Until the smarter signal handler is engaged, below.
     38 
     39 Prog=${0##*/}
     40 
     41 iOpts=""
     42 dOpts=""
     43 LockRegion=""
     44 Nprocs=1
     45 Files=""
     46 Remove_Test_Files=""
     47 Files_To_Remove=""
     48 MPPrun=""
     49 export TCID="rwtest"
     50 export TST_TOTAL=1
     51 export TST_COUNT=1
     52 
     53 usage()
     54 {
     55 	echo "$Prog: [-chq] [-N name] [ iogen options ] [ doio options ] files" >&2
     56 }
     57 
     58 help()
     59 {
     60 	echo "\
     61     -c           Cleanup test files created by this invocation on exit.
     62                  Default is to leave them.
     63     -h           This help - ignore all other options/arguments
     64     -F		 Only process filenames - does not run iogen & doio.
     65     -P Places	 Not used
     66     -S Scenario  Execute an internal scenario.
     67     -N Name	 Pan-style name to be printed with error messages.
     68 
     69     Options passed through to iogen:
     70     -[afiLmOstT] arg
     71     -o
     72     -q		 Set rwtest to be quiet and pass the flag on to iogen.
     73 
     74     Options passed through to doio:
     75     -D[rmMVUC] arg
     76     -D[aekv]
     77     -n nprocs    # procs to do simultanious io to the test files.
     78                  Default is 1.  If -n is non-zero, doio's -k option (use
     79 		 file locking) is forced.
     80 
     81     files        Files to test on.  File names have the following format:
     82 		 [ size: ] path
     83 		 [ free% [ max size ] : ] path
     84 		 If no size is specified, the files must exist
     85                  and the contents will be overwritten if testing write or
     86                  writea system calls.  If a size is supplied, an attempt to
     87                  create/grow/shrink path to the desired size will be made.
     88                  size is an integer which defaults to bytes, but may be
     89                  suffixed by 'b', 'k', or 'm' for blocks (4096 byte units),
     90 	         kilobytes (1024 byte units), or megabytes (2^20 byte units).
     91 
     92 		 If the size is a percentage, df is used to find how much
     93 		 free space there is (in blocks), and uses that.  The maximum
     94 		 size is implied to be in blocks.
     95 " >&2
     96 }
     97 
     98 killkids()
     99 {
    100 	trap "killkids" INT
    101 	if [[ -z $didkids ]]
    102 	then
    103 		didkids=done
    104 		kill -INT -$$
    105 	fi
    106 }
    107 
    108 
    109 cleanup_and_exit()
    110 {
    111 	if [ -n "$Remove_Test_Files" ]
    112 	then
    113 		if [ -n "$Files_To_Remove" ]
    114 		then
    115 			rm -rf $Files_To_Remove
    116 		fi
    117 	fi
    118 
    119 	if [ $1 -ne 0 ]
    120 	then
    121 	    tst_resm TFAIL "Test failed"
    122 	    echo "Test failed"
    123 	else
    124 	    tst_resm TPASS "Test passed"
    125 	    echo "Test passed"
    126 	fi
    127 
    128 	exit $1
    129 }
    130 
    131 while (( $# > 0 ))
    132 do	case $1 in
    133 	-c)	Remove_Test_Files=yes
    134 		;;
    135 
    136 	-d)	debug=$2
    137 		shift
    138 		;;
    139 
    140 	-h)	help
    141 		exit 0
    142 		;;
    143 
    144 	-F)
    145 		opt_F="-F"	# only process filenames
    146 		;;
    147 
    148 	-P)
    149 		PLACES=$2
    150 		shift
    151 		;;
    152 
    153 	-S)	Scenario=$2
    154 		shift
    155 		opt_S="-S"
    156 		;;
    157 
    158 	-N)	Name="($2)"
    159 		TCID=$2
    160 		iOpts="$iOpts -N $2"
    161 		dOpts="$dOpts -N $2"
    162 		shift
    163 		;;
    164 
    165 	# iogen Options to pass thru ... options with an argument
    166 	-[afiLmOstT] )
    167 		iOpts="$iOpts $1 $2"
    168 		shift
    169 		;;
    170 
    171 	# iogen Options to pass thru ... just the option
    172 	-[o] )
    173 		iOpts="$iOpts $1"
    174 		;;
    175 
    176 	# iogen options to look at
    177 	-q)
    178 		iOpts="$iOpts $1"
    179 		Quiet=$1
    180 		;;
    181 
    182 	# doio Options to pass thru ... options with an argument
    183 	-D[rmMVUC] )
    184 		o=${1#-D}
    185 		dOpts="$dOpts -$o $2"
    186 		shift
    187 		;;
    188 
    189 	# doio options to pass thru ... just the options
    190 	-D[aekv] )
    191 		o=${1#-D}
    192 		dOpts="$dOpts -$o"
    193 		;;
    194 
    195 	# doio options to look at
    196 	-n | -Dn )
    197 		dOpts="$dOpts $1 $2"
    198 		# force file locking with > 1 process
    199 		if [[ $2 > 1 ]]
    200 		then
    201 			dOpts="$dOpts -k"
    202 		fi
    203 		opt_n="-n"
    204 		shift
    205 		;;
    206 
    207 	\? | -*)
    208 		echo "$Prog:  Illegal option $1" >&2
    209 		tst_resm TBROK "Illegal option $1"
    210 		exit 1
    211 		;;
    212 
    213 	*)
    214 		break
    215 		;;
    216 	esac
    217 	shift
    218 done
    219 
    220 #
    221 # Hard-Coded Scenario Specifications
    222 #
    223 # FSA		RAW I/O via FSA
    224 # MPPnnn	Run as a <nnn> sized MPP application
    225 # userstripe	create files using user striping
    226 #
    227 
    228 if [[ -n "$opt_S" ]]
    229 then
    230 	case $Scenario in
    231 
    232 	FSA )
    233 		# I/O via FSA
    234 		Flags="parallel"
    235 		Nprocs=1
    236 		LockRegion=""
    237 	;;
    238 
    239 	MPP* )
    240 		# use mpprun...  to cooperate with a batch system, this
    241 		# requires scanning mppview, etc.
    242 
    243 		NPE=${Scenario#MPP}
    244 		MPPrun=" mpprun -n $NPE "
    245 	;;
    246 	userstripe)
    247 		#create files using user striping
    248 		Oflags=O_PLACE,0xffffffffffffffff,1000
    249 	;;
    250 
    251 	places*)
    252 		FSIZE=${Scenario#places-}
    253 		oi="$IFS"
    254 		IFS=":"
    255 		set -- $PLACES
    256 		if [ $# -eq 0 ]
    257 		then
    258 			# "this isn't supposed to happen"
    259 			Files="25%:rwtest.$$"
    260 		else
    261 			IFS="$oi"
    262 			PL=${*}
    263 			for p in $PL
    264 			do
    265 				f="$f "${FSIZE}":"${p}"/rwtest$$"
    266 			done
    267 			set -- $f
    268 		fi
    269 	;;
    270 	esac
    271 fi
    272 
    273 #
    274 # If no files are specified ...
    275 #	check if PLACES is set; if so, put one file in each place
    276 #	otherwise generate one filename in the current directory.
    277 #
    278 
    279 if [ $# -eq 0 ]
    280 then
    281 	# put one file in each of $PLACES
    282 	Files="25%:rwtest.file"
    283 else
    284 	Files=$*
    285 fi
    286 
    287 #
    288 # use 'df -PB' to see how many blocks are available, apply a hard limit of
    289 # 1,000,000 blocks if no limit is specified
    290 #
    291 
    292 case "$(uname -s)" in
    293 	IRIX | IRIX64 )		dfOpts="-Pb"	;;
    294 	Linux)			dfOpts="-P"	;;
    295 	*)			dfOpts="-PB"	;;
    296 esac
    297 
    298 for f in $Files
    299 do
    300 	file=${f##*:}
    301 	if [ ! -f "$file" ]
    302 	then
    303 		Files_To_Remove="$Files_To_Remove $file"
    304 	fi
    305 
    306 	dir=$(dirname $file)
    307 	# create directory for file if non-existent
    308 	if [ ! -d "$dir" ]
    309 	then
    310 		mkdir -p $dir
    311 		Files_To_Remove="$Files_To_Remove $dir"
    312 	fi
    313 	size=${f%%:*}
    314 	if [[ $size = *%* ]]
    315 	then
    316 
    317 		typeset -i n=0
    318 		while (( n < ${#szcache[*]} ))
    319 		do
    320 			if [[ szcache[$n] = $dir ]]; then
    321 				break;
    322 			fi
    323 			n=n+1
    324 		done
    325 
    326 		if (( n < ${#szcache[*]} ))
    327 		then
    328 			blks=${szblks[$n]}
    329 		else
    330 			# If df is a symlink (to busybox) then do not pass the $dir and $dfOpts
    331 			# parameters because they don't work as expected
    332                         if test -h $(which df)
    333                            then
    334                                dir=""; dfOpts="";
    335                         fi
    336 
    337 			blks=$(df $dfOpts $dir |
    338 			(while read fs blks used avail cap mountpoint
    339 			 do
    340 				#echo $fs $blks $used $avail >&2
    341 				b=$avail
    342 			 done
    343 			 echo $b) )
    344 
    345 			# check if blks is a number, else set a default value for blks
    346 			default_sz=1000000
    347 			if [ $blks -eq $blks 2> /dev/null ]
    348 			then
    349 
    350 				case $(uname) in
    351 				Linux)  blks=$( expr $blks / 2 ) ;;
    352 				esac
    353 
    354 				szcache[${#szcache[*]}+1]=$dir
    355 				szblks[${#szblks[*]}+1]=$blks
    356 
    357 				max=${size##*\%}
    358 				[ "x$max" = "x" ] && max=$default_sz
    359 				size=${size%%\%*}
    360 
    361 				case $(uname) in
    362 				IRIX*)
    363 				  sz=$( perl -le 'print int( '$blks' * '$size' / 100 )' )
    364 				  ;;
    365 				*)
    366 				  sz=$(expr \( $blks '*' $size \) / 100)
    367 				  ;;
    368 				esac
    369 
    370 				if [ $sz -gt $max ]
    371 				then
    372 					sz=$max
    373 				fi
    374 			else
    375 				sz=$default_sz
    376 			fi
    377 		fi
    378 		f=$sz"b:"$file
    379 	fi
    380 	F[${#F[*]}+1]=$f
    381 done
    382 
    383 Files=${F[*]}
    384 
    385 if [[ -z ${dOpts} ]]; then
    386 	dOpts=-av
    387 fi
    388 
    389 if [[ -n "$opt_F" ]]; then
    390 
    391 	echo $Files
    392 
    393 else
    394 
    395 	cmd="${LTPROOT}/testcases/bin/iogen ${iOpts} ${Files} | $MPPrun ${LTPROOT}/testcases/bin/doio ${dOpts}"
    396 
    397 	if [[ -z "$Quiet" ]]; then
    398 		echo $cmd
    399 	fi
    400 
    401 	trap "killkids" INT
    402 	trap "cleanup_and_exit 2" HUP
    403 
    404 	( ${LTPROOT}/testcases/bin/iogen ${iOpts} ${Files}
    405 	  r=$?
    406 	  if [ $r -ne 0 ]
    407 	  then
    408 		echo "$Prog$Name : iogen reported errors (r=$r)" >&2
    409 		tst_resm TFAIL "iogen reported errors (r=$r)"
    410 		kill -HUP $$
    411 	  fi
    412 	) | $MPPrun ${LTPROOT}/testcases/bin/doio ${dOpts}
    413 	r=$?
    414 	if [ $r -ne 0 ]
    415 	then
    416 		echo "$Prog$Name : doio reported errors (r=$r)" >&2
    417 		tst_resm TFAIL "doio reported errors (r=$r)"
    418 	fi
    419 
    420 	cleanup_and_exit $r
    421 fi
    422