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