X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=tools%2Fgenfio;h=286d814de71506c0c187dd4a6b530b446b54e9b7;hp=3599450663e83951dda78a1697e81b43f38678e8;hb=fa07eaa6913d7171c4259b3b0cd76dae3e76ca00;hpb=af360e392d3c9f6a299596adfcfef8de2f198ad2 diff --git a/tools/genfio b/tools/genfio index 35994506..286d814d 100755 --- a/tools/genfio +++ b/tools/genfio @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/bash # # Copyright (C) 2013 eNovance SAS # Author: Erwan Velu @@ -17,7 +17,7 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BLK_SIZE= BLOCK_SIZE=4k @@ -25,13 +25,15 @@ SEQ=-1 TEMPLATE=/tmp/template.fio OUTFILE= DISKS= +PRINTABLE_DISKS= RUNTIME=300 ETA=0 -MODES="read,write,randread,randwrite" +MODES="write,randwrite,read,randread" SHORT_HOSTNAME= CACHED_IO="FALSE" PREFIX="" PREFIX_FILENAME="" +IODEPTH=1 show_help() { PROG=$(basename $0) @@ -48,76 +50,98 @@ show_help() { -p : Run parallel test one test after anoter but all disks at the same time Enabled by default +-D iodepth : Run with the specified iodepth + Default is $IODEPTH -d disk1[,disk2,disk3,..] : Run the tests on the selected disks Separated each disk with a comma - Disk name shall be "sdxx", /dev/ shall NOT be used here +-z filesize : Specify the working file size, if you are passing filepaths to -d + Disabled by default -r seconds : Time in seconds per benchmark 0 means till the end of the device - Default is 300 seconds + Default is $RUNTIME seconds -b blocksize[,blocksize1, ...] : The blocksizes to test under fio format (4k, 1m, ...) Separated each blocksize with a comma - Default is 4k + Default is $BLOCK_SIZE -m mode1,[mode2,mode3, ...] : Define the fio IO profile to use like read, write, randread, randwrite - Default is "read,write,randread,randwrite" + Default is "$MODES" -x prefix : Add a prefix to the fio filename Useful to let a context associated with the file If the prefix features a / (slash), prefix will be considered as a directory +-A cmd_to_run : System command to run after each job (exec_postrun in fio) +-B cmd_to_run : System command to run before each job (exec_prerun in fio) Example: -$PROG -d sdb,sdc,sdd,sde -a -b 4k,128k,1m -r 100 -a -x dellr720-day2/ +$PROG -d /dev/sdb,/dev/sdc,/dev/sdd,/dev/sde -a -b 4k,128k,1m -r 100 -a -x dellr720-day2/ Will generate an fio file that will run - - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 4k with read,write,randread,randwrite tests + - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 4k with write,randwrite,read,randread tests ETA ~ 4 tests * 4 disks * 100 seconds - - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 128k with read,write,randread,randwrite tests + - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 128k with write,randwrite,read,randread tests ETA ~ 4 tests * 4 disks * 100 seconds - - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 1m with read,write,randread,randwrite tests + - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 1m with write,randwrite,read,randread tests ETA ~ 4 tests * 4 disks * 100 seconds - - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 4k with read,write,randread,randwrite tests + - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 4k with write,randwrite,read,randread tests ETA ~ 4 tests * 100 seconds - - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 128k with read,write,randread,randwrite tests + - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 128k with write,randwrite,read,randread tests ETA ~ 4 tests * 100 seconds - - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 1m with read,write,randread,randwrite tests + - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 1m with write,randwrite,read,randread tests ETA ~ 4 tests * 100 seconds -Generating dellr720-day2/localhost-4k,128k,1m-all-read,write,randread,randwrite-sdb,sdc,sdd,sde.fio +Generating dellr720-day2/localhost-4k,128k,1m-all-write,randwrite,read,randread-sdb,sdc,sdd,sde.fio Estimated Time = 6000 seconds : 1 hour 40 minutes EOF } -gen_template() { -cat >$TEMPLATE << EOF -[global] -ioengine=libaio -invalidate=1 -ramp_time=5 -EOF +finish_template() { +echo "iodepth=$IODEPTH" >> $TEMPLATE if [ "$RUNTIME" != "0" ]; then -cat >>$TEMPLATE << EOF -runtime=$RUNTIME -EOF + echo "runtime=$RUNTIME" >> $TEMPLATE + echo "time_based" >> $TEMPLATE fi if [ "$CACHED_IO" = "FALSE" ]; then -cat >>$TEMPLATE << EOF -direct=1 -EOF + echo "direct=1" >> $TEMPLATE fi +} + +diskname_to_printable() { +COUNT=0 +for disk in $(echo $@ | tr "," " "); do + R=$(basename $disk | sed 's|/|_|g') + COUNT=$(($COUNT + 1)) + if [ $COUNT -eq 1 ]; then + P="$R" + else + P="$P,$R" + fi +done +echo $P +} + +gen_template() { +cat >$TEMPLATE << EOF +[global] +ioengine=libaio +invalidate=1 +ramp_time=5 +EOF } gen_seq_suite() { TYPE=$1 +disk=$2 +PRINTABLE_DISK=$(diskname_to_printable $disk) cat >> $OUTFILE << EOF -[$TYPE-$disk-$BLK_SIZE-seq] +[$TYPE-$PRINTABLE_DISK-$BLK_SIZE-seq] stonewall bs=$BLK_SIZE -filename=/dev/$disk +filename=$disk rw=$TYPE -write_bw_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$disk-$TYPE-seq.results -write_iops_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$disk-$TYPE-seq.results +write_bw_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$PRINTABLE_DISK-$TYPE-seq.results +write_iops_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$PRINTABLE_DISK-$TYPE-seq.results EOF ETA=$(($ETA + $RUNTIME)) } @@ -125,7 +149,7 @@ ETA=$(($ETA + $RUNTIME)) gen_seq_fio() { for disk in $(echo $DISKS | tr "," " "); do for mode in $(echo $MODES | tr "," " "); do - gen_seq_suite "$mode" + gen_seq_suite "$mode" "$disk" done done } @@ -136,8 +160,9 @@ TYPE=$1 NEED_WALL=$2 D=0 for disk in $(echo $DISKS | tr "," " "); do + PRINTABLE_DISK=$(diskname_to_printable $disk) cat >> $OUTFILE << EOF -[$TYPE-$disk-$BLK_SIZE-para] +[$TYPE-$PRINTABLE_DISK-$BLK_SIZE-para] bs=$BLK_SIZE EOF @@ -147,10 +172,10 @@ if [ "$D" = 0 ]; then fi cat >> $OUTFILE << EOF -filename=/dev/$disk +filename=$disk rw=$TYPE -write_bw_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$disk-$TYPE-para.results -write_iops_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$disk-$TYPE-para.results +write_bw_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$PRINTABLE_DISK-$TYPE-para.results +write_iops_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$PRINTABLE_DISK-$TYPE-para.results EOF done @@ -180,7 +205,7 @@ esac } parse_cmdline() { -while getopts "hacpsd:b:r:m:x:" opt; do +while getopts "hacpsd:b:r:m:x:z:D:A:B:" opt; do case $opt in h) show_help @@ -223,10 +248,24 @@ while getopts "hacpsd:b:r:m:x:" opt; do ;; d) DISKS=$OPTARG + PRINTABLE_DISKS=$(diskname_to_printable "$DISKS") + ;; + D) + IODEPTH=$OPTARG ;; a) SEQ=2 ;; + B) + echo "exec_prerun=$OPTARG" >> $TEMPLATE + ;; + A) + echo "exec_postrun=$OPTARG" >> $TEMPLATE + ;; + z) + FSIZE=$OPTARG + echo "size=$FSIZE" >> $TEMPLATE + ;; \?) echo "Invalid option: -$OPTARG" >&2 ;; @@ -240,14 +279,14 @@ fi SHORT_HOSTNAME=$(hostname -s) case $SEQ in 2) - OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-all-$MODES-$DISKS.fio + OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-all-$MODES-$PRINTABLE_DISKS.fio ;; 1) - OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-sequential-$MODES-$DISKS.fio + OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-sequential-$MODES-$PRINTABLE_DISKS.fio ;; 0) - OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-parallel-$MODES-$DISKS.fio + OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-parallel-$MODES-$PRINTABLE_DISKS.fio ;; esac @@ -260,10 +299,45 @@ fi } +check_mode_order() { +FOUND_WRITE="NO" +CAUSE="You are reading data before writing them " + +# If no write occurs, let's show a different message +echo $MODES | grep -q "write" +if [ "$?" -ne 0 ]; then + CAUSE="You are reading data while never wrote them before" +fi + +for mode in $(echo $MODES | tr "," " "); do + echo $mode | grep -q write + if [ "$?" -eq 0 ]; then + FOUND_WRITE="YES" + fi + echo $mode | grep -q "read" + if [ "$?" -eq 0 ]; then + if [ "$FOUND_WRITE" = "NO" ]; then + echo "###############################################################" + echo "# Warning : $CAUSE#" + echo "# On some storage devices, this could lead to invalid results #" + echo "# #" + echo "# Press Ctrl-C to adjust pattern order if you have doubts #" + echo "# Or Wait 5 seconds before the file will be created #" + echo "###############################################################" + sleep 5 + # No need to try showing the message more than one time + return + fi + fi +done +} + ########## MAIN -parse_cmdline $@ gen_template +parse_cmdline "$@" +finish_template +check_mode_order echo "Generating $OUTFILE" cp -f $TEMPLATE $OUTFILE