Whamcloud - gitweb
LU-3068 build: fix 'incorrect expression' errors
[fs/lustre-release.git] / lustre / scripts / bdev-io-survey.sh
index 23ffc7a..084ca5a 100755 (executable)
@@ -12,6 +12,7 @@
 #      discard first vmstat line
 #
 
+HOSTNAME=`hostname`
 # a temp dir that is setup and torn down for each script run
 tmpdir=""
 # so we can kill background processes as the test cleans up
@@ -22,6 +23,9 @@ declare -a cleanup_mounts
 cur_y="0"
 # a global which funcs use to get at the blocks[] array
 last_block=-1
+# prefix to run oprofile or readprofile
+oprofile=""
+readprofile=""
 
 # defaults for some options:
 min_threads=1
@@ -226,7 +230,7 @@ sgp_dd_start() {
        local bdev=${blocks[$i]};
 
        case "$wor" in
-               w) ifof="if=/dev/zero of=$bdev" ;;
+               [wo]) ifof="if=/dev/zero of=$bdev" ;;
                r) ifof="if=$bdev of=/dev/null" ;;
                *) die "asked to do io with $wor?"
        esac
@@ -268,6 +272,10 @@ ext2_iozone_prepare() {
                echo "iozone binary not found in PATH"
                return 1
        fi
+       if ! iozone -i 0 -w -+o -s 1k -r 1k -f /dev/null > /dev/null; then
+               echo "iozone doesn't support -+o"
+               return 1
+       fi
        if ! which mke2fs; then
                echo "mke2fs binary not found in PATH"
                return 1
@@ -298,7 +306,7 @@ ext2_iozone_setup() {
 
        case "$wor" in
                w) rm -f $f ;;
-               r) ;;
+               [or]) ;;
                *) die "asked to do io with $wor?"
        esac
 }
@@ -311,13 +319,13 @@ ext2_iozone_start() {
        local f="$tmpdir/mount_$id/iozone"
 
        case "$wor" in
-               w) args="-i 0 -w" ;;
-               r) args="-i 1 -w" ;;
+               [wo]) args="-i 0 -w" ;;
+               r) args="-i 1" ;;
                *) die "asked to do io with $wor?"
        esac
 
        echo iozone "$args -r ${iosize}k -s $(($io_len / $threads))k \
-                       -t $threads -x -I -f $f"
+                       -t $threads -+o -x -I -f $f"
 }
 ext2_iozone_result() {
        local output=$1
@@ -326,7 +334,7 @@ ext2_iozone_result() {
        local field
 
        case "$wor" in
-               w) string="writers" 
+               [wo]) string="writers" 
                   field=7 
                        ;;
                r) string="readers" 
@@ -339,15 +347,8 @@ ext2_iozone_result() {
                        {print $'$(($field + 2))'}' $output` / 1024
 }
 ext2_iozone_cleanup() {
-       local id=$1
-       local wor=$2
-       local f="$tmpdir/mount_$id/iozone"
-
-       case "$wor" in
-               w) ;;
-               r) rm -f $f ;;
-               *) die "asked to do io with $wor?"
-       esac
+       # the final read w/o -w removed the file
+       local nothing=0
 }
 ext2_iozone_finish() {
        local index=$1
@@ -421,14 +422,14 @@ echo_filter_config() {
        fi
 
        if [ $index = 0 ]; then
-               if ! lmc -m $config --add net  \
-                       --node localhost --nid localhost --nettype tcp; then
-                       echo "error adding localhost net node"
+               if ! lmc -m $config --add net \
+                       --node $HOSTNAME --nid $HOSTNAME --nettype tcp; then
+                       echo "error adding $HOSTNAME net node"
                        return 1
                fi
        fi
 
-       if ! lmc -m $config --add ost --ost ost_$index --node localhost \
+       if ! lmc -m $config --add ost --ost ost_$index --node $HOSTNAME \
                        --fstype ext3 --dev $bdev --journal_size 400; then
                echo "error adding $bdev to config with lmc"
                return 1
@@ -450,6 +451,10 @@ echo_filter_prepare() {
                        return 1;
                fi
                running_config="$config"
+
+               echo 0 > /proc/sys/lnet/debug
+               echo 0 > /proc/sys/lnet/subsystem_debug
+
                if ! grep -q '^obdecho\>' /proc/modules; then
                        local m
                        if ! modprobe obdecho; then
@@ -492,7 +497,7 @@ echo_filter_setup() {
 
        case "$wor" in
                w) ;;
-               r) return ;;
+               [or]) return ;;
                *) die "asked to do io with $wor?"
        esac
 
