Whamcloud - gitweb
LU-633 iokit: mds-survey script for MD echo client test
[fs/lustre-release.git] / lustre-iokit / obdfilter-survey / libecho
1 #!/bin/bash
2 # GPL HEADER START
3 #
4 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License version 2 only,
8 # as published by the Free Software Foundation.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # General Public License version 2 for more details (a copy is included
14 # in the LICENSE file that accompanied this code).
15 #
16 # You should have received a copy of the GNU General Public License
17 # version 2 along with this program; If not, see
18 # http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19 #
20 # Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 # CA 95054 USA or visit www.sun.com if you need additional information or
22 # have any questions.
23 #
24 # GPL HEADER END
25 #
26 # Copyright  2008 Sun Microsystems, Inc. All rights reserved
27 # Use is subject to license terms.
28 #
29 # This file is part of Lustre, http://www.lustre.org/
30 # Lustre is a trademark of Sun Microsystems, Inc.
31 #
32 # Author: Jitendra Pawar <jitendra@clusterfs.com>
33
34
35 # binaries
36 lsmod="/sbin/lsmod"
37 modprobe="/sbin/modprobe"
38 insmod="/sbin/insmod"
39 rmmod="/sbin/rmmod"
40
41 declare -a ost_names
42 declare -a client_names
43 declare -a host_list
44 declare -a dev_list
45 declare -a unique_hosts
46 declare count
47 declare -a vmstatpids
48 declare -a do_unload_echo
49
50
51 DSH=${DSH:-"ssh"}
52 NETTYPE=${NETTYPE:-tcp}
53
54 dsh () {
55     local node="$1"
56     local user="$2"
57     shift 2
58     local command="$@"
59
60     command="export PATH=/sbin:/usr/sbin:\$PATH; $command"
61
62     case $DSH in
63         ssh)
64             if [ -n "$user" ]; then
65                 user="$user@"
66             fi
67             $DSH $user$node "$command"
68             ;;
69         rsh)
70             if [ -n "$user" ]; then
71                 user="-l $user"
72             fi
73             $DSH $user $node "$command"
74             ;;
75     esac
76 }
77
78 # how to run commands on other nodes
79 # You need to make this work on your cluster if you have specified
80 # non-local obd instances above
81 remote_shell () {
82     host=$1
83     shift
84     cmds="$@"
85     if [ "$host" = "localhost" -o "$host" = `uname -n` ]; then
86         eval "$cmds"
87     else
88         # split $host into $host and $user
89         local user=""
90         if [[ $host == *@* ]]; then
91             user=${host%@*}
92             host=${host#*@}
93         fi
94         dsh $host "$user" "$cmds"
95     fi
96 }
97
98 # checks whether obdecho module is loded on given host.
99 # parameter: 1. hostname
100 obdecho_loaded() {
101     local host=$1
102     remote_shell $host $lsmod | grep obdecho > /dev/null 2>&1
103 }
104
105 # load obdecho.ko or obdecho.o module on host kernel.
106 load_obdecho () {
107     local index=$1
108     local host=${unique_hosts[$index]}
109     do_unload_echo[$index]=0
110     if obdecho_loaded $host; then
111         return 0
112     fi
113     if [ -z "$lustre_root" ]; then
114         remote_shell $host $modprobe obdecho
115     elif [ -f ${lustre_root}/obdecho/obdecho.ko ]; then
116         remote_shell $host $insmod ${lustre_root}/obdecho/obdecho.ko
117     else
118         remote_shell $host $insmod ${lustre_root}/obdecho/obdecho.o
119     fi
120     if obdecho_loaded $host; then
121         do_unload_echo[$index]=1
122     else
123         echo Could not install obdecho on $host
124         return 1
125     fi
126     return 0
127 }
128
129 load_obdechos () {
130     for ((i = 0; i < ${#unique_hosts[@]}; i++)); do
131                 load_obdecho $i || cleanup 1
132     done
133 }
134
135 # unload obdecho module from host kernel.
136 unload_obdecho () {
137     local index=$1
138     local host=${unique_hosts[$index]}
139     if ((${do_unload_echo[$index]})); then
140         remote_shell $host $rmmod obdecho
141         do_unload_echo[$index]=0
142     fi
143 }
144
145 # returns the device number which is displayed in "lctl device_list"
146
147 # parameter: 1. hostname
148 #            2. type of device ex: echo_client
149 #            3. name of device ex: ECHO_matrix.linsyssoft.com
150 get_devno () {
151     local host=$1
152     local type=$2
153     local name=$3
154     remote_shell $host $lctl device_list | \
155         awk "{if (\$2 == \"UP\" && \$3 == \"$type\" && \$4 == \"$name\") {\
156                   print \$1; exit}}"
157 }
158
159 get_devnos () {
160     local i=0
161     local host
162     for ((i = 0; i < $count; i++)); do
163         ost=${ost_names[$i]}
164         host=${host_list[$i]}
165         dev=$(get_devno $host obdfilter $ost)
166         dev_list[$i]=$dev
167         if [ -z "$dev" ]; then
168             echo Cant find device for $ost on $host
169             return 1
170         fi
171     done
172     return 0
173 }
174
175 # do cleanup for netdisk case.
176 cleanup_netdisk () {
177     for osc in $@; do
178         $lctl <<EOF
179         cfg_device $osc 
180         cleanup
181         detach
182 EOF
183     done
184 }
185
186 # do cleanup for network case.
187 cleanup_network () {
188     local clean_srv_OSS=$1
189     $lctl <<EOF
190     cfg_device echotmp 
191     cleanup
192     detach
193 EOF
194     remote_shell "root@$server_nid" "$lctl << EOF
195         cfg_device echo_srv
196         cleanup
197         detach
198 EOF"
199     if [ $clean_srv_OSS ]; then
200         remote_shell "root@$server_nid" "$lctl << EOF
201             cfg_device OSS
202             cleanup
203             detach
204 EOF"
205     fi
206 }
207
208 # do cleanup and exit.
209 cleanup () {
210     local exit_status=$1
211     shift
212     for ((i = 0; i < $ndevs; i++)); do
213         host=${host_names[$i]}
214             if [ -n ${do_teardown_ec[$i]} ]; then
215                 teardown_ec_devno $host ${client_names[$i]}
216             fi
217     done
218     pidcount=0
219     for host in ${unique_hosts[@]}; do
220         remote_shell $host "killall -q vmstat >/dev/null 2>&1" &
221         pid=$!
222         kill -term ${vmstatpids[$pidcount]} 2>/dev/null
223         kill -kill ${vmstatpids[$pidcount]} 2>/dev/null
224         wait $pid
225         pidcount=$((pidcount+1))
226         if ((${do_unload_obdecho[$host]})); then
227             unload_obdecho $host
228         fi
229     done
230     if [ $case == "network" ]; then
231         cleanup_network $1 
232     fi
233     if [ $case == "netdisk" ]; then
234         shift
235         cleanup_netdisk $@
236     fi
237     if [ $exit_status ]; then
238         if [ $exit_status -ne 0 ]; then
239             echo "program exited with error "
240         else
241             echo "done!"
242         fi
243     else
244         echo "Terminated"
245     fi
246     exit $exit_status
247 }
248 trap 'cleanup 0 $clean_srv_OSS $cleanup_oscs' SIGHUP SIGINT SIGTERM
249
250 # gets echoclient device number and attach it to the client UUID
251 # Results are  returned by an echo followed by an exit
252 # This must run in a subshell.
253 #
254 # parameter: 1. hostname
255 #            2. client name, ex:- ns8:ECHO_ns8
256 #            3. name of ost instances, ex:- lustre-OST0001 
257 get_ec_devno () {
258     exec 8>&1 1>&2
259     local host=$1
260     local client_name="$2"
261     local ost_name="$3"
262     local dev_type="${4:-obdfilter}"
263     local stack_type="${5:-}"
264
265     if [ -z "$client_name" ]; then
266         if [ -z "$ost_name" ]; then
267             echo "client and ost name both null"
268             exit 1
269         fi
270         client_name=${ost_name}_ecc
271     fi
272     ec=`get_devno $host echo_client $client_name`
273     if [ -n "$ec" ]; then
274         echo $ec $client_name $client_name >&8
275         exit 0
276     fi
277     if [ -z "$ost_name" ]; then
278         echo "no echo client and ost_name not set, client:" \
279             "$client_name, host: $host"
280         exit 1
281     fi
282     ost=`get_devno $host $dev_type $ost_name`
283     if [ -z "$ost" ]; then
284         echo "OST $ost_name not setup"
285         exit 1
286     fi
287     client_name=${ost_name}_ecc
288     remote_shell $host "$lctl <<EOF
289         attach echo_client $client_name ${client_name}_UUID
290         setup $ost_name $stack_type
291 EOF"
292     ec=`get_devno $host echo_client $client_name`
293     if [ -z "$ec" ]; then
294         echo "Can't setup echo-client"
295         exit 1
296     fi
297     echo $ec $client_name 1 >&8
298     exit 0
299 }
300
301 # Create echo-clients using osc_names and osc_uuid
302 # It creates echoclients for all osc listed using #lctl device_list command
303 ec_using_osc () {
304     local osc_name=$1
305     $lctl <<EOF
306         attach echo_client ${osc_name}_ecc ${osc_name}_ecc_UUID
307         cfg_device ${osc_name}_ecc
308         setup $osc_name
309 EOF
310
311 }
312
313 # create echo client using server nid.
314 ec_using_srv_nid () {
315     local server_nid=$1
316     local ocsname=$2
317     local oscuuid=$3
318     $lctl add_uuid echo_UUID $server_nid@$NETTYPE >/dev/null 2>&1
319     $lctl <<EOF
320         attach osc $ocsname $oscuuid
321         cfg_device $ocsname
322         setup echo_srv_UUID echo_UUID
323 EOF
324     $lctl <<EOF
325         attach echo_client ${ocsname}_ecc $oscuuid
326         setup $ocsname 
327 EOF
328 }
329
330 setup_osc_for_remote_ost () {
331     local ost_nid=$1
332     local obdfilter_name=$2
333     local host_name=host_$3
334     $lctl add_uuid ${host_name}_UUID $ost_nid@$NETTYPE >/dev/null 2>&1
335     $lctl <<EOF
336         attach osc ${obdfilter_name}_osc ${obdfilter_name}_osc_UUID
337         cfg_device ${obdfilter_name}_osc 
338         setup ${obdfilter_name}_UUID ${host_name}_UUID
339 EOF
340 }
341
342 # setup obdecho on server
343 setup_srv_obd () {
344     local server_nid=$1
345     local test_ostfsnm=$2
346     remote_shell "root@$server_nid" "$lctl << EOF
347         attach obdecho $test_ostfsnm ${test_ostfsnm}_UUID
348         cfg_device $test_ostfsnm
349         setup
350 EOF"
351 }
352
353 # setup OSS on server
354 setup_OSS () {
355     local server_nid=$1
356     remote_shell "root@$server_nid" "$lctl << EOF
357         attach ost OSS OSS_UUID
358         cfg_device OSS
359         setup
360 EOF"
361 }
362
363 # cleanup and detach the echo-clients that we have created during the test.
364 # parameter: 1. hostname
365 #            2. client name, ex:- ns8:ECHO_ns8
366 teardown_ec_devno () {
367     local host=$1
368     local client_name=$2
369     remote_shell $host "$lctl <<EOF
370         cfg $client_name
371         cleanup
372         detach
373 EOF"
374 }
375
376 unique () {
377     echo "$@" | xargs -n1 echo | sort -u
378 }
379
380 split_hostname () {
381     local name=$1
382     case $name in
383     *:*) host=`echo $name | sed 's/:.*$//'`
384          name=`echo $name | sed 's/[^:]*://'`
385          ;;
386     *)   host=localhost
387          ;;
388     esac
389     echo "$host $name"
390 }
391
392 check_cleanup () {
393     type_obj="$1"
394     osc_names_str=$($lctl dl | grep $type_obj)
395     count=0;
396     for name in $osc_names_str; do
397         count=$((count+1))
398     done
399     
400     if [ $count != 0 ]; then
401         echo "$type_obj could not be cleanup";
402         exit 0;
403     fi 
404
405 }
406
407 check_setup () {
408     type_obj="$1"
409     osc_names_str=$($lctl dl | grep $type_obj)
410     count=0;
411     for name in $osc_names_str; do
412         count=$((count+1))
413     done
414
415     if [ $count == 0 ]; then
416         echo "$type_obj could not be setup";
417         exit 0;
418     fi
419
420 }
421
422 # added from bugzill req.
423 get_targets () {
424     if [ -z "$ost_names" ]; then
425         targets=$($lctl device_list | awk "{if (\$2 == \"UP\" && \
426             \$3 == \"obdfilter\") {print \$4} }")
427     fi
428     if [ -z "$targets" ]; then
429         echo "Can't find any OSTs to test.  Please set targets=..."
430         exit 1
431     fi
432     count=0
433     for name in $targets; do
434         ost_names[$count]=$name
435         str=(`split_hostname $name`)
436         host_names[$count]=${str[0]}
437         count=$((count+1))
438     done
439 }
440
441 get_hosts () {
442     # split out hostnames from ost names
443     for ((i = 0; i < count; i++)); do
444         str=(`split_hostname ${targets[$i]}`)
445         host_list[$i]=${str[0]}
446         ost_names[$i]=${str[1]}
447     done
448 }