Whamcloud - gitweb
LU-16861 obdfilter: Exclude quotes when getting NIDs
[fs/lustre-release.git] / lustre-iokit / lst-survey / lst.sh
1 #!/bin/bash
2
3 print_help() {
4         cat <<EOF
5 Usage:
6 ${0##*/} -f "nid1[ nid2...]" -t "nidA[ nidB...]" -m read|write|rw|ping [options]
7 or
8 ${0##*/} -H -f "host1[ host2...]" -t "hostA[ hostB...]" -m read|write|rw|ping [options]
9
10 Options:
11         -b batch_name
12            Creates a batch test called <batch_name> rather than using the
13            default.
14         -c concurrency
15            The number of requests that are active at one time.
16         -C simple|full
17            A data validation check (checksum of data). The default is that no
18            check is done.
19         -d <source_count:sink_count>
20            Determines the ratio of client nodes to server nodes for the
21            specified test. This allows you to specify a wide range of
22            topologies, including one-to-one and all-to-all. Distribution divides
23            the source group into subsets, which are paired with equivalent
24            subsets from the target group so only nodes in matching subsets
25            communicate.
26         -D delay
27            The interval of the statistics (in seconds). Default is 15.
28         -e
29            Lists the number of failed RPCs on test nodes in the current session.
30         -h
31            Display this help.
32         -H
33            Run in "host mode". Host mode indicates that the arguments to '-t'
34            and '-f' flags are hostnames rather than LNet nids. This script will
35            attempt to ssh to each node to ensure the lnet-selftest module is
36            loaded, and to determine the appropriate LNet NIDs to give to LST.
37         -f "nid1[ nid2...]"
38            Space-separated list of LNet NIDs to place in the "clients" group.
39            When '-H' flag is specified, the '-f' argument is a space-separated
40            list of hostnames.
41            PDSH-style expressions are supported for NID arguments, but not for
42            host mode ('-H').
43         -g servers|clients
44            Report stats only from the specified group. Either 'clients' or
45            'servers'.
46         -l loops
47            The number of test loops. Default is -1 (infinite).
48         -L
49            Load lnet-selftest module on local and remote hosts. The module will
50            be unloaded at the end of the test execution. Requires running in
51            host mode ('-H').
52         -m read|write|rw|ping
53            Type of test to run. 'rw' specifies to run simultaneous read and
54            write test.
55         -M
56            Report bandwidth stats in MiB/s (default is MB/s).
57         -n count
58            The number of stat RPCs to issue. Default is 1.
59         -o <offset>
60            Add off=<offset> to brw tests.
61         -s iosize
62            I/O size in bytes, kilobytes, or Megabytes (i.e., -s 1024, -s 4K,
63            -s 1M). The default is 1 Megabyte.
64         -S <rate|bw|"rate  bw">
65            By default, only bandwidth stats are displayed for read and write
66            and only RPC rate stats are shown for ping tests. The '-S' flag can
67            be used to override the stat output.
68            Examples:
69              Show only RPC rate stats:
70                 # lst.sh -S rate ...
71              Show only bandwidth stats:
72                 # lst.sh -S bw ...
73              Show both bandwidth and RPC rate stats:
74                 # lst.sh -S "rate bw" ...
75                 or
76                 # lst.sh -S "bw rate" ...
77         -t "nid1[ nid2...]"
78            Space-separated list of LNet NIDs to place in the "servers" group.
79            When '-H' flag is specified, the '-t' argument is a space-separated
80            list of hostnames.
81            PDSH-style expressions are supported for NID arguments, but not for
82            host mode ('-H').
83 EOF
84         exit
85 }
86
87 stop_lst() {
88         local rc=0
89
90         if ${LST_BATCH_STARTED}; then
91                 $LCTL mark "lst stop ${BATCH_NAME}"
92
93                 [[ -n ${ALL_HOSTS} ]] &&
94                         $PDSH "${ALL_HOSTS}" "$LCTL mark 'lst stop ${BATCH_NAME}'"
95
96                 lst stop "${BATCH_NAME}" || rc=$?
97                 LST_BATCH_STARTED=false
98         fi
99
100         if ${LST_SESSION_CREATED}; then
101                 $LCTL mark "Stop LST $MODE"
102                 echo "Stop LST $MODE - $(date)"
103
104                 [[ -n ${ALL_HOSTS} ]] &&
105                         $PDSH "${ALL_HOSTS}" "$LCTL mark 'Stop LST $MODE'"
106
107                 lst end_session || rc=$((rc + $?))
108                 LST_SESSION_CREATED=false
109         fi
110
111         return $rc
112 }
113
114 exit_handler() {
115         local rc=${1:-0}
116
117         trap "" EXIT
118
119         stop_lst || rc=$((rc + $?))
120
121         if ${LOAD_MODULES}; then
122                 echo "Attempting to 'modprobe -r lnet-selftest' on all hosts (30 second timeout)..."
123                 $PDSH "${ALL_HOSTS}" -u 30 \
124                         "if lsmod | grep -q lnet_selftest; then
125                                  modprobe -r lnet-selftest
126                          else
127                                  :
128                          fi" | dshbak -c
129                 rc=$((rc + PIPESTATUS[0]))
130                 if lsmod | grep -q lnet_selftest; then
131                         timeout 30 modprobe -r lnet-selftest
132                         rc=$((rc + $?))
133                 fi
134         fi
135
136         return $rc
137 }
138
139 LST_SESSION_CREATED=false # Whether 'lst new_session' was executed
140 LST_BATCH_STARTED=false # Whether 'lst run <batch>' was executed
141
142 PDSH="pdsh -S -Rssh -w"
143 BATCH_NAME=""
144 CONCURRENCY=16
145 CHECK=
146 DISTRIBUTION="1:1"
147 CLIENTS=""
148 LOOPS=""
149 MODE=""
150 IOSIZE="1m"
151 SERVERS=""
152 COUNT="1"
153 DELAY="15"
154 STAT_GROUP=""
155 SHOW_ERRORS=false
156 STAT_OPTS=""
157 STAT_OPT_RATE=false
158 STAT_OPT_BW=false
159 BW_UNITS="--mbs"
160 HOST_MODE=false
161 LOAD_MODULES=false
162 BRW_OFFSET=""
163 while getopts "b:C:c:d:D:ef:g:hHl:Lm:Mn:o:s:S:t:" flag ; do
164         case $flag in
165                 b) BATCH_NAME="$OPTARG";;
166                 c) CONCURRENCY="$OPTARG";;
167                 C) CHECK="$OPTARG";;
168                 d) DISTRIBUTION="$OPTARG";;
169                 D) DELAY="$OPTARG";;
170                 e) SHOW_ERRORS=true;;
171                 h) print_help;;
172                 H) HOST_MODE=true;;
173                 f) CLIENTS="$OPTARG";;
174                 g) STAT_GROUP="$OPTARG";;
175                 l) LOOPS="$OPTARG";;
176                 L) LOAD_MODULES=true;;
177                 m) MODE="$OPTARG";;
178                 M) BW_UNITS="";;
179                 n) COUNT="$OPTARG";;
180                 o) BRW_OFFSET="$OPTARG";;
181                 s) IOSIZE="$OPTARG";;
182                 S) STAT_OPTS="$OPTARG";;
183                 t) SERVERS="$OPTARG";;
184                 *) echo "Unrecognized option '-$flag'"
185                    exit 1;;
186         esac
187 done
188
189 # find where 'lctl' binary is installed on this system
190 if [[ -x "$LCTL" ]]; then       # full pathname specified
191         : # echo "LCTL=$LCTL"
192 elif [[ -n "$LUSTRE" && -x "$LUSTRE/utils/lctl" ]]; then
193         LCTL=$LUSTRE/utils/lctl
194 else                            # hope that it is in the PATH
195         LCTL=${LCTL:-lctl}
196 fi
197 #echo "using LCTL='$LCTL' lustre_root='$lustre_root' LUSTRE='$LUSTRE'"
198 [[ -n "$(which $LCTL)" ]] || { echo "error: lctl not found"; exit 99; }
199
200 if [[ -z $CLIENTS ]]; then
201         echo "Must specify \"clients\" group (-f)"
202         exit 1
203 elif [[ -z $SERVERS ]]; then
204         echo "Must specify \"servers\" group (-t)"
205         exit 1
206 elif [[ -z $MODE ]]; then
207         echo "Must specify a mode (-m <read|write|rw|ping>)"
208         exit 1
209 elif ! [[ $MODE =~ read|write|rw|ping ]]; then
210         echo "Invalid mode - \"$MODE\". (-m <read|write|rw|ping>)"
211         exit 1
212 elif [[ -z $(which lst 2>/dev/null) ]]; then
213         echo "Cannot find lst executable in PATH."
214         exit 1
215 elif ${LOAD_MODULES} && ! ${HOST_MODE}; then
216         echo "Module loading ('-L') is only available in host mode ('-H')"
217         exit 1
218 fi
219
220 for stat_opt in ${STAT_OPTS}; do
221         if [[ $stat_opt == rate ]]; then
222                 STAT_OPT_RATE=true
223         elif [[ $stat_opt == bw ]]; then
224                 STAT_OPT_BW=true
225         else
226                 echo "Invalid stat option \"-S $stat_opt\""
227                 print_help
228         fi
229 done
230
231 if [[ -z $STAT_GROUP ]]; then
232         STAT_GROUP="clients servers"
233 elif ! [[ $STAT_GROUP =~ clients|servers ]]; then
234         echo "Stat group must be either \"clients\" or \"servers\". Found \"$STAT_GROUP\""
235         exit 1
236 fi
237
238 if [[ -n ${LOOPS} && ${LOOPS} -eq 0 ]]; then
239         echo "Loops must be -1 or > 0. Found \"${LOOPS}\""
240         exit 1
241 fi
242
243 if ! ${LOAD_MODULES} && ! lsmod | grep -q lnet_selftest; then
244         echo "lnet-selftest module is not loaded on local host."
245         echo "Please ensure lnet-selftest module is loaded on the local host and all test nodes."
246         exit 1
247 fi
248
249 ALL_HOSTS=""
250 if ${HOST_MODE}; then
251         which pdsh &>/dev/null || { echo "Need pdsh for host mode"; exit; }
252         which ssh &>/dev/null || { echo "Need ssh for host mode"; exit; }
253
254         ALL_HOSTS="${SERVERS} ${CLIENTS}"
255         ALL_HOSTS=${ALL_HOSTS## }
256         ALL_HOSTS=${ALL_HOSTS%% }
257         ALL_HOSTS="${ALL_HOSTS// /,}"
258
259         if ${LOAD_MODULES}; then
260                 echo "Loading lnet-selftest on test nodes"
261                 $PDSH "${ALL_HOSTS}" \
262                         "if ! lsmod | grep -q lnet_selftest; then
263                                  modprobe lnet-selftest 2>&1
264                          else
265                                  true
266                          fi" | dshbak -c
267                 rc=${PIPESTATUS[0]}
268                 if [[ $rc -ne 0 ]]; then
269                         echo "Failed to load lnet-selftest module on test nodes"
270                         exit "$rc"
271                 fi
272
273                 if ! lsmod | grep -q lnet_selftest; then
274                         modprobe lnet-selftest
275                         rc=$?
276                         if [[ $rc -ne 0 ]]; then
277                                 echo "Failed to load lnet-selftest on local host"
278                                 exit $rc
279                         fi
280                 fi
281         fi
282
283         idx=0
284         opts=( -o NumberOfPasswordPrompts=0 -o ConnectTimeout=5 )
285         for host in ${SERVERS//,/ }; do
286                 s_nids[idx]=$(ssh "${opts[@]}" "$host" '$LCTL list_nids | head -n 1')
287                 if [[ -z ${s_nids[idx]} ]]; then
288                         echo "Failed to determine primary NID of $host"
289                         exit
290                 fi
291                 idx=$((idx + 1))
292         done
293
294         idx=0
295         for host in ${CLIENTS//,/ }; do
296                 c_nids[idx]=$(ssh "${opts[@]}" "${host}" '$LCTL list_nids | head -n 1')
297                 if [[ -z ${c_nids[idx]} ]]; then
298                         echo "Failed to determine primary NID of $host"
299                         exit
300                 fi
301                 idx=$((idx + 1))
302         done
303
304         SERVER_NIDS=( "${s_nids[@]}" )
305         CLIENT_NIDS=( "${c_nids[@]}" )
306 else
307         IFS=" " read -r -a SERVER_NIDS <<< "${SERVERS}"
308         IFS=" " read -r -a CLIENT_NIDS <<< "${CLIENTS}"
309 fi
310
311 if ! grep -q '\[' <<<"${SERVER_NIDS[@]}" && which lnetctl &>/dev/null; then
312         echo "Discover server NIDs"
313         lnetctl discover "${SERVER_NIDS[@]}" 1>/dev/null
314         rc=$?
315         if [[ $rc -ne 0 ]]; then
316                 echo "Failed to discover all server NIDs"
317                 exit $rc
318         fi
319 fi
320
321 if ! grep -q '\[' <<<"${CLIENT_NIDS[@]}" && which lnetctl &>/dev/null; then
322         echo "Discover client NIDs"
323         lnetctl discover "${CLIENT_NIDS[@]}" 1>/dev/null
324         rc=$?
325         if [[ $rc -ne 0 ]]; then
326                 echo "Failed to discover all client NIDs"
327                 exit $rc
328         fi
329 fi
330
331 [[ -n $ALL_HOSTS ]] &&
332         $PDSH "$ALL_HOSTS" "$LCTL mark 'Start LST $MODE'"
333
334 $LCTL mark "Start LST $MODE"
335 echo "Start LST $MODE - $(date)"
336
337 trap 'exit_handler' EXIT
338
339 export LST_SESSION=$$
340 echo "LST_SESSION=$LST_SESSION"
341 lst new_session lnet_session || { echo "new_session failed $?"; exit; }
342 LST_SESSION_CREATED=true
343
344 echo "Adding clients: ${CLIENT_NIDS[*]}"
345 lst add_group clients "${CLIENT_NIDS[@]}" || exit
346 echo "Adding servers: ${SERVER_NIDS[*]}"
347 lst add_group servers "${SERVER_NIDS[@]}" || exit
348
349 if [[ -z ${BATCH_NAME} ]]; then
350         BATCH_NAME="brw_${MODE}"
351 fi
352 lst add_batch "${BATCH_NAME}" || exit
353
354 test_opts+=( --batch "${BATCH_NAME}" --concurrency "${CONCURRENCY}" )
355 test_opts+=( --from clients --to servers --distribute "${DISTRIBUTION}" )
356 [[ -n ${LOOPS} ]] &&
357         test_opts+=( --loop "${LOOPS}" )
358
359 if [[ $MODE == ping ]]; then
360         test_opts+=( ping )
361 elif [[ $MODE == rw ]]; then
362         read_opts=( "${test_opts[@]}" brw read size="$IOSIZE" )
363         write_opts=( "${test_opts[@]}" brw write size="$IOSIZE" )
364         if [[ -n $CHECK ]];  then
365                 read_opts+=( check="$CHECK" )
366                 write_opts+=( check="$CHECK" )
367         fi
368         if [[ -n $BRW_OFFSET ]]; then
369                 read_opts+=( off="$BRW_OFFSET" )
370                 write_opts+=( off="$BRW_OFFSET" )
371         fi
372 else
373         test_opts+=( brw "${MODE}" )
374         [[ -n $BRW_OFFSET ]] &&
375                 test_opts+=( off="$BRW_OFFSET" )
376         [[ -n $CHECK ]] &&
377                 test_opts+=( check="$CHECK" )
378         test_opts+=( size="$IOSIZE" )
379 fi
380
381 stat_opts=( --count "${COUNT}" --delay "${DELAY}" )
382 if [[ -n $STAT_OPTS ]]; then
383         if ${STAT_OPT_RATE}; then
384                 stat_opts+=( --rate )
385         fi
386         if ${STAT_OPT_BW}; then
387                 stat_opts+=( --bw )
388         fi
389 elif [[ $MODE == ping ]]; then
390         stat_opts+=( --rate )
391 else
392         stat_opts+=( --bw "${BW_UNITS}" )
393 fi
394
395 for g in ${STAT_GROUP}; do
396         stat_opts+=( "${g}" )
397 done
398
399 if [[ $MODE == rw ]]; then
400         echo "Test: ${read_opts[*]}"
401         echo "Test: ${write_opts[*]}"
402         echo "Stat: ${stat_opts[*]}"
403         lst add_test "${read_opts[@]}" || exit
404         lst add_test "${write_opts[@]}" || exit
405 else
406         echo "Test: ${test_opts[*]}"
407         echo "Stat: ${stat_opts[*]}"
408         lst add_test "${test_opts[@]}" || exit
409 fi
410
411 lst run "${BATCH_NAME}" || exit
412
413 LST_BATCH_STARTED=true
414
415 lst stat "${stat_opts[@]}"
416
417 if ${SHOW_ERRORS}; then
418         lst show_error --session servers clients
419 fi
420
421 exit