3 # this runs prep/commit against filters and generates a
4 # table of their write timings. it needs the names
5 # of the filters it will run against and needs the
6 # obdecho module loaded. it spews a lot of junk
7 # as it goes, only the last bit is really interesting;
8 # tee it to a log file.
10 # ex: FILTER_NAMES="ost1 ost2" sh ./filter_survey.sh
12 SRCDIR="`dirname $0`/"
13 export PATH=$SRCDIR/../utils:/sbin:/usr/sbin::$PATH
25 [ ! -z "$tmp_dir" ] && [ -d $tmp_dir ] && rm -rf $tmp_dir
26 [ -z "$echo_objs" ] && exit 0
27 for obj in $echo_objs; do
29 # I can't believe leading whitespace matters here.
41 lctl device_list | awk "/obdfilter $1/ {exit 1}"
45 # holy crap are these confusing
52 # build up echo_clients attached to the given filters and record
53 # their names and obj numbers for later use and teardown
56 [ -z "$FILTER_NAMES" ] && die "please specify filter names to run against"
57 for fn in $FILTER_NAMES; do
58 if not_a_filter $fn; then
59 die "'$fn' isn't the name of an obdfilter device"
64 attach echo_client $en ${en}_uuid
69 [ $? -eq 0 ] || die "error setting up echo_client (is obdecho loaded?)"
71 obj=`lctl device_list | awk "/echo_client $en/ {print "'$1}'`
72 [ -z "$obj" ] && die "couldn't find my echo_client's object number"
73 echo setup echo_client name $en as object $obj
74 echo_objs="$echo_objs $obj"
76 last_filter=$(($last_filter + 1))
77 echo_names[$last_filter]=$en
79 # build up the seperators we'll use in generating the wiki
93 if which opcontrol; then
94 echo generating oprofile results
97 echo not using oprofile
101 tmp_dir=`mktemp -d /tmp/echo_client_survey_XXXXXX` || die "mktemp failed"
103 TOT_PAGES=${TOT_PAGES:-524288}
109 local tp=`echo 'scale=2; '$threads' * '$pages' * 4096 / ('$time' * 1024 * 1024)' | bc`
114 echo "waiting idle io via vmstat"
116 ($10 == 0 && $11 == 0) {
119 print "idle for 3 seconds, must be done"
124 "deletion took longer than 10s, bailing";
130 # sorry for the wild indenting. get a wide terminal, its 2003.
134 for order_threads in `seq 0 3`; do
135 nthreads=$(echo "2^$order_threads" | bc)
137 for stride in 16 64 128; do
138 span="<|$(($nthreads +1))>"
139 row="||$span $nthreads||$span $stride||"
140 sum_row="||$nthreads||$stride||"
142 for t in `seq 1 $nthreads`; do
146 for obj_per_thread in y n; do
147 if [ $obj_per_thread == "y" ]; then
155 # create the objects that this write/rewrite run
157 for i in `seq 0 $last_filter`; do
158 oid=`lctl --device "\$"${echo_names[$i]} create $nthreads | \
159 awk '/1 is object id/ { print $6 }'`
160 [ -z "$oid" ] && die "error creating object"
164 # iterate through write and rewrite
169 $oprofile opcontrol --start
171 echo 'nice -19 vmstat 5' > $tmp_dir/vmstat-log
172 nice -19 vmstat 5 >> $tmp_dir/vmstat-log &
175 $oprofile opcontrol --reset
177 # start a test_brw thread in the background
178 # for each given filter
179 for i in `seq 0 $last_filter`; do
180 lctl --threads $nthreads v "\$"${echo_names[$i]} \
181 test_brw ${offset_prefix}1 w v \
182 $TOT_PAGES ${objid_prefix}${oids[$i]} p$stride | \
186 echo ------ waiting for $nthreads obj per thread $obj_per_thread rw: $a ----
190 $oprofile opcontrol --shutdown
191 echo ------ finished $nthreads obj per thread $obj_per_thread rw: $a ----
193 cat $tmp_dir/vmstat-log
194 rm $tmp_dir/vmstat-log
197 $oprofile opreport -c -l
199 for t in `seq 1 $nthreads`; do
200 thread_row[$t]="${thread_row[$t]} ||"
203 for i in `seq 0 $last_filter`; do
205 for t in `seq 1 $nthreads`; do
207 MS=`grep "test_brw-$t" $f | \
208 awk '($8=="MB/s):"){print $6, substr($7,2);}'`
209 thread_row[$t]="${thread_row[$t]}$MS||"
210 time=`echo $MS | cut -d s -f 1`
211 if [ `echo "$time > $maxtime" | bc` -eq "1" ]; then
215 tp=`throughput $nthreads $TOT_PAGES $maxtime`
216 row_tmp="${row_tmp}<#ffffe0>$tp $maxtime||"
217 sum_row="${sum_row}$tp||"
219 if [ `echo "$maxtime > $total_maxtime" | bc` -eq "1" ]; then
220 total_maxtime=$maxtime;
223 tp=`throughput $(($nthreads * $(($last_filter +1)))) $TOT_PAGES $total_maxtime`
224 row="${row}<#ffffe0>${tp} $total_maxtime||${row_tmp}"
227 # destroy the objects from this run and wait for
228 # their destruction to complete
229 for i in `seq 0 $last_filter`; do
230 lctl --device "\$"${echo_names[$i]} destroy ${oids[$i]} $nthreads
235 num_rows=$(($num_rows + 1))
236 rows[$num_rows]="$row"
238 num_summary_rows=$(($num_summary_rows + 1))
239 summary[$num_summary_rows]="$sum_row"
241 for t in `seq 1 $nthreads`; do
242 num_rows=$(($num_rows + 1))
243 rows[$num_rows]="${thread_row[$t]}"
250 bg='<rowbgcolor="#eoeoff"'
251 echo "||$bg|2>threads writing $TOT_PAGES pages||<|2>pages per prep/commit${sep1}oid per thread${sep1}shared oid||"
252 echo "$sep2$bg>write${sep2}re-write${sep2}write${sep2}re-write||"
253 for r in `seq 1 $num_rows`; do
259 echo "||$bg|2>threads||<|2>pages ${sep4}oid/thread${sep4}shared oid||"
260 echo "$sep3$bg>write${sep3}re-write${sep3}write${sep3}re-write||"
261 for r in `seq 1 $num_summary_rows`; do