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