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