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