generic/457: use thin volume for dmlogwrites target device
[xfstests-dev.git] / ltp / rwtest.sh
1 #!/bin/bash
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         Linux)                  dfOpts="-P"     ;;
256         *)                      dfOpts="-PB"    ;;
257 esac
258
259 for f in $Files
260 do
261         file=${f##*:}
262         if [ ! -f "$file" ]
263         then
264                 Files_To_Remove="$Files_To_Remove $file"
265         fi
266
267         dir=$(dirname $file)
268         size=${f%%:*}
269         if [[ $size = *%* ]]
270         then
271
272                 typeset -i n=0
273                 while (( n < ${#szcache[*]} ))
274                 do
275                         if [[ szcache[$n] = $dir ]]; then
276                                 break;
277                         fi
278                         n=n+1
279                 done
280
281                 if (( n < ${#szcache[*]} ))
282                 then
283                         blks=${szblks[$n]}
284                 else
285                         blks=$(df $dfOpts $dir |
286                         (while read fs blks used avail cap mountpoint
287                          do
288                                 #echo $fs $blks $used $avail >&2
289                                 b=$avail
290                          done
291                          echo $b) )
292
293                         case $(uname) in
294                         Linux)  blks=$( expr $blks / 2 ) ;;
295                         esac
296
297                         szcache[${#szcache[*]}+1]=$dir
298                         szblks[${#szblks[*]}+1]=$blks
299                 fi
300
301                 max=${size##*\%}
302                 if [[ "$max" = "" ]]
303                 then
304                         max=1000000
305                 fi
306                 size=${size%%\%*}
307
308                 sz=$(expr \( $blks '*' $size \) / 100)
309
310                 if [[ $sz -gt $max ]]
311                 then
312                         sz=$max
313                 fi
314                 f=$sz"b:"$file
315         fi
316         F[${#F[*]}+1]=$f
317 done
318
319 Files=${F[*]}
320
321 if [[ -z ${dOpts} ]]; then
322         dOpts=-av
323 fi
324
325 if [[ -n "$opt_F" ]]; then
326
327         echo $Files
328
329 else
330
331         [[ -n "$here" ]] || here=`pwd`
332         if [[ -x ${LTPROOT}/testcases/bin/iogen ]]; then
333                 IOgen=${LTPROOT}/testcases/bin/iogen
334         elif [[ -x ${here}/ltp/iogen ]]; then
335                 IOgen=$here/ltp/iogen
336         elif [[ -x ./iogen ]]; then
337                 IOgen=./iogen
338         else
339                 echo Cannot find iogen command
340                 exit 1
341         fi
342         if [[ -x ${LTPROOT}/testcases/bin/doio ]]; then
343                 doIO=${LTPROOT}/testcases/bin/doio
344         elif [[ -x ${here}/ltp/doio ]]; then
345                 doIO=$here/ltp/doio
346         elif [[ -x ./doio ]]; then
347                 doIO=./doio
348         else
349                 echo Cannot find doio command
350                 exit 1
351         fi
352
353         cmd="$IOgen ${iOpts} ${Files} | $MPPrun $doIO ${dOpts}"
354
355         if [[ -z "$Quiet" ]]; then
356                 echo $cmd
357         fi
358
359         trap "killkids" INT
360         trap "cleanup_and_exit 2" HUP
361
362         ( $IOgen ${iOpts} ${Files}
363           r=$?
364           if [ $r -ne 0 ]
365           then
366                 echo "$Prog$Name : iogen reported errors (r=$r)" >&2
367                 kill -HUP $$
368           fi
369         ) | $MPPrun $doIO ${dOpts}
370         r=$?
371         if [ $r -ne 0 ]
372         then
373                 echo "$Prog$Name : doio reported errors (r=$r)" >&2
374         fi
375
376         cleanup_and_exit $r
377 fi