Whamcloud - gitweb
1ae1dc0cb1d5c36b9fc761acd9a07089d4dcaa38
[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
53 dsh () {
54     local node="$1"
55     local user="$2"
56     shift 2
57     local command="$@"
58
59     local here=$(pwd)
60
61     command="cd $here; export PATH=/sbin:/usr/sbin:\$PATH; $command"
62
63     case $DSH in
64         ssh)
65             if [ -n "$user" ]; then
66                 user="$user@"
67             fi
68             $DSH $user$node "$command"
69             ;;
70         rsh)
71             if [ -n "$user" ]; then
72                 user="-l $user"
73             fi
74             $DSH $user $node "$command"
75             ;;
76     esac
77 }
78
79 # how to run commands on other nodes
80 # You need to make this work on your cluster if you have specified
81 # non-local obd instances above
82 remote_shell () {
83     host=$1
84     shift
85     cmds="$@"
86     if [ "$host" = "localhost" -o "$host" = `uname -n` ]; then
87         eval "$cmds"
88     else
89         # split $host into $host and $user
90         local user=""
91         if [[ $host == *@* ]]; then
92             user=${host%@*}
93             host=${host#*@}
94         fi
95         dsh $host "$user" "$cmds"
96     fi
97 }
98
99 # checks whether obdecho module is loded on given host.
100 # parameter: 1. hostname
101 obdecho_loaded() {
102     local host=$1
103     remote_shell $host $lsmod | grep obdecho > /dev/null 2>&1
104 }
105
106 # load obdecho.ko or obdecho.o module on host kernel.
107 load_obdecho () {
108     local index=$1
109     local host=${unique_hosts[$index]}
110     do_unload_echo[$index]=0
111     if obdecho_loaded $host; then
112         return 0
113     fi
114     if [ -z "$lustre_root" ]; then
115         remote_shell $host $modprobe obdecho
116     elif [ -f ${lustre_root}/obdecho/obdecho.ko ]; then
117         remote_shell $host $insmod ${lustre_root}/obdecho/obdecho.ko
118     else
119         remote_shell $host $insmod ${lustre_root}/obdecho/obdecho.o
120     fi
121     if obdecho_loaded $host; then
122         do_unload_echo[$index]=1
123     else
124         echo Could not install obdecho on $host
125         return 1
126     fi
127     return 0
128 }
129
130 load_obdechos () {
131     for ((i = 0; i < ${#unique_hosts[@]}; i++)); do
132                 load_obdecho $i || cleanup 1
133     done
134 }
135
136 # unload obdecho module from host kernel.
137 unload_obdecho () {
138     local index=$1
139     local host=${unique_hosts[$index]}
140     if ((${do_unload_echo[$index]})); then
141         remote_shell $host $rmmod obdecho
142         do_unload_echo[$index]=0
143     fi
144 }
145
146 # returns the device number which is displayed in "lctl device_list"
147
148 # parameter: 1. hostname
149 #            2. type of device ex: echo_client
150 #            3. name of device ex: ECHO_matrix.linsyssoft.com
151 get_devno () {
152     local host=$1
153     local type=$2
154     local name=$3
155     remote_shell $host $lctl device_list | \
156         awk "{if (\$2 == \"UP\" && \$3 == \"$type\" && \$4 == \"$name\") {\
157                   print \$1; exit}}"
158 }
159
160 get_devnos () {
161     local i=0
162     local host
163     for ((i = 0; i < $count; i++)); do
164         ost=${ost_names[$i]}
165         host=${host_list[$i]}
166         dev=$(get_devno $host obdfilter $ost)
167         dev_list[$i]=$dev
168         if [ -z "$dev" ]; then
169             echo Cant find device for $ost on $host
170             return 1
171         fi
172     done
173     return 0
174 }
175
176 # do cleanup for netdisk case.
177 cleanup_netdisk () {
178     for osc in $@; do
179         lctl <<EOF
180         cfg_device $osc 
181         cleanup
182         detach
183 EOF
184     done
185 }
186
187 # do cleanup for network case.
188 cleanup_network () {
189     local clean_srv_OSS=$1
190     lctl <<EOF
191     cfg_device echotmp 
192     cleanup
193     detach
194 EOF
195     remote_shell "root@$server_nid" "lctl << EOF
196         cfg_device echo_srv
197         cleanup
198         detach
199 EOF"
200     if [ $clean_srv_OSS ]; then
201         remote_shell "root@$server_nid" "lctl << EOF
202             cfg_device OSS
203             cleanup
204             detach
205 EOF"
206     fi
207 }
208
209 # do cleanup and exit.
210 cleanup () {
211     local exit_status=$1
212     shift
213     for ((i = 0; i < $ndevs; i++)); do
214         host=${host_names[$i]}
215             if [ -n ${do_teardown_ec[$i]} ]; then
216                 teardown_ec_devno $host ${client_names[$i]}
217             fi
218     done
219     pidcount=0
220     for host in ${unique_hosts[@]}; do
221         remote_shell $host "killall -q vmstat >/dev/null 2>&1" &
222         pid=$!
223         kill -term ${vmstatpids[$pidcount]} 2>/dev/null
224         kill -kill ${vmstatpids[$pidcount]} 2>/dev/null
225         wait $pid
226         pidcount=$((pidcount+1))
227         if ((${do_unload_obdecho[$host]})); then
228             unload_obdecho $host
229         fi
230     done
231     if [ $case == "network" ]; then
232         cleanup_network $1 
233     fi
234     if [ $case == "netdisk" ]; then
235         shift
236         cleanup_netdisk $@
237     fi
238     if [ $exit_status ]; then
239         if [ $exit_status -ne 0 ]; then
240             echo "program exited with error "
241         else
242             echo "done!"
243         fi
244     else
245         echo "Terminated"
246     fi
247     exit $exit_status
248 }
249 trap cleanup SIGHUP SIGINT SIGTERM
250
251 # gets echoclient device number and attch it to the client UUID
252
253 # parameter: 1. hostname
254 #            2. client name, ex:- ns8:ECHO_ns8
255 #            3. name of ost instances, ex:- lustre-OST0001 
256 get_ec_devno () {
257     local host=$1
258     local client_name="$2"
259     local ost_name="$3"
260     if [ -z "$client_name" ]; then
261         if [ -z "$ost_name" ]; then
262             echo "client and ost name both null" 1>&2
263             return
264         fi
265         client_name=${ost_name}_ecc
266     fi
267     ec=`get_devno $host echo_client $client_name`
268     if [ -n "$ec" ]; then
269         echo $ec $client_name $client_name
270         return
271     fi
272     if [ -z "$ost_name" ]; then
273         echo "no echo client and ost_name not set, client: $client_name, host: $host" 1>&2
274         return
275     fi
276     ost=`get_devno $host obdfilter $ost_name`
277     if [ -z "$ost" ]; then
278         echo "OST $ost_name not setup" 1>&2
279         return
280     fi
281     client_name=${ost_name}_ecc
282     remote_shell $host "$lctl <<EOF
283         attach echo_client $client_name ${client_name}_UUID
284         setup $ost_name
285 EOF"
286     ec=`get_devno $host echo_client $client_name`
287     if [ -z "$ec" ]; then
288         echo "Can't setup echo-client" 1>&2
289         return
290     fi
291     echo $ec $client_name 1
292 }
293
294 # Create echo-clients using osc_names and osc_uuid
295 # It creates echoclients for all osc listed using #lctl device_list command
296 ec_using_osc () {
297     local osc_name=$1
298     $lctl <<EOF
299         attach echo_client ${osc_name}_ecc ${osc_name}_ecc_UUID
300         cfg_device ${osc_name}_ecc
301         setup $osc_name
302 EOF
303
304 }
305
306 # create echo client using server nid.
307 ec_using_srv_nid () {
308     local server_nid=$1
309     local ocsname=$2
310     local oscuuid=$3
311     $lctl add_uuid echo_UUID $server_nid@tcp >/dev/null 2>&1
312     $lctl <<EOF
313         attach osc $ocsname $oscuuid
314         cfg_device $ocsname
315         setup echo_srv_UUID echo_UUID
316 EOF
317     $lctl <<EOF
318         attach echo_client ${ocsname}_ecc $oscuuid
319         setup $ocsname 
320 EOF
321 }
322
323 setup_osc_for_remote_ost () {
324     local ost_nid=$1
325     local obdfilter_name=$2
326     local host_name=host_$3
327     $lctl add_uuid ${host_name}_UUID $ost_nid@tcp >/dev/null 2>&1
328     $lctl <<EOF
329         attach osc ${obdfilter_name}_osc ${obdfilter_name}_osc_UUID
330         cfg_device ${obdfilter_name}_osc 
331         setup ${obdfilter_name}_UUID ${host_name}_UUID
332 EOF
333 }
334
335 # setup obdecho on server
336 setup_srv_obd () {
337     local server_nid=$1
338     local test_ostfsnm=$2
339     remote_shell "root@$server_nid" "$lctl << EOF
340         attach obdecho $test_ostfsnm ${test_ostfsnm}_UUID
341         cfg_device $test_ostfsnm
342         setup
343 EOF"
344 }
345
346 # setup OSS on server
347 setup_OSS () {
348     local server_nid=$1
349     remote_shell "root@$server_nid" "$lctl << EOF
350         attach ost OSS OSS_UUID
351         cfg_device OSS
352         setup
353 EOF"
354 }
355
356 # cleanup and detach the echo-clients that we have created during the test.
357 # parameter: 1. hostname
358 #            2. client name, ex:- ns8:ECHO_ns8
359 teardown_ec_devno () {
360     local host=$1
361     local client_name=$2
362     remote_shell $host "$lctl <<EOF
363         cfg $client_name
364         cleanup
365         detach
366 EOF"
367 }
368
369 unique () {
370     echo "$@" | xargs -n1 echo | sort -u
371 }
372
373 split_hostname () {
374     local name=$1
375     case $name in
376     *:*) host=`echo $name | sed 's/:.*$//'`
377          name=`echo $name | sed 's/[^:]*://'`
378          ;;
379     *)   host=localhost
380          ;;
381     esac
382     echo "$host $name"
383 }
384
385 check_cleanup () {
386     type_obj="$1"
387     osc_names_str=$(lctl dl | grep $type_obj)
388     count=0;
389     for name in $osc_names_str; do
390         count=$((count+1))
391     done
392     
393     if [ $count != 0 ]; then
394         echo "$type_obj could not be cleanup";
395         exit 0;
396     fi 
397
398 }
399
400 check_setup () {
401     type_obj="$1"
402     osc_names_str=$(lctl dl | grep $type_obj)
403     count=0;
404     for name in $osc_names_str; do
405         count=$((count+1))
406     done
407
408     if [ $count == 0 ]; then
409         echo "$type_obj could not be setup";
410         exit 0;
411     fi
412
413 }
414
415 # added from bugzill req.
416 get_targets () {
417     if [ -z "$ost_names" ]; then
418         targets=$($lctl device_list | awk "{if (\$2 == \"UP\" && \
419             \$3 == \"obdfilter\") {print \$4} }")
420     fi
421     if [ -z "$targets" ]; then
422         echo "Can't find any OSTs to test.  Please set targets=..."
423         exit 1
424     fi
425     count=0
426     for name in $targets; do
427         ost_names[$count]=$name
428         str=(`split_hostname $name`)
429         host_names[$count]=${str[0]}
430         count=$((count+1))
431     done
432 }
433
434 get_hosts () {
435     # split out hostnames from ost names
436     for ((i = 0; i < count; i++)); do
437         str=(`split_hostname ${targets[$i]}`)
438         host_list[$i]=${str[0]}
439         ost_names[$i]=${str[1]}
440     done
441 }