Whamcloud - gitweb
23aa2b851937e5c2d3be58500066b2c9a53d3b31
[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     if [ -z "$client_name" ]; then
263         if [ -z "$ost_name" ]; then
264             echo "client and ost name both null"
265             exit 1
266         fi
267         client_name=${ost_name}_ecc
268     fi
269     ec=`get_devno $host echo_client $client_name`
270     if [ -n "$ec" ]; then
271         echo $ec $client_name $client_name >&8
272         exit 0
273     fi
274     if [ -z "$ost_name" ]; then
275         echo "no echo client and ost_name not set, client:" \
276             "$client_name, host: $host"
277         exit 1
278     fi
279     ost=`get_devno $host obdfilter $ost_name`
280     if [ -z "$ost" ]; then
281         echo "OST $ost_name not setup"
282         exit 1
283     fi
284     client_name=${ost_name}_ecc
285     remote_shell $host "$lctl <<EOF
286         attach echo_client $client_name ${client_name}_UUID
287         setup $ost_name
288 EOF"
289     ec=`get_devno $host echo_client $client_name`
290     if [ -z "$ec" ]; then
291         echo "Can't setup echo-client"
292         exit 1
293     fi
294     echo $ec $client_name 1 >&8
295     exit 0
296 }
297
298 # Create echo-clients using osc_names and osc_uuid
299 # It creates echoclients for all osc listed using #lctl device_list command
300 ec_using_osc () {
301     local osc_name=$1
302     $lctl <<EOF
303         attach echo_client ${osc_name}_ecc ${osc_name}_ecc_UUID
304         cfg_device ${osc_name}_ecc
305         setup $osc_name
306 EOF
307
308 }
309
310 # create echo client using server nid.
311 ec_using_srv_nid () {
312     local server_nid=$1
313     local ocsname=$2
314     local oscuuid=$3
315     $lctl add_uuid echo_UUID $server_nid@$NETTYPE >/dev/null 2>&1
316     $lctl <<EOF
317         attach osc $ocsname $oscuuid
318         cfg_device $ocsname
319         setup echo_srv_UUID echo_UUID
320 EOF
321     $lctl <<EOF
322         attach echo_client ${ocsname}_ecc $oscuuid
323         setup $ocsname 
324 EOF
325 }
326
327 setup_osc_for_remote_ost () {
328     local ost_nid=$1
329     local obdfilter_name=$2
330     local host_name=host_$3
331     $lctl add_uuid ${host_name}_UUID $ost_nid@$NETTYPE >/dev/null 2>&1
332     $lctl <<EOF
333         attach osc ${obdfilter_name}_osc ${obdfilter_name}_osc_UUID
334         cfg_device ${obdfilter_name}_osc 
335         setup ${obdfilter_name}_UUID ${host_name}_UUID
336 EOF
337 }
338
339 # setup obdecho on server
340 setup_srv_obd () {
341     local server_nid=$1
342     local test_ostfsnm=$2
343     remote_shell "root@$server_nid" "$lctl << EOF
344         attach obdecho $test_ostfsnm ${test_ostfsnm}_UUID
345         cfg_device $test_ostfsnm
346         setup
347 EOF"
348 }
349
350 # setup OSS on server
351 setup_OSS () {
352     local server_nid=$1
353     remote_shell "root@$server_nid" "$lctl << EOF
354         attach ost OSS OSS_UUID
355         cfg_device OSS
356         setup
357 EOF"
358 }
359
360 # cleanup and detach the echo-clients that we have created during the test.
361 # parameter: 1. hostname
362 #            2. client name, ex:- ns8:ECHO_ns8
363 teardown_ec_devno () {
364     local host=$1
365     local client_name=$2
366     remote_shell $host "$lctl <<EOF
367         cfg $client_name
368         cleanup
369         detach
370 EOF"
371 }
372
373 unique () {
374     echo "$@" | xargs -n1 echo | sort -u
375 }
376
377 split_hostname () {
378     local name=$1
379     case $name in
380     *:*) host=`echo $name | sed 's/:.*$//'`
381          name=`echo $name | sed 's/[^:]*://'`
382          ;;
383     *)   host=localhost
384          ;;
385     esac
386     echo "$host $name"
387 }
388
389 check_cleanup () {
390     type_obj="$1"
391     osc_names_str=$($lctl dl | grep $type_obj)
392     count=0;
393     for name in $osc_names_str; do
394         count=$((count+1))
395     done
396     
397     if [ $count != 0 ]; then
398         echo "$type_obj could not be cleanup";
399         exit 0;
400     fi 
401
402 }
403
404 check_setup () {
405     type_obj="$1"
406     osc_names_str=$($lctl dl | grep $type_obj)
407     count=0;
408     for name in $osc_names_str; do
409         count=$((count+1))
410     done
411
412     if [ $count == 0 ]; then
413         echo "$type_obj could not be setup";
414         exit 0;
415     fi
416
417 }
418
419 # added from bugzill req.
420 get_targets () {
421     if [ -z "$ost_names" ]; then
422         targets=$($lctl device_list | awk "{if (\$2 == \"UP\" && \
423             \$3 == \"obdfilter\") {print \$4} }")
424     fi
425     if [ -z "$targets" ]; then
426         echo "Can't find any OSTs to test.  Please set targets=..."
427         exit 1
428     fi
429     count=0
430     for name in $targets; do
431         ost_names[$count]=$name
432         str=(`split_hostname $name`)
433         host_names[$count]=${str[0]}
434         count=$((count+1))
435     done
436 }
437
438 get_hosts () {
439     # split out hostnames from ost names
440     for ((i = 0; i < count; i++)); do
441         str=(`split_hostname ${targets[$i]}`)
442         host_list[$i]=${str[0]}
443         ost_names[$i]=${str[1]}
444     done
445 }