Merge branch 'master' of https://github.com/Venutiwa/fio
[fio.git] / tools / genfio
CommitLineData
c60587f6 1#!/usr/bin/env bash
afbbd646
EV
2#
3# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
4# Author: Erwan Velu <erwan@enovance.com>
5#
6# The license below covers all files distributed with fio unless otherwise
7# noted in the file itself.
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License version 2 as
11# published by the Free Software Foundation.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
22BLK_SIZE=
23BLOCK_SIZE=4k
24SEQ=-1
25TEMPLATE=/tmp/template.fio
26OUTFILE=
27DISKS=
bed59bab 28PRINTABLE_DISKS=
afbbd646
EV
29RUNTIME=300
30ETA=0
60238f0e 31MODES="write,randwrite,read,randread"
afbbd646 32SHORT_HOSTNAME=
76c7c63e 33CACHED_IO="FALSE"
a7419837
EV
34PREFIX=""
35PREFIX_FILENAME=""
7d1ca6cf 36IODEPTH=1
afbbd646
EV
37
38show_help() {
39 PROG=$(basename $0)
40 echo "usage of $PROG:"
41 cat << EOF
42-h : Show this help & exit
76c7c63e 43-c : Enable cached-based IOs
e1c6f2e1 44 Disabled by default
afbbd646 45-a : Run sequential test then parallel one
e1c6f2e1 46 Disabled by default
afbbd646
EV
47-s : Run sequential test (default value)
48 one test after another then one disk after another
e1c6f2e1 49 Disabled by default
afbbd646
EV
50-p : Run parallel test
51 one test after anoter but all disks at the same time
e1c6f2e1 52 Enabled by default
7d1ca6cf 53-D iodepth : Run with the specified iodepth
80139d2d 54 Default is $IODEPTH
afbbd646
EV
55-d disk1[,disk2,disk3,..] : Run the tests on the selected disks
56 Separated each disk with a comma
f6facd21
LM
57-z filesize : Specify the working file size, if you are passing filepaths to -d
58 Disabled by default
e1c6f2e1 59-r seconds : Time in seconds per benchmark
72fe3ef1 60 0 means till the end of the device
80139d2d 61 Default is $RUNTIME seconds
afbbd646
EV
62-b blocksize[,blocksize1, ...] : The blocksizes to test under fio format (4k, 1m, ...)
63 Separated each blocksize with a comma
80139d2d 64 Default is $BLOCK_SIZE
afbbd646 65-m mode1,[mode2,mode3, ...] : Define the fio IO profile to use like read, write, randread, randwrite
80139d2d 66 Default is "$MODES"
a7419837
EV
67-x prefix : Add a prefix to the fio filename
68 Useful to let a context associated with the file
69 If the prefix features a / (slash), prefix will be considered as a directory
ca143750
EV
70-A cmd_to_run : System command to run after each job (exec_postrun in fio)
71-B cmd_to_run : System command to run before each job (exec_prerun in fio)
afbbd646
EV
72
73Example:
74
bed59bab 75$PROG -d /dev/sdb,/dev/sdc,/dev/sdd,/dev/sde -a -b 4k,128k,1m -r 100 -a -x dellr720-day2/
afbbd646
EV
76
77 Will generate an fio file that will run
60238f0e 78 - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 4k with write,randwrite,read,randread tests
afbbd646 79 ETA ~ 4 tests * 4 disks * 100 seconds
60238f0e 80 - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 128k with write,randwrite,read,randread tests
afbbd646 81 ETA ~ 4 tests * 4 disks * 100 seconds
60238f0e 82 - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 1m with write,randwrite,read,randread tests
afbbd646 83 ETA ~ 4 tests * 4 disks * 100 seconds
60238f0e 84 - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 4k with write,randwrite,read,randread tests
afbbd646 85 ETA ~ 4 tests * 100 seconds
60238f0e 86 - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 128k with write,randwrite,read,randread tests
afbbd646 87 ETA ~ 4 tests * 100 seconds
60238f0e 88 - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 1m with write,randwrite,read,randread tests
afbbd646
EV
89 ETA ~ 4 tests * 100 seconds
90
60238f0e 91Generating dellr720-day2/localhost-4k,128k,1m-all-write,randwrite,read,randread-sdb,sdc,sdd,sde.fio
afbbd646
EV
92Estimated Time = 6000 seconds : 1 hour 40 minutes
93EOF
94}
95
fdc0f3b6 96finish_template() {
ea0542d9 97echo "iodepth=$IODEPTH" >> $TEMPLATE
afbbd646 98
72fe3ef1 99if [ "$RUNTIME" != "0" ]; then
ea0542d9
EV
100 echo "runtime=$RUNTIME" >> $TEMPLATE
101 echo "time_based" >> $TEMPLATE
72fe3ef1
EV
102fi
103
76c7c63e 104if [ "$CACHED_IO" = "FALSE" ]; then
ea0542d9 105 echo "direct=1" >> $TEMPLATE
76c7c63e 106fi
fdc0f3b6 107}
76c7c63e 108
bed59bab
EV
109
110diskname_to_printable() {
111COUNT=0
112for disk in $(echo $@ | tr "," " "); do
113 R=$(basename $disk | sed 's|/|_|g')
114 COUNT=$(($COUNT + 1))
115 if [ $COUNT -eq 1 ]; then
116 P="$R"
117 else
118 P="$P,$R"
119 fi
120done
121echo $P
122}
123
fdc0f3b6
EV
124gen_template() {
125cat >$TEMPLATE << EOF
126[global]
127ioengine=libaio
128invalidate=1
129ramp_time=5
130EOF
afbbd646
EV
131}
132
133gen_seq_suite() {
134TYPE=$1
bed59bab
EV
135disk=$2
136PRINTABLE_DISK=$(diskname_to_printable $disk)
afbbd646 137cat >> $OUTFILE << EOF
bed59bab 138[$TYPE-$PRINTABLE_DISK-$BLK_SIZE-seq]
afbbd646
EV
139stonewall
140bs=$BLK_SIZE
bed59bab 141filename=$disk
afbbd646 142rw=$TYPE
bed59bab
EV
143write_bw_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$PRINTABLE_DISK-$TYPE-seq.results
144write_iops_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$PRINTABLE_DISK-$TYPE-seq.results
afbbd646
EV
145EOF
146ETA=$(($ETA + $RUNTIME))
147}
148
149gen_seq_fio() {
150for disk in $(echo $DISKS | tr "," " "); do
151 for mode in $(echo $MODES | tr "," " "); do
bed59bab 152 gen_seq_suite "$mode" "$disk"
afbbd646
EV
153 done
154done
155}
156
157
158gen_para_suite() {
159TYPE=$1
160NEED_WALL=$2
161D=0
162for disk in $(echo $DISKS | tr "," " "); do
bed59bab 163 PRINTABLE_DISK=$(diskname_to_printable $disk)
afbbd646 164 cat >> $OUTFILE << EOF
bed59bab 165[$TYPE-$PRINTABLE_DISK-$BLK_SIZE-para]
afbbd646
EV
166bs=$BLK_SIZE
167EOF
168
169if [ "$D" = 0 ]; then
170 echo "stonewall" >> $OUTFILE
171 D=1
172fi
173
174cat >> $OUTFILE << EOF
bed59bab 175filename=$disk
afbbd646 176rw=$TYPE
bed59bab
EV
177write_bw_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$PRINTABLE_DISK-$TYPE-para.results
178write_iops_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$PRINTABLE_DISK-$TYPE-para.results
afbbd646
EV
179EOF
180done
181
182ETA=$(($ETA + $RUNTIME))
183echo >> $OUTFILE
184}
185
186gen_para_fio() {
187for mode in $(echo $MODES | tr "," " "); do
188 gen_para_suite "$mode"
189done
190}
191
192gen_fio() {
193case $SEQ in
194 2)
195 gen_seq_fio
196 gen_para_fio
197 ;;
198 1)
199 gen_seq_fio
200 ;;
201 0)
202 gen_para_fio
203 ;;
204esac
205}
206
207parse_cmdline() {
f6facd21 208while getopts "hacpsd:b:r:m:x:z:D:A:B:" opt; do
afbbd646
EV
209 case $opt in
210 h)
211 show_help
212 exit 0
213 ;;
214 b)
215 BLOCK_SIZE=$OPTARG
216 ;;
76c7c63e
EV
217 c)
218 CACHED_IO="TRUE"
219 ;;
afbbd646
EV
220 s)
221 if [ "$SEQ" = "-1" ]; then
222 SEQ=1
223 fi
224 ;;
a7419837
EV
225 x)
226 PREFIX=$OPTARG
227 echo "$PREFIX" | grep -q "/"
228 if [ "$?" -eq 0 ]; then
229 mkdir -p $PREFIX
230 # No need to keep the prefix for the log files
231 # we do have a directory for that
232 PREFIX_FILENAME=""
233 else
234 # We need to keep the prefix for the log files
235 PREFIX_FILENAME=$PREFIX
236 fi
237 ;;
afbbd646
EV
238 r)
239 RUNTIME=$OPTARG
240 ;;
241 p)
242 if [ "$SEQ" = "-1" ]; then
243 SEQ=0
244 fi
245 ;;
246 m)
247 MODES=$OPTARG;
248 ;;
249 d)
250 DISKS=$OPTARG
bed59bab 251 PRINTABLE_DISKS=$(diskname_to_printable "$DISKS")
afbbd646 252 ;;
7d1ca6cf
EV
253 D)
254 IODEPTH=$OPTARG
255 ;;
afbbd646
EV
256 a)
257 SEQ=2
258 ;;
ca143750
EV
259 B)
260 echo "exec_prerun=$OPTARG" >> $TEMPLATE
261 ;;
262 A)
263 echo "exec_postrun=$OPTARG" >> $TEMPLATE
264 ;;
f6facd21
LM
265 z)
266 FSIZE=$OPTARG
267 echo "size=$FSIZE" >> $TEMPLATE
268 ;;
afbbd646
EV
269 \?)
270 echo "Invalid option: -$OPTARG" >&2
271 ;;
272 esac
273done
274
275if [ "$SEQ" = "-1" ]; then
276 SEQ=0
277fi
278
279SHORT_HOSTNAME=$(hostname -s)
280case $SEQ in
281 2)
bed59bab 282 OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-all-$MODES-$PRINTABLE_DISKS.fio
afbbd646
EV
283 ;;
284
285 1)
bed59bab 286 OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-sequential-$MODES-$PRINTABLE_DISKS.fio
afbbd646
EV
287 ;;
288 0)
bed59bab 289 OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-parallel-$MODES-$PRINTABLE_DISKS.fio
afbbd646
EV
290 ;;
291esac
292
293if [ -z "$DISKS" ]; then
294 echo "Missing DISKS !"
e1c6f2e1
EV
295 echo "Please read the help !"
296 show_help
afbbd646
EV
297 exit 1
298fi
299
300}
301
60238f0e
EV
302check_mode_order() {
303FOUND_WRITE="NO"
304CAUSE="You are reading data before writing them "
305
306# If no write occurs, let's show a different message
307echo $MODES | grep -q "write"
308if [ "$?" -ne 0 ]; then
309 CAUSE="You are reading data while never wrote them before"
310fi
311
312for mode in $(echo $MODES | tr "," " "); do
313 echo $mode | grep -q write
314 if [ "$?" -eq 0 ]; then
315 FOUND_WRITE="YES"
316 fi
317 echo $mode | grep -q "read"
318 if [ "$?" -eq 0 ]; then
319 if [ "$FOUND_WRITE" = "NO" ]; then
320 echo "###############################################################"
321 echo "# Warning : $CAUSE#"
322 echo "# On some storage devices, this could lead to invalid results #"
323 echo "# #"
324 echo "# Press Ctrl-C to adjust pattern order if you have doubts #"
325 echo "# Or Wait 5 seconds before the file will be created #"
326 echo "###############################################################"
327 sleep 5
328 # No need to try showing the message more than one time
329 return
330 fi
331 fi
332done
333}
334
afbbd646
EV
335
336########## MAIN
fdc0f3b6 337gen_template
3b73c537 338parse_cmdline "$@"
fdc0f3b6 339finish_template
60238f0e 340check_mode_order
afbbd646
EV
341
342echo "Generating $OUTFILE"
343cp -f $TEMPLATE $OUTFILE
344echo >> $OUTFILE
345
346for BLK_SIZE in $(echo $BLOCK_SIZE | tr "," " "); do
347 gen_fio
348done
349ETA_H=$(($ETA / 3600))
350ETA_M=$((($ETA - ($ETA_H*3600)) / 60))
af360e39 351if [ "$ETA" = "0" ]; then
72fe3ef1
EV
352 echo "Cannot estimate ETA as RUNTIME=0"
353else
354 echo "Estimated Time = $ETA seconds : $ETA_H hour $ETA_M minutes"
355fi