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