Whamcloud - gitweb
src needs to be in the options list if it is going to be available for use.
[fs/lustre-release.git] / lustre-iokit / ost-survey / ost-survey.sh
1 #!/bin/bash
2
3 # This script is to be run on a client machine and will test all the 
4 # OSTs to determine which is the fastest and slowest
5 # The current test method 
6 # Create a directory for each OST
7 # Use 'lfs setstripe' to set the Lustre striping such that IO goes to 
8 # only one OST
9 # Use 'dd' to write a file of a specified size
10 # Use 'dd' to read a file of a specified size
11 # Compute the average 
12 # Find the slowest OST
13
14
15 declare -a rTime=()          # Time to read some data
16 declare -a wTime=()          # Time to write some data
17 declare -a rMBs=()           # Read speed
18 declare -a wMBs=()           # Write speed
19
20 # GLOBALS
21 OSTS=0                       # Number of OSTS we will loop over
22 OFILE=testdummy              #  File name to use
23 BSIZE=1024                   # size of blocks to be written 
24 MNT=''                       # Location of Lustre file system
25 DIR="tmpdir"                 # Name used to create a series of tmp directories
26 VERBOSE=1                    # Set this to get verbose output ( TODO - use getopts? )
27
28 # Usage
29 if [ $# -ne 2 ]; then
30    echo "Usage: $0 <size of test file in KB> <Lustre directory>"
31    exit 1
32 fi
33
34
35 test_preq () {
36     # check for a mounted Lustre filesystem
37     MNT=`grep lustre /proc/mounts | awk '{print $2}'`
38     if [ -z $MNT ]; then
39         echo "Mounted Lustre filesystem not found"
40         exit 1
41     fi
42     
43     # Check for Lustre utilites in PATH
44     # Check for dd
45 }
46
47 ost_count () {
48   # We assume that all devices with 'osc' in the string are OSTs
49   OSTS=`lctl dl | grep -c osc`
50 }
51
52 make_dummy () {
53 # Create a file full of zeros
54     echo "make dummy"
55     local DIR=$1
56     local SIZE=$2
57     mkdir -p $MNT/$DIR
58     dd if=/dev/zero of=$MNT/$DIR/$OFILE count=$SIZE bs=$BSIZE 2> /dev/null
59     
60 }
61
62 output_all_data () {
63     echo "$OSTS OST devices found"
64     local CNT=0
65     while [ $CNT -lt $OSTS ]; do
66         echo "Ost index $CNT Read speed ${rMBs[$CNT]} Write speed ${wMBs[$CNT]}"
67         echo "Ost index $CNT Read time ${rTime[$CNT]} Write time ${wTime[$CNT]}"
68         CNT=$(( $CNT + 1 ))
69     done
70 }
71 run_test () {
72     local DIR=$1
73     local SIZE=$2
74     local INX=$3
75     local ACTION=$4
76     
77     if [ ! -f $MNT/$DIR/$OFILE ] && [ $ACTION == 'read' ]; then
78         make_dummy $DIR $SIZE
79     fi
80
81     t0=`date +%s.%N`
82     if [ $ACTION == 'read' ]; then 
83         OUTS=`dd if=$MNT/$DIR/$OFILE of=/dev/null count=$SIZE bs=$BSIZE 2> /dev/null`
84     elif [ $ACTION == 'write' ]; then 
85         OUTS=`dd of=$MNT/$DIR/$OFILE if=/dev/zero count=$SIZE bs=$BSIZE 2> /dev/null`
86     else
87         echo "Action not read||write"
88         exit 1
89     fi
90     t1=`date +%s.%N`
91
92     tdelta=`awk "BEGIN {printf \"%7.2f\", $t1 - $t0; exit}"`
93     sdelta=$(( $SIZE * $BSIZE ))
94     delta=`awk "BEGIN {printf \"%7.2f\", ($SIZE * $BSIZE / ( $t1 - $t0 )) / ( 1024 * 1024 ) ; exit}"`
95     
96     if [ $ACTION == 'read' ]; then 
97         rTime[$INX]=$tdelta
98         rMBs[$INX]=$delta
99     else 
100         wTime[$INX]=$tdelta
101         wMBs[$INX]=$delta
102     fi
103 }
104
105 display_average () {
106     local CNT=0
107     local OP=$1
108     while [ $CNT -lt $OSTS ]; do
109         if [ $OP == "read" ]; then
110             echo "${rMBs[$CNT]} $OP"
111         elif [ $OP == "write" ]; then
112             echo "${wMBs[$CNT]} $OP"
113         else
114             echo "Bad param"
115             exit 1
116         fi
117         CNT=$(( $CNT + 1 ))
118     done |  awk '{ c++; t+= $1; op = $2 }; END { printf "Average %s Speed: %7.2f\n", op, t/c }'
119
120 }
121
122 find_min () {
123     local CNT=0
124     local OP=$1
125     while [ $CNT -lt $OSTS ]; do
126         if [ $OP == "read" ]; then
127             echo "${rMBs[$CNT]} $CNT $OP"
128         elif [ $OP == "write" ]; then 
129             echo "${wMBs[$CNT]} $CNT $OP"
130         else
131             echo "Bad param"
132             exit 1
133         fi
134             CNT=$(( $CNT + 1 ))
135     done | awk '{
136         if (NR == 1) { min = $1; indx = $2; op = $3 } 
137         else if (min > $1){  min = $1; indx = $ 2; op = $3}
138     } 
139     END {printf "%s - Worst OST indx %d %7.2f MB/s\n", op, indx, min}'
140 }
141
142 find_max () {
143     local CNT=0
144     local OP=$1
145     while [ $CNT -lt $OSTS ]; do
146         if [ $OP == "read" ]; then
147             echo "${rMBs[$CNT]} $CNT $OP"
148         elif [ $OP == "write" ]; then 
149             echo "${wMBs[$CNT]} $CNT $OP"
150         else
151             echo "Bad param"
152             exit 1
153         fi
154             CNT=$(( $CNT + 1 ))
155     done | awk '{
156         if (NR == 1) { max = $1; indx = $2; op = $3 } 
157         else if (max < $1){  max = $1; indx = $ 2; op = $3 }
158     } 
159     END {printf "%s - Best OST indx %d %7.2f MB/s\n", op, indx, max}'
160 }
161 # Temp cleanup
162
163 CNT=0
164 MYSIZE=1024
165
166 test_preq
167 ost_count
168
169 while [ $CNT -lt $OSTS ]; do
170     rm -rf $MNT/${DIR}${CNT}
171     mkdir -p $MNT/${DIR}${CNT}
172     lfs setstripe $MNT/${DIR}${CNT} 0 $CNT 1
173     run_test ${DIR}${CNT} $MYSIZE $CNT write
174     run_test ${DIR}${CNT} $MYSIZE $CNT read
175     CNT=$(( $CNT + 1 ))
176 done
177
178 MAX_MB=0
179 MIN_T=999999999
180
181 display_average read
182 display_average write
183 find_min read
184 find_min write
185 find_max read
186 find_max write
187
188 CNT=0
189
190
191 if [ $VERBOSE ]; then
192     output_all_data
193 fi
194