@@ -507,19 +512,20 @@ echo_filter_start() {
        local iosize=$2
        local wor=$3
        local id=$4
+       local rw
 
        local name="echo_$id"
-       local len_pages=$(($io_len / $(($page_size / 1024)) ))
+       local len_pages=$(($io_len / $(($page_size / 1024)) / $threads ))
        local size_pages=$(($iosize / $(($page_size / 1024)) ))
 
        case "$wor" in
-               w) ;;
-               r) ;;
+               [wo]) rw="w" ;;
+               r) rw="r" ;;
                *) die "asked to do io with $wor?"
        esac
 
        echo lctl --threads $threads v "\$"$name \
-               test_brw 1 $wor v $len_pages t${running_oids[$i]} p$size_pages
+               test_brw 1 $rw v $len_pages t${running_oids[$id]} p$size_pages
 }
 echo_filter_result() {
        local output=$1
@@ -538,13 +544,13 @@ echo_filter_cleanup() {
        local name="echo_$id"
 
        case "$wor" in
-               w) return ;;
+               [wo]) return ;;
                r) ;;
                *) die "asked to do io with $wor?"
        esac
 
-       lctl --device "\$"$name destroy ${running_oids[$i]} $threads
-       unset running_oids[$i]
+       lctl --device "\$"$name destroy ${running_oids[$id]} $threads
+       unset running_oids[$id]
 }
 echo_filter_finish() {
        local index=$1
@@ -581,6 +587,8 @@ test_one() {
 
        echo $test with $threads threads
 
+       $oprofile opcontrol --start
+
        # start up vmstat and record its pid
         nice -19 vmstat 1 > $vmstat_log 2>&1 &
        [ $? = 0 ] || die "vmstat failed"
@@ -597,10 +605,14 @@ test_one() {
                iostat_pids[$i]=$pid
        done
 
+       $oprofile opcontrol --reset
+       $readprofile -r
+
        # start all the tests.  each returns a pid to wait on
        pids=""
        for i in `seq 0 $last_block`; do
                local cmd=`${test}_start $threads $iosize $wor $i`
+               echo "$cmd" >> $tmpdir/commands
                $cmd > $tmpdir/$i 2>&1 &
                local pid=$!
                pids="$pids $pid"
@@ -626,6 +638,16 @@ test_one() {
                pid_has_stopped $pid
        done
 
+       $readprofile | sort -rn > $tmpdir/readprofile
+
+       $oprofile opcontrol --shutdown
+       $oprofile opreport > $tmpdir/oprofile
+       echo >> $tmpdir/oprofile
+       $oprofile opreport -c -l | head -20 >> $tmpdir/oprofile
+
+       save_output $tmpdir/oprofile $opref.oprofile
+       save_output $tmpdir/readprofile $opref.readprofile
+
        # collect the results of vmstat and iostat
        cpu=$(mean_stddev $(awk \
              '(NR > 3 && NF == 16 && $16 != "id" )     \
@@ -714,7 +736,7 @@ test_iterator() {
                        table_set $test 0 $cur_y $thr
                        table_set $test 1 $cur_y $iosize
 
-                       for wor in w r; do
+                       for wor in w r; do
                                table_set $test 2 $cur_y $wor
                                test_one $test 3 $thr $iosize $wor
                        done
@@ -759,8 +781,10 @@ if [ -z "$io_len" ]; then
 fi
 
 if [ ! -z "$output_dir" ]; then
-       [ ! -e "$output_dir" ] && "output dir $output_dir doesn't exist"
-       [ ! -d "$output_dir" ] && "output dir $output_dir isn't a directory"
+       if [ ! -e "$output_dir" ]; then
+                mkdir -p "$output_dir" || die  "error creating $output_dir"
+       fi
+       [ ! -d "$output_dir" ] && die "$output_dir isn't a directory"
 fi
 
 block=`echo $block | sed -e 's/,/ /g'`
@@ -774,6 +798,26 @@ for t in $run_tests; do
        fi
 done
 
+if which opcontrol; then
+        echo generating oprofile results
+        oprofile=""
+else
+        echo not using oprofile
+        oprofile=": "
+fi
+
+if which readprofile; then
+       map="/boot/System.map-`uname -r`"
+       if [ -f /proc/profile -a -f "$map" ]; then
+               echo generating profiles with 'readprofile'
+               readprofile="readprofile -m $map"
+       fi
+fi
+if [ -z "$readprofile" ]; then
+       echo not using readprofile
+       readprofile=": "
+fi
+
 [ $min_threads -gt $max_threads ] && \
        die "min threads $min_threads must be <= min_threads $min_threads"
 
@@ -814,11 +858,14 @@ for t in $run_tests; do
        test_results="$test_results $t"
 done
 
+save_output $tmpdir/commands commands
+
 [ ! -z "$test_results" ] && (
        echo
        echo "T = number of concurrent threads per device"
        echo "L = base io operation length, in KB"
        echo "m = IO method: read, write, or over-write"
+       echo "A = aggregate throughput from all devices"
        echo "C = percentage CPU used, both user and system"
        echo "MB/s = per-device throughput"
        echo "rR = read requests issued to the device per second"