Whamcloud - gitweb
Implement async OSC create to avoid the blocking unnecessarily.
[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 host_list
26 declare -a dev_list
27 declare -a unique_hosts
28 declare count
29 declare -a vmstatpids
30 declare -a do_unload_echo
31
32
33 DSH=${DSH:-"ssh"}
34
35 dsh () {
36     local node="$1"
37     local user="$2"
38     shift 2
39     local command="$@"
40
41     local here=$(pwd)
42
43     command="cd $here; export PATH=/sbin:/usr/sbin:\$PATH; $command"
44
45     case $DSH in
46         ssh)
47             if [ -n "$user" ]; then
48                 user="$user@"
49             fi
50             $DSH $user$node "$command"
51             ;;
52         rsh)
53             if [ -n "$user" ]; then
54                 user="-l $user"
55             fi
56             $DSH $user $node "$command"
57             ;;
58     esac
59 }
60 # This function executes the command sent through parameters to host
61 # parameters
62 # 1. hostname
63 # 2. command to be executed on host
64 custom_remote_shell () {
65     host=$1
66     shift
67     cmds="$*"
68     here=`pwd`
69     # Hop on to the remote node, chdir to 'here' and run the given
70     # commands. One of the following will probably work.
71     ssh $host "cd $here; $cmds"
72     #rsh $host "cd $here; $cmds"
73     # we have to remove the leading `uname -n`: from pdsh output lines
74     #pdsh -w $host "cd $here; $cmds" | sed 's/^[^:]*://'
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 and exit.
175 cleanup () {
176     for ((i = 0; i < ndevs; i++)); do
177         host=${host_names[$i]}
178             if [ -n ${do_teardown_ec[$i]} ]; then
179                 teardown_ec_devno $host ${client_names[$i]}
180             fi
181     done
182     pidcount=0
183     for host in ${unique_hosts[@]}; do
184         remote_shell $host "killall vmstat -q" &
185         pid=$!
186         kill -term ${vmstatpids[$pidcount]} 2>/dev/null
187         kill -kill ${vmstatpids[$pidcount]} 2>/dev/null
188         wait $pid
189         pidcount=$((pidcount+1))
190         if ((${do_unload_obdecho[$host]})); then
191             unload_obdecho $host
192         fi
193     done
194     if [ $case == "network" ]; then
195         lctl <<EOF
196         device osc_testfs
197         cleanup
198         detach
199 EOF
200         remote_shell "root@$server_nid" "lctl << EOF
201             device OSS
202             cleanup
203             detach
204             device ost_testfs
205             cleanup
206             detach
207 EOF"
208     fi
209     if [ $1 -ne 0 ]; then 
210         echo "program exited with error "
211     else
212         echo "done!"
213     fi
214     exit $1
215 }
216 trap cleanup SIGHUP SIGINT SIGTERM
217
218 # gets echoclient device number and attch it to the client UUID
219
220 # parameter: 1. hostname
221 #            2. client name, ex:- ns8:ECHO_ns8
222 #            3. name of ost instances, ex:- lustre-OST0001 
223 get_ec_devno () {
224     local host=$1
225     local client_name="$2"
226     local ost_name="$3"
227     if [ -z "$client_name" ]; then
228         if [ -z "$ost_name" ]; then
229             echo "client and ost name both null" 1>&2
230             return
231         fi
232         client_name=${ost_name}_echo_client
233     fi
234     ec=`get_devno $host echo_client $client_name`
235     if [ -n "$ec" ]; then
236         echo $ec $client_name $client_name
237         return
238     fi
239     if [ -z "$ost_name" ]; then
240         echo "no echo client and ost_name not set, client: $client_name, host: $host" 1>&2
241         return
242     fi
243     ost=`get_devno $host obdfilter $ost_name`
244     if [ -z "$ost" ]; then
245         echo "OST $ost_name not setup" 1>&2
246         return
247     fi
248     remote_shell $host "$lctl <<EOF
249         attach echo_client $client_name ${client_name}_UUID
250         setup $ost_name
251 EOF"
252     ec=`get_devno $host echo_client $client_name`
253     if [ -z "$ec" ]; then
254         echo "Can't setup echo client" 1>&2
255         return
256     fi
257     echo $ec $client_name 1
258 }
259
260 # Create echo-clients using osc_names and osc_uuid
261 # It creates echoclients for all osc listed using #lctl device_list command
262 ec_using_osc () {
263     local osc_name=$1
264     local osc_uuid=$2
265     $lctl <<EOF
266         attach echo_client ECHO_$osc_name $osc_uuid
267         cfg_device ECHO_$osc_name
268         setup $osc_name
269 EOF
270
271 }
272
273 # create echo client using server nid.
274 ec_using_srv_nid () {
275     local server_nid=$1
276     local ocsname=$2
277     local oscuuid=$3
278     $lctl <<EOF
279         add_uuid testfs_UUID $server_nid@tcp
280         attach osc $ocsname $oscuuid
281         cfg_device $ocsname
282         setup ost_testfs_UUID testfs_UUID
283 EOF
284     $lctl <<EOF
285         attach echo_client ECHO_$ocsname $oscuuid
286         setup $ocsname 
287 EOF
288 }
289
290 # setup obdecho and ost on server
291 setup_srv_obd () {
292     local server_nid=$1
293     local test_ostfsnm=$2
294     echo 
295     remote_shell "root@$server_nid" "$lctl << EOF
296         attach obdecho $test_ostfsnm ${test_ostfsnm}_UUID
297         cfg_device $test_ostfsnm
298         setup
299         attach ost OSS OSS_UUID
300         cfg_device OSS
301         setup
302 EOF"  
303 }
304
305 # cleanup and detach the echo-clients that we have created during the test.
306 # parameter: 1. hostname
307 #            2. client name, ex:- ns8:ECHO_ns8
308 teardown_ec_devno () {
309     local host=$1
310     local client_name=$2
311     remote_shell $host "$lctl <<EOF
312         cfg $client_name
313         cleanup
314         detach
315 EOF"
316 }
317
318 unique () {
319     echo "$@" | xargs -n1 echo | sort -u
320 }
321
322 split_hostname () {
323     local name=$1
324     case $name in
325     *:*) host=`echo $name | sed 's/:.*$//'`
326          name=`echo $name | sed 's/[^:]*://'`
327          ;;
328     *)   host=localhost
329          ;;
330     esac
331     echo "$host $name"
332 }
333
334 check_cleanup () {
335     type_obj="$1"
336     osc_names_str=$(lctl dl | grep $type_obj)
337     count=0;
338     for name in $osc_names_str; do
339         count=$((count+1))
340     done
341     
342     if [ $count != 0 ]; then
343         echo "$type_obj could not be cleanup";
344         exit 0;
345     fi 
346
347 }
348
349 check_setup () {
350     type_obj="$1"
351     osc_names_str=$(lctl dl | grep $type_obj)
352     count=0;
353     for name in $osc_names_str; do
354         count=$((count+1))
355     done
356
357     if [ $count == 0 ]; then
358         echo "$type_obj could not be setup";
359         exit 0;
360     fi
361
362 }
363
364 # added from bugzill req.
365 get_targets () {
366     if [ -z "$ost_names" ]; then
367         OSTS=$($lctl device_list | awk "{if (\$2 == \"UP\" && \
368             \$3 == \"obdfilter\") {print \$4} }")
369     fi
370     if [ -z "$OSTS" ]; then
371         echo "Can't find any OSTs to test.  Please set ost_names=..."
372         exit 1
373     fi
374     count=0
375     for name in $OSTS; do
376         ost_names[$count]=$name
377         count=$((count+1))
378     done
379 }
380
381 get_hosts () {
382     # split out hostnames from ost names
383     for ((i = 0; i < count; i++)); do
384         str=(`split_hostname ${OSTS[$i]}`)
385         host_list[$i]=${str[0]}
386         ost_names[$i]=${str[1]}
387     done
388 }