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