5e358ab41834fc585be1ff6f5d37e826916087e7
[xfstests-dev.git] / ltp / rwtest.sh
1 #!/bin/sh
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., 59
22 # Temple Place - Suite 330, Boston MA 02111-1307, 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=$(basename $0)
40
41 iOpts=""
42 dOpts=""
43 LockRegion=""
44 Nprocs=1
45 Files=""
46 Remove_Test_Files=""
47 Files_To_Remove=""
48 MPPrun=""
49
50 usage()
51 {
52         echo "$Prog: [-chq] [-N name] [ iogen options ] [ doio options ] files" >&2
53 }
54
55 help()
56 {
57         echo "\
58     -c           Cleanup test files created by this invocation on exit.
59                  Default is to leave them.  
60     -h           This help - ignore all other options/arguments
61     -F           Only process filenames - does not run iogen & doio.
62     -P Places    Not used
63     -S Scenario  Execute an internal scenario.
64     -N Name      Pan-style name to be printed with error messages.
65
66     Options passed through to iogen:
67     -[afiLmOstT] arg
68     -o
69     -q           Set rwtest to be quiet and pass the flag on to iogen.
70
71     Options passed through to doio:
72     -D[rmMVUC] arg
73     -D[aekv]
74     -n nprocs    # procs to do simultanious io to the test files.
75                  Default is 1.  If -n is non-zero, doio's -k option (use
76                  file locking) is forced.
77
78     files        Files to test on.  File names have the following fomat:
79                  [ size: ] path
80                  [ free% [ max size ] : ] path
81                  If no size is specified, the files must exist
82                  and the contents will be overwritten if testing write or
83                  writea system calls.  If a size is supplied, an attempt to
84                  create/grow/shrink path to the desired size will be made.
85                  size is an integer which defaults to bytes, but may be
86                  suffixed by 'b', 'k', or 'm' for blocks (4096 byte units), 
87                  kilobytes (1024 byte units), or megabytes (2^20 byte units).
88
89                  If the size is a percentage, df is used to find how much
90                  free space there is (in blocks), and uses that.  The maximum
91                  size is implied to be in blocks.
92 " >&2
93 }
94
95 killkids()
96 {
97         trap "killkids" INT
98         if [[ -z $didkids ]]
99         then
100                 didkids=done
101                 kill -INT -$$
102         fi
103 }
104
105
106 cleanup_and_exit()
107 {
108         if [ -n "$Remove_Test_Files" ]
109         then
110                 if [ -n "$Files_To_Remove" ]
111                 then
112                         rm -f $Files_To_Remove
113                 fi
114         fi
115
116         exit $1
117 }
118
119 while (( $# > 0 ))
120 do      case $1 in
121         -c)     Remove_Test_Files=yes
122                 ;;
123
124         -d)     debug=$2
125                 shift
126                 ;;
127
128         -h)     help
129                 exit 0
130                 ;;
131
132         -F)
133                 opt_F="-F"      # only process filenames
134                 ;;
135
136         -P)
137                 PLACES=$2
138                 shift
139                 ;;
140
141         -S)     Scenario=$2
142                 shift
143                 opt_S="-S"
144                 ;;
145
146         -N)     Name="($2)"
147                 iOpts="$iOpts -N $2"
148                 dOpts="$dOpts -N $2"
149                 shift
150                 ;;
151
152         # iogen Options to pass thru ... options with an argument
153         -[afiLmOstT] )
154                 iOpts="$iOpts $1 $2"
155                 shift
156                 ;;
157
158         # iogen Options to pass thru ... just the option
159         -[o] )
160                 iOpts="$iOpts $1"
161                 ;;
162
163         # iogen options to look at
164         -q)
165                 iOpts="$iOpts $1"
166                 Quiet=$1
167                 ;;
168
169         # doio Options to pass thru ... options with an argument
170         -D[rmMVUC] )
171                 o=${1#-D}
172                 dOpts="$dOpts -$o $2"
173                 shift
174                 ;;
175
176         # doio options to pass thru ... just the options
177         -D[aekv] )
178                 o=${1#-D}
179                 dOpts="$dOpts -$o"
180                 ;;
181
182         # doio options to look at
183         -n | -Dn )
184                 dOpts="$dOpts $1 $2"
185                 # force file locking with > 1 process
186                 if [[ $2 > 1 ]]
187                 then
188                         dOpts="$dOpts -k"
189                 fi
190                 opt_n="-n"
191                 shift
192                 ;;
193
194         \? | -*)
195                 echo "$Prog:  Illegal option $1" >&2
196                 exit 1
197                 ;;
198
199         *)
200                 break
201                 ;;
202         esac
203         shift
204 done
205
206 if [[ $TOUTPUT = "NOPASS" ]]; then
207         iOpts="$iOpts -q"
208         Quiet="-q"
209 fi
210
211 #
212 # Hard-Coded Scenario Specifications
213 #
214 # FSA           RAW I/O via FSA
215 # MPPnnn        Run as a <nnn> sized MPP application
216 # userstripe    create files using user striping
217 #
218
219 if [[ -n "$opt_S" ]]
220 then
221         case $Scenario in
222
223         FSA )
224                 # I/O via FSA
225                 Flags="parallel"
226                 Nprocs=1
227                 LockRegion=""
228         ;;
229
230         MPP* )
231                 # use mpprun...  to cooperate with a batch system, this
232                 # requires scanning mppview, etc.
233
234                 NPE=${Scenario#MPP}
235                 MPPrun=" mpprun -n $NPE "
236         ;;
237         userstripe)
238                 #create files using user striping
239                 Oflags=O_PLACE,0xffffffffffffffff,1000
240         ;;
241
242         places*)
243                 FSIZE=${Scenario#places-}
244                 oi="$IFS"
245                 IFS=":"
246                 set -- $PLACES
247                 if [ $# -eq 0 ]
248                 then
249                         # "this isn't supposed to happen"
250                         Files="25%:rwtest.$$"
251                 else
252                         IFS="$oi"
253                         PL=${*}
254                         for p in $PL
255                         do
256                                 f="$f "${FSIZE}":"${p}"/rwtest$$"
257                         done
258                         set -- $f
259                 fi
260         ;;
261         esac
262 fi
263
264 #
265 # If no files are specified ...
266 #       check if PLACES is set; if so, put one file in each place
267 #       otherwise generate one filename in the current directory.
268 #
269
270 if [ $# -eq 0 ]
271 then
272         # put one file in each of $PLACES
273         Files="25%:rwtest.file"
274 else
275         Files=$*
276 fi
277
278 #
279 # use 'df -PB' to see how many blocks are available, apply a hard limit of
280 # 1,000,000 blocks if no limit is specified
281 #
282
283 case $(uname -s) in
284         IRIX | IRIX64 )         dfOpts="-Pb"    ;;
285         Linux)                  dfOpts="-P"     ;;
286         *)                      dfOpts="-PB"    ;;
287 esac
288
289 for f in $Files
290 do
291         file=${f##*:}
292         if [ ! -f "$file" ]
293         then
294                 Files_To_Remove="$Files_To_Remove $file"
295         fi
296
297         dir=$(dirname $file)
298         size=${f%%:*}
299         if [[ $size = *%* ]]
300         then
301
302                 typeset -i n=0
303                 while (( n < ${#szcache[*]} ))
304                 do
305                         if [[ szcache[$n] = $dir ]]; then
306                                 break;
307                         fi
308                         n=n+1
309                 done
310
311                 if (( n < ${#szcache[*]} ))
312                 then
313                         blks=${szblks[$n]}
314                 else
315                         blks=$(df $dfOpts $dir |
316                         (while read fs blks used avail cap mountpoint
317                          do
318                                 #echo $fs $blks $used $avail >&2
319                                 b=$avail
320                          done
321                          echo $b) )
322
323                         case $(uname) in
324                         Linux)  blks=$( expr $blks / 2 ) ;;
325                         esac
326
327                         szcache[${#szcache[*]}+1]=$dir
328                         szblks[${#szblks[*]}+1]=$blks
329                 fi
330
331                 max=${size##*\%}
332                 if [[ "$max" = "" ]]
333                 then
334                         max=1000000
335                 fi
336                 size=${size%%\%*}
337
338                 sz=$(expr \( $blks '*' $size \) / 100)
339
340                 if [[ $sz -gt $max ]]
341                 then
342                         sz=$max
343                 fi
344                 f=$sz"b:"$file
345         fi
346         F[${#F[*]}+1]=$f
347 done
348
349 Files=${F[*]}
350
351 if [[ -z ${dOpts} ]]; then
352         dOpts=-av
353 fi
354
355 if [[ -n "$opt_F" ]]; then
356
357         echo $Files
358
359 else
360
361         [[ -n "$here" ]] || here=`pwd`
362         if [[ -x ${LTPROOT}/testcases/bin/iogen ]]; then
363                 IOgen=${LTPROOT}/testcases/bin/iogen
364         elif [[ -x ${here}/ltp/iogen ]]; then
365                 IOgen=$here/ltp/iogen
366         elif [[ -x ./iogen ]]; then
367                 IOgen=./iogen
368         else
369                 echo Cannot find iogen command
370                 exit 1
371         fi
372         if [[ -x ${LTPROOT}/testcases/bin/doio ]]; then
373                 doIO=${LTPROOT}/testcases/bin/doio
374         elif [[ -x ${here}/ltp/doio ]]; then
375                 doIO=$here/ltp/doio
376         elif [[ -x ./doio ]]; then
377                 doIO=./doio
378         else
379                 echo Cannot find doio command
380                 exit 1
381         fi
382
383         cmd="$IOgen ${iOpts} ${Files} | $MPPrun $doIO ${dOpts}"
384
385         if [[ -z "$Quiet" ]]; then
386                 echo $cmd
387         fi
388
389         trap "killkids" INT
390         trap "cleanup_and_exit 2" HUP
391
392         ( $IOgen ${iOpts} ${Files}
393           r=$?
394           if [ $r -ne 0 ]
395           then
396                 echo "$Prog$Name : iogen reported errors (r=$r)" >&2
397                 kill -HUP $$
398           fi
399         ) | $MPPrun $doIO ${dOpts}
400         r=$?
401         if [ $r -ne 0 ]
402         then
403                 echo "$Prog$Name : doio reported errors (r=$r)" >&2
404         fi
405
406         cleanup_and_exit $r
407 fi