Whamcloud - gitweb
LU-911 osd: OI is implemented internally within OSD
[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" \
195         "$lctl <<-EOF
196                 cfg_device echo_srv
197                 cleanup
198                 detach
199         EOF"
200     if [ $clean_srv_OSS ]; then
201         remote_shell "root@$server_nid" \
202         "$lctl <<-EOF
203                 cfg_device OSS
204                 cleanup
205                 detach
206         EOF"
207     fi
208 }
209
210 # do cleanup and exit.
211 cleanup () {
212     local exit_status=$1
213     local host
214     case=${case:-"disk"}
215     shift
216     for ((i = 0; i < $ndevs; i++)); do
217         host=${host_names[$i]}
218         if [ -n ${do_teardown_ec[$i]} ]; then
219             teardown_ec_devno $host ${client_names[$i]}
220         fi
221     done
222     pidcount=0
223     for ((i = 0; i < ${#unique_hosts[@]}; i++)); do
224         host=${unique_hosts[$i]}
225         remote_shell $host "killall -q vmstat >/dev/null 2>&1" &
226         pid=$!
227         kill -term ${vmstatpids[$pidcount]} 2>/dev/null
228         kill -kill ${vmstatpids[$pidcount]} 2>/dev/null
229         wait $pid
230         pidcount=$((pidcount+1))
231         if ((${do_unload_echo[$i]})); then
232             unload_obdecho $i
233         fi
234     done
235     if [ $case == "network" ]; then
236         cleanup_network $1
237     fi
238     if [ $case == "netdisk" ]; then
239         shift
240         cleanup_netdisk $@
241     fi
242     if [ $exit_status ]; then
243         if [ $exit_status -ne 0 ]; then
244             echo "program exited with error "
245         else
246             echo "done!"
247         fi
248     else
249         echo "Terminated"
250     fi
251     exit $exit_status
252 }
253 trap 'cleanup 0 $clean_srv_OSS $cleanup_oscs' SIGHUP SIGINT SIGTERM
254
255 # gets echoclient device number and attach it to the client UUID
256 # Results are  returned by an echo followed by an exit
257 # This must run in a subshell.
258 #
259 # parameter: 1. hostname
260 #            2. client name, ex:- ns8:ECHO_ns8
261 #            3. name of ost instances, ex:- lustre-OST0001
262 get_ec_devno () {
263     exec 8>&1 1>&2
264     local host=$1
265     local client_name="$2"
266     local ost_name="$3"
267     local dev_type="${4:-obdfilter}"
268     local stack_type="${5:-}"
269
270     if [ -z "$client_name" ]; then
271         if [ -z "$ost_name" ]; then
272             echo "client and ost name both null"
273             exit 1
274     fi
275         client_name=${ost_name}_ecc
276     fi
277     ec=`get_devno $host echo_client $client_name`
278     if [ -n "$ec" ]; then
279         echo $ec $client_name $client_name >&8
280         exit 0
281     fi
282     if [ -z "$ost_name" ]; then
283         echo "no echo client and ost_name not set, client:" \
284             "$client_name, host: $host"
285         exit 1
286     fi
287     ost=`get_devno $host $dev_type $ost_name`
288     if [ -z "$ost" ]; then
289         echo "OST $ost_name not setup"
290         exit 1
291     fi
292     client_name=${ost_name}_ecc
293     remote_shell $host \
294         "$lctl <<-EOF
295                 attach echo_client $client_name ${client_name}_UUID
296                 setup $ost_name $stack_type
297         EOF"
298     ec=`get_devno $host echo_client $client_name`
299     if [ -z "$ec" ]; then
300         echo "Can't setup echo-client"
301         exit 1
302     fi
303     echo $ec $client_name 1 >&8
304     exit 0
305 }
306
307 # Create echo-clients using osc_names and osc_uuid
308 # It creates echoclients for all osc listed using #lctl device_list command
309 ec_using_osc () {
310     local osc_name=$1
311         $lctl <<-EOF
312                 attach echo_client ${osc_name}_ecc ${osc_name}_ecc_UUID
313                 cfg_device ${osc_name}_ecc
314                 setup $osc_name
315         EOF
316
317 }
318
319 # create echo client using server nid.
320 ec_using_srv_nid () {
321     local server_nid=$1
322     local ocsname=$2
323     local oscuuid=$3
324     $lctl add_uuid echo_UUID $server_nid@$NETTYPE >/dev/null 2>&1
325         $lctl <<-EOF
326                 attach osc $ocsname $oscuuid
327                 cfg_device $ocsname
328                 setup echo_srv_UUID echo_UUID
329         EOF
330         $lctl <<-EOF
331                 attach echo_client ${ocsname}_ecc $oscuuid
332                 setup $ocsname
333         EOF
334 }
335
336 setup_osc_for_remote_ost () {
337     local ost_nid=$1
338     local obdfilter_name=$2
339     local host_name=host_$3
340     $lctl add_uuid ${host_name}_UUID $ost_nid@$NETTYPE >/dev/null 2>&1
341         $lctl <<-EOF
342                 attach osc ${obdfilter_name}_osc ${obdfilter_name}_osc_UUID
343                 cfg_device ${obdfilter_name}_osc
344                 setup ${obdfilter_name}_UUID ${host_name}_UUID
345         EOF
346 }
347
348 # setup obdecho on server
349 setup_srv_obd () {
350     local server_nid=$1
351     local test_ostfsnm=$2
352     remote_shell "root@$server_nid" \
353         "$lctl <<-EOF
354                 attach obdecho $test_ostfsnm ${test_ostfsnm}_UUID
355                 cfg_device $test_ostfsnm
356                 setup
357         EOF"
358 }
359
360 # setup OSS on server
361 setup_OSS () {
362     local server_nid=$1
363     remote_shell "root@$server_nid" \
364         "$lctl <<-EOF
365                 attach ost OSS OSS_UUID
366                 cfg_device OSS
367                 setup
368         EOF"
369 }
370
371 # cleanup and detach the echo-clients that we have created during the test.
372 # parameter: 1. hostname
373 #            2. client name, ex:- ns8:ECHO_ns8
374 teardown_ec_devno () {
375     local host=$1
376     local client_name=$2
377     remote_shell $host \
378         "$lctl <<-EOF
379                 cfg $client_name
380                 cleanup
381                 detach
382         EOF"
383 }
384
385 unique () {
386     echo "$@" | xargs -n1 echo | sort -u
387 }
388
389 split_hostname () {
390     local name=$1
391     case $name in
392     *:*) host=`echo $name | sed 's/:.*$//'`
393          name=`echo $name | sed 's/[^:]*://'`
394          ;;
395     *)   host=localhost
396          ;;
397     esac
398     echo "$host $name"
399 }
400
401 check_cleanup () {
402     type_obj="$1"
403     osc_names_str=$($lctl dl | grep $type_obj)
404     count=0;
405     for name in $osc_names_str; do
406         count=$((count+1))
407     done
408
409     if [ $count != 0 ]; then
410         echo "$type_obj could not be cleanup";
411         exit 0;
412     fi
413
414 }
415
416 check_setup () {
417     type_obj="$1"
418     osc_names_str=$($lctl dl | grep $type_obj)
419     count=0;
420     for name in $osc_names_str; do
421         count=$((count+1))
422     done
423
424     if [ $count == 0 ]; then
425         echo "$type_obj could not be setup";
426         exit 0;
427     fi
428
429 }
430
431 # added from bugzill req.
432 get_targets () {
433     if [ -z "$ost_names" ]; then
434         targets=$($lctl device_list | awk "{if (\$2 == \"UP\" && \
435             \$3 == \"obdfilter\") {print \$4} }")
436     fi
437     if [ -z "$targets" ]; then
438         echo "Can't find any OSTs to test.  Please set targets=..."
439         exit 1
440     fi
441     count=0
442     for name in $targets; do
443         ost_names[$count]=$name
444         str=(`split_hostname $name`)
445         host_names[$count]=${str[0]}
446         count=$((count+1))
447     done
448 }
449
450 get_hosts () {
451     # split out hostnames from ost names
452     for ((i = 0; i < count; i++)); do
453         str=(`split_hostname ${targets[$i]}`)
454         host_list[$i]=${str[0]}
455         ost_names[$i]=${str[1]}
456     done
457 }