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 [ "$last_filter" = "-1" ] && exit 0
27 for i in `seq 0 $last_filter`; do
28 local name="${echo_names[$i]}"
29 echo cleaning up $name
30 # I can't believe leading whitespace matters here.
42 lctl device_list | awk "/obdfilter $1/ {exit 1}"
46 # holy crap are these confusing
53 # build up echo_clients attached to the given filters and record
54 # 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
68 [ $? -eq 0 ] || die "error setting up echo_client (is obdecho loaded?)"
70 obj=`lctl device_list | awk "/echo_client $en/ {print "'$1}'`
71 [ -z "$obj" ] && die "couldn't find my echo_client's object number"
72 echo setup echo_client name $en as object $obj
73 echo_objs="$echo_objs $obj"
75 last_filter=$(($last_filter + 1))
76 echo_names[$last_filter]=$en
78 # build up the seperators we'll use in generating the wiki
92 if which opcontrol; then
93 echo generating oprofile results
96 echo not using oprofile
100 tmp_dir=`mktemp -d /tmp/echo_client_survey_XXXXXX` || die "mktemp failed"
102 TOT_PAGES=${TOT_PAGES:-524288}
108 local tp=`echo 'scale=2; '$threads' * '$pages' * 4096 / ('$time' * 1024 * 1024)' | bc`
113 echo "waiting idle io via vmstat"
115 ($10 == 0 && $11 == 0) {
118 print "idle for 3 seconds, must be done"
123 "deletion took longer than 10s, bailing";
129 # sorry for the wild indenting. get a wide terminal, its 2003.
133 for order_threads in `seq 0 3`; do
134 nthreads=$(echo "2^$order_threads" | bc)
136 for stride in 16 64 128; do
137 span="<|$(($nthreads +1))>"
138 row="||$span $nthreads||$span $stride||"
139 sum_row="||$nthreads||$stride||"
141 for t in `seq 1 $nthreads`; do
145 for obj_per_thread in y n; do
146 if [ $obj_per_thread == "y" ]; then
154 # create the objects that this write/rewrite run
156 for i in `seq 0 $last_filter`; do
157 oid=`lctl --device "\$"${echo_names[$i]} create $nthreads | \
158 awk '/1 is object id/ { print $6 }'`
159 [ -z "$oid" ] && die "error creating object"
163 # iterate through write and rewrite
168 $oprofile opcontrol --start
170 echo 'nice -19 vmstat 5' > $tmp_dir/vmstat-log
171 nice -19 vmstat 5 >> $tmp_dir/vmstat-log &
174 $oprofile opcontrol --reset
176 # start a test_brw thread in the background
177 # for each given filter
178 for i in `seq 0 $last_filter`; do
179 lctl --threads $nthreads v "\$"${echo_names[$i]} \
180 test_brw ${offset_prefix}1 w v \
181 $TOT_PAGES ${objid_prefix}${oids[$i]} p$stride | \
185 echo ------ waiting for $nthreads obj per thread $obj_per_thread rw: $a ----
189 $oprofile opcontrol --shutdown
190 echo ------ finished $nthreads obj per thread $obj_per_thread rw: $a ----
192 cat $tmp_dir/vmstat-log
193 rm $tmp_dir/vmstat-log
196 $oprofile opreport -c -l
198 for t in `seq 1 $nthreads`; do
199 thread_row[$t]="${thread_row[$t]} ||"
202 for i in `seq 0 $last_filter`; do
204 for t in `seq 1 $nthreads`; do
206 MS=`grep "test_brw-$t" $f | \
207 awk '($8=="MB/s):"){print $6, substr($7,2);}'`
208 thread_row[$t]="${thread_row[$t]}$MS||"
209 time=`echo $MS | cut -d s -f 1`
210 if [ `echo "$time > $maxtime" | bc` -eq "1" ]; then
214 tp=`throughput $nthreads $TOT_PAGES $maxtime`
215 row_tmp="${row_tmp}<#ffffe0>$tp $maxtime||"
216 sum_row="${sum_row}$tp||"
218 if [ `echo "$maxtime > $total_maxtime" | bc` -eq "1" ]; then
219 total_maxtime=$maxtime;
222 tp=`throughput $(($nthreads * $(($last_filter +1)))) $TOT_PAGES $total_maxtime`
223 row="${row}<#ffffe0>${tp} $total_maxtime||${row_tmp}"
226 # destroy the objects from this run and wait for
227 # their destruction to complete
228 for i in `seq 0 $last_filter`; do
229 lctl --device "\$"${echo_names[$i]} destroy ${oids[$i]} $nthreads
234 num_rows=$(($num_rows + 1))
235 rows[$num_rows]="$row"
237 num_summary_rows=$(($num_summary_rows + 1))
238 summary[$num_summary_rows]="$sum_row"
240 for t in `seq 1 $nthreads`; do
241 num_rows=$(($num_rows + 1))
242 rows[$num_rows]="${thread_row[$t]}"
249 bg='<rowbgcolor="#eoeoff"'
250 echo "||$bg|2>threads writing $TOT_PAGES pages||<|2>pages per prep/commit${sep1}oid per thread${sep1}shared oid||"
251 echo "$sep2$bg>write${sep2}re-write${sep2}write${sep2}re-write||"
252 for r in `seq 1 $num_rows`; do
258 echo "||$bg|2>threads||<|2>pages ${sep4}oid/thread${sep4}shared oid||"
259 echo "$sep3$bg>write${sep3}re-write${sep3}write${sep3}re-write||"
260 for r in `seq 1 $num_summary_rows`; do