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