genfio: Warn users if read occurs before write
[fio.git] / tools / genfio
CommitLineData
afbbd646
EV
1#!/bin/bash
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=
28RUNTIME=300
29ETA=0
60238f0e 30MODES="write,randwrite,read,randread"
afbbd646 31SHORT_HOSTNAME=
76c7c63e 32CACHED_IO="FALSE"
a7419837
EV
33PREFIX=""
34PREFIX_FILENAME=""
afbbd646
EV
35
36show_help() {
37 PROG=$(basename $0)
38 echo "usage of $PROG:"
39 cat << EOF
40-h : Show this help & exit
76c7c63e 41-c : Enable cached-based IOs
e1c6f2e1 42 Disabled by default
afbbd646 43-a : Run sequential test then parallel one
e1c6f2e1 44 Disabled by default
afbbd646
EV
45-s : Run sequential test (default value)
46 one test after another then one disk after another
e1c6f2e1 47 Disabled by default
afbbd646
EV
48-p : Run parallel test
49 one test after anoter but all disks at the same time
e1c6f2e1 50 Enabled by default
afbbd646
EV
51-d disk1[,disk2,disk3,..] : Run the tests on the selected disks
52 Separated each disk with a comma
53 Disk name shall be "sdxx", /dev/ shall NOT be used here
e1c6f2e1 54-r seconds : Time in seconds per benchmark
72fe3ef1 55 0 means till the end of the device
e1c6f2e1 56 Default is 300 seconds
afbbd646
EV
57-b blocksize[,blocksize1, ...] : The blocksizes to test under fio format (4k, 1m, ...)
58 Separated each blocksize with a comma
e1c6f2e1 59 Default is 4k
afbbd646 60-m mode1,[mode2,mode3, ...] : Define the fio IO profile to use like read, write, randread, randwrite
60238f0e 61 Default is "write,randwrite,read,randread"
a7419837
EV
62-x prefix : Add a prefix to the fio filename
63 Useful to let a context associated with the file
64 If the prefix features a / (slash), prefix will be considered as a directory
afbbd646
EV
65
66Example:
67
a7419837 68$PROG -d sdb,sdc,sdd,sde -a -b 4k,128k,1m -r 100 -a -x dellr720-day2/
afbbd646
EV
69
70 Will generate an fio file that will run
60238f0e 71 - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 4k with write,randwrite,read,randread tests
afbbd646 72 ETA ~ 4 tests * 4 disks * 100 seconds
60238f0e 73 - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 128k with write,randwrite,read,randread tests
afbbd646 74 ETA ~ 4 tests * 4 disks * 100 seconds
60238f0e 75 - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 1m with write,randwrite,read,randread tests
afbbd646 76 ETA ~ 4 tests * 4 disks * 100 seconds
60238f0e 77 - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 4k with write,randwrite,read,randread tests
afbbd646 78 ETA ~ 4 tests * 100 seconds
60238f0e 79 - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 128k with write,randwrite,read,randread tests
afbbd646 80 ETA ~ 4 tests * 100 seconds
60238f0e 81 - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 1m with write,randwrite,read,randread tests
afbbd646
EV
82 ETA ~ 4 tests * 100 seconds
83
60238f0e 84Generating dellr720-day2/localhost-4k,128k,1m-all-write,randwrite,read,randread-sdb,sdc,sdd,sde.fio
afbbd646
EV
85Estimated Time = 6000 seconds : 1 hour 40 minutes
86EOF
87}
88
89gen_template() {
90cat >$TEMPLATE << EOF
91[global]
92ioengine=libaio
93invalidate=1
afbbd646 94ramp_time=5
72fe3ef1 95EOF
afbbd646 96
72fe3ef1
EV
97if [ "$RUNTIME" != "0" ]; then
98cat >>$TEMPLATE << EOF
99runtime=$RUNTIME
afbbd646 100EOF
72fe3ef1
EV
101fi
102
76c7c63e
EV
103if [ "$CACHED_IO" = "FALSE" ]; then
104cat >>$TEMPLATE << EOF
105direct=1
106EOF
107fi
108
afbbd646
EV
109}
110
111gen_seq_suite() {
112TYPE=$1
113cat >> $OUTFILE << EOF
114[$TYPE-$disk-$BLK_SIZE-seq]
115stonewall
116bs=$BLK_SIZE
117filename=/dev/$disk
118rw=$TYPE
a7419837
EV
119write_bw_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$disk-$TYPE-seq.results
120write_iops_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$disk-$TYPE-seq.results
afbbd646
EV
121EOF
122ETA=$(($ETA + $RUNTIME))
123}
124
125gen_seq_fio() {
126for disk in $(echo $DISKS | tr "," " "); do
127 for mode in $(echo $MODES | tr "," " "); do
128 gen_seq_suite "$mode"
129 done
130done
131}
132
133
134gen_para_suite() {
135TYPE=$1
136NEED_WALL=$2
137D=0
138for disk in $(echo $DISKS | tr "," " "); do
139 cat >> $OUTFILE << EOF
140[$TYPE-$disk-$BLK_SIZE-para]
141bs=$BLK_SIZE
142EOF
143
144if [ "$D" = 0 ]; then
145 echo "stonewall" >> $OUTFILE
146 D=1
147fi
148
149cat >> $OUTFILE << EOF
150filename=/dev/$disk
151rw=$TYPE
a7419837
EV
152write_bw_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$disk-$TYPE-para.results
153write_iops_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$disk-$TYPE-para.results
afbbd646
EV
154EOF
155done
156
157ETA=$(($ETA + $RUNTIME))
158echo >> $OUTFILE
159}
160
161gen_para_fio() {
162for mode in $(echo $MODES | tr "," " "); do
163 gen_para_suite "$mode"
164done
165}
166
167gen_fio() {
168case $SEQ in
169 2)
170 gen_seq_fio
171 gen_para_fio
172 ;;
173 1)
174 gen_seq_fio
175 ;;
176 0)
177 gen_para_fio
178 ;;
179esac
180}
181
182parse_cmdline() {
a7419837 183while getopts "hacpsd:b:r:m:x:" opt; do
afbbd646
EV
184 case $opt in
185 h)
186 show_help
187 exit 0
188 ;;
189 b)
190 BLOCK_SIZE=$OPTARG
191 ;;
76c7c63e
EV
192 c)
193 CACHED_IO="TRUE"
194 ;;
afbbd646
EV
195 s)
196 if [ "$SEQ" = "-1" ]; then
197 SEQ=1
198 fi
199 ;;
a7419837
EV
200 x)
201 PREFIX=$OPTARG
202 echo "$PREFIX" | grep -q "/"
203 if [ "$?" -eq 0 ]; then
204 mkdir -p $PREFIX
205 # No need to keep the prefix for the log files
206 # we do have a directory for that
207 PREFIX_FILENAME=""
208 else
209 # We need to keep the prefix for the log files
210 PREFIX_FILENAME=$PREFIX
211 fi
212 ;;
afbbd646
EV
213 r)
214 RUNTIME=$OPTARG
215 ;;
216 p)
217 if [ "$SEQ" = "-1" ]; then
218 SEQ=0
219 fi
220 ;;
221 m)
222 MODES=$OPTARG;
223 ;;
224 d)
225 DISKS=$OPTARG
226 ;;
227 a)
228 SEQ=2
229 ;;
230 \?)
231 echo "Invalid option: -$OPTARG" >&2
232 ;;
233 esac
234done
235
236if [ "$SEQ" = "-1" ]; then
237 SEQ=0
238fi
239
240SHORT_HOSTNAME=$(hostname -s)
241case $SEQ in
242 2)
a7419837 243 OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-all-$MODES-$DISKS.fio
afbbd646
EV
244 ;;
245
246 1)
a7419837 247 OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-sequential-$MODES-$DISKS.fio
afbbd646
EV
248 ;;
249 0)
a7419837 250 OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-parallel-$MODES-$DISKS.fio
afbbd646
EV
251 ;;
252esac
253
254if [ -z "$DISKS" ]; then
255 echo "Missing DISKS !"
e1c6f2e1
EV
256 echo "Please read the help !"
257 show_help
afbbd646
EV
258 exit 1
259fi
260
261}
262
60238f0e
EV
263check_mode_order() {
264FOUND_WRITE="NO"
265CAUSE="You are reading data before writing them "
266
267# If no write occurs, let's show a different message
268echo $MODES | grep -q "write"
269if [ "$?" -ne 0 ]; then
270 CAUSE="You are reading data while never wrote them before"
271fi
272
273for mode in $(echo $MODES | tr "," " "); do
274 echo $mode | grep -q write
275 if [ "$?" -eq 0 ]; then
276 FOUND_WRITE="YES"
277 fi
278 echo $mode | grep -q "read"
279 if [ "$?" -eq 0 ]; then
280 if [ "$FOUND_WRITE" = "NO" ]; then
281 echo "###############################################################"
282 echo "# Warning : $CAUSE#"
283 echo "# On some storage devices, this could lead to invalid results #"
284 echo "# #"
285 echo "# Press Ctrl-C to adjust pattern order if you have doubts #"
286 echo "# Or Wait 5 seconds before the file will be created #"
287 echo "###############################################################"
288 sleep 5
289 # No need to try showing the message more than one time
290 return
291 fi
292 fi
293done
294}
295
afbbd646
EV
296
297########## MAIN
298parse_cmdline $@
60238f0e 299check_mode_order
afbbd646
EV
300gen_template
301
302echo "Generating $OUTFILE"
303cp -f $TEMPLATE $OUTFILE
304echo >> $OUTFILE
305
306for BLK_SIZE in $(echo $BLOCK_SIZE | tr "," " "); do
307 gen_fio
308done
309ETA_H=$(($ETA / 3600))
310ETA_M=$((($ETA - ($ETA_H*3600)) / 60))
af360e39 311if [ "$ETA" = "0" ]; then
72fe3ef1
EV
312 echo "Cannot estimate ETA as RUNTIME=0"
313else
314 echo "Estimated Time = $ETA seconds : $ETA_H hour $ETA_M minutes"
315fi