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