pmrep: fix archive end time reporting
[pcp.git] / qa / getpmcdhosts
blob2c630151aa25677a0d53ba1ea9184ee83b950b50
1 #! /bin/sh
2 #
3 # Output a list of hosts from the "qa_hosts" file which meet certain
4 # criteria specified by the options (see _usage).
5 # The list of QA hosts can be overridden by setting the environment
6 # variable QA_HOSTS.
8 # Allows QA tests to get hostnames of particular configurations
9 # that they need.
11 # Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
14 . ./common.rc
16 tmp=/tmp/$$
17 tmp=`pwd`/tmp
18 rm -rf $tmp.*
19 status=1 # failure is the default!
20 trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
21 HOSTS=qa_hosts
22 SSH_USER=pcpqa
24 _usage()
26 echo >&2 'Usage: getpmcdhosts [options]
28 Options:
29 -a {pmda} pmda connected to pmcd
30 -b 32|64 kernel binary format
31 -D debug/trace (see also -V)
32 -e big|little endianess
33 -h hostfile name of host file, default is qa_hosts
34 -L do not consider localhost
35 -m {metric}<op>{value} satisfies metric value predicate
36 -n num match first num hosts
37 -P return host running a primary pmlogger
38 -p multi|single multi or single processor
39 -s system operating system (uname -s)
40 -v {item}<op>{ver} version of item
41 -V verbose diagnostics (see also -D)
43 Legal item:
44 ipc inter-process protocol (deprecated)
45 libpcp shared library (deprecated)
46 pcp PCP version installed
48 <op> is one of =, >, >=, <, <= or !=
50 Most options may be used together but not repeated.
51 The environment variable QA_STS overrides the default host
52 file and -h
54 exit 1
58 # _checkpmcdhost moomba _ 64 _ multi 2 _ _ _
60 # Parameters:
61 # host name
62 # agent name | _
63 # binfmt 32 | n32 | 64 | _
64 # primary true | false
65 # proc multi | single | _
66 # pcp 1 | 2 | _
67 # msg true | false | _
68 # system irix | linux | _
69 # endian big | small | _
72 _checkpmcdhost()
74 HOST=$1
75 AGENT=$2
76 BINFMT=$3
77 PRIMARY=$4
78 PROC=$5
79 PCP=$6
80 MSG=$7
81 SYSTEM=${8}
82 ENDIAN=${9}
83 ERROR=0
85 # check that host has a running pmcd
87 if pminfo -h $HOST -f pmcd.agent.status >/dev/null 2>&1
88 then
90 else
91 $MSG && echo "$HOST: No running pmcd" >&2
92 return 1
95 # check for running agent
97 if [ "$AGENT" != "_" ]
98 then
99 if pmprobe -h $HOST -I pmcd.agent.type 2>/dev/null | grep $AGENT >/dev/null 2>&1
100 then
102 else
103 $MSG && echo "$HOST: $AGENT not running" >&2
104 return 1
108 # check binfmt
110 if [ "$BINFMT" != "_" ]
111 then
112 # only want 32 or 64 (not ia32 or n32 etc...)
113 # if want to be specific then use "-m pmcd.simabi=ia32"
114 objfmt=`pmprobe -h $HOST -v pmcd.simabi 2>/dev/null \
115 | sed -e 's/\"//g' \
116 | $PCP_AWK_PROG 'NF > 2 { for (i = 3; i <= NF; i++) printf "%s ",$i }' \
117 | sed -e 's/.*x86-64/64/g' \
118 -e 's/.*x86_64/64/g' \
119 -e 's/IA-64/64/g' \
120 -e 's/ $//' \
121 -e 's/[a-zA-Z]//g' `
123 if [ "$objfmt" != $BINFMT ]
124 then
125 $MSG && echo "$HOST: binary format $BINFMT != $objfmt" >&2
126 return 1
130 # check operating system name
132 if [ "$SYSTEM" != "_" ]
133 then
134 osname=`ssh -q $SSH_USER@$HOST uname -s`
135 if echo $osname | grep -i $SYSTEM >/dev/null 2>&1
136 then
138 else
139 $MSG && echo "$HOST: system $SYSTEM no match with $osname " >&2
140 return 1;
144 # check that host is running primary pmlogger
146 if $PRIMARY
147 then
148 if pminfo -h $HOST -f pmcd.pmlogger.host | grep primary > /dev/null 2>&1
149 then
151 else
152 $MSG && echo "$HOST: is _not_ running primary pmlogger" >&2
153 return 1
157 # check number of processors
159 if [ "$PROC" != "_" ]
160 then
161 $VERBOSE && echo "+ pmprobe -h $HOST -v hinv.ncpu | sed ..."
162 ncpu=`pmprobe -h $HOST -v hinv.ncpu 2>/dev/null \
163 | sed -e 's/\"//g' \
164 | $PCP_AWK_PROG 'NF == 3 && $3 ~ /^[0-9][0-9]*$/ { print $3 }'`
165 $VERBOSE && echo "-> |$ncpu|"
167 if [ -z "$ncpu" -o "$ncpu" = 0 ]
168 then
169 if $MSG
170 then
171 echo "$HOST: Unknown number of processors, pmprobe -> `pmprobe -h $HOST -v hinv.ncpu 2>&1`" >&2
173 return 1
175 if [ "$ncpu" -gt 1 -a "$PROC" = "single" ]
176 then
177 $MSG && echo "$HOST: Has $ncpu processors" >&2
178 return 1
179 elif [ "$ncpu" -eq 1 -a "$PROC" = "multi" ]
180 then
181 $MSG && echo "$HOST: Has only one processor" >&2
182 return 1
186 # check endianess
188 if [ "$ENDIAN" != "_" ]
189 then
190 $VERBOSE && echo "+ echo a | ssh -q $SSH_USER@$HOST od -x"
191 check=`echo a | ssh -q $SSH_USER@$HOST "od -x" 2>&1 | sed -e 's/^0[^ ]* *//' -e 's/[ ]*$//' -e '/^$/d'`
192 $VERBOSE && echo "-> |$check|"
193 case "$check"
195 0a61)
196 if [ "$ENDIAN" = big ]
197 then
198 $MSG && echo "$HOST: little endian" >&2
199 return 1
202 610a)
203 if [ "$ENDIAN" = little ]
204 then
205 $MSG && echo "$HOST: big endian" >&2
206 return 1
210 echo "$0: INTERNAL BOTCH: expecting 0a61 or 610a, got \"$check\"" >&2
211 exit 1
213 esac
216 # check the item value pairs
218 if [ -s "$tmp.items" ]
219 then
220 cat $tmp.items \
221 | while read item op value
223 case "$item"
225 pcp)
226 if pmprobe -h $HOST -v pmcd.version >$tmp.probe 2>$tmp.err
227 then
229 else
230 rm -f $tmp.probe
234 echo "$0: INTERNAL BOTCH item=\"$item\" not expected here!"
235 exit 1
237 esac
238 if [ -s $tmp.probe ]
239 then
240 satisfies=`sed -e 's/"//g' $tmp.probe \
241 | $PCP_AWK_PROG '
242 BEGIN { op = "'"$op"'"; value="'"$value"'" }
243 NF >=3 { if ( $2 < 0 ) {
244 print "0";
245 exit;
247 # got a value
248 if (op == "=") {
249 if ($3 == value)
250 print "1";
251 else
252 print "0";
254 else if (op == "<") {
255 if ($3 < value)
256 print "1";
257 else
258 print "0";
260 else if (op == "<=") {
261 if ($3 <= value)
262 print "1";
263 else
264 print "0";
266 else if (op == ">") {
267 if ($3 > value)
268 print "1";
269 else
270 print "0";
272 else if (op == ">=") {
273 if ($3 >= value)
274 print "1";
275 else
276 print "0";
278 else if (op == "!=") {
279 if ($3 != value)
280 print "1";
281 else
282 print "0";
284 else {
285 print "2";
287 exit;
289 { print "0" }'`
290 if [ $satisfies -ne 1 ]
291 then
292 $MSG && echo "$HOST: does not satisfy predicate $metric $op $value" >&2
293 return 1
295 else
296 $MSG && echo "$HOST: pmprobe failed `cat $tmp.errs`" >&2
297 return 1
299 done
300 [ $? -eq 1 ] && return 1
303 # check the metric value pairs
305 if [ -s "$tmp.metrics" ]
306 then
307 cat $tmp.metrics \
308 | while read metric op value
310 if pmprobe -h $HOST -v $metric >$tmp.probe 2>$tmp.errs
311 then
312 satisfies=`sed -e 's/"//g' $tmp.probe \
313 | $PCP_AWK_PROG '
314 BEGIN { op = "'"$op"'"; value="'"$value"'" }
315 NF >=3 { if ( $2 < 0 ) {
316 print "0";
317 exit;
319 # got a value
320 if (op == "=") {
321 if ($3 == value)
322 print "1";
323 else
324 print "0";
326 else if (op == "<") {
327 if ($3 < value)
328 print "1";
329 else
330 print "0";
332 else if (op == "<=") {
333 if ($3 <= value)
334 print "1";
335 else
336 print "0";
338 else if (op == ">") {
339 if ($3 > value)
340 print "1";
341 else
342 print "0";
344 else if (op == ">=") {
345 if ($3 >= value)
346 print "1";
347 else
348 print "0";
350 else if (op == "!=") {
351 if ($3 != value)
352 print "1";
353 else
354 print "0";
356 else {
357 print "2";
359 exit;
361 { print "0" }'`
362 if [ $satisfies -ne 1 ]
363 then
364 $MSG && echo "$HOST: does not satisfy predicate $metric $op $value" >&2
365 return 1
367 else
368 $MSG && echo "$HOST: pmprobe failed `cat $tmp.errs`" >&2
369 return 1
371 done
372 [ $? -eq 1 ] && return 1
375 return 0
378 # Go thru table of hosts and see which meet the
379 # given criteria and return either the first one
380 # or a list of them if need be.
383 # set defaults
384 AGENT="_"
385 BINFMT="_"
386 PROC="_"
387 PCP="_"
388 SYSTEM="_"
389 ENDIAN="_"
391 PRIMARY=false
392 LOCAL=false
393 LIST=true
394 MSG=false
395 COUNT=0
396 VERBOSE=false
398 while getopts "a:b:De:h:Lm:n:Pp:s:v:V" c
400 case $c
403 AGENT=$OPTARG
406 BINFMT=$OPTARG
409 MSG=true
412 ENDIAN=$OPTARG
413 case "$ENDIAN"
415 big|little)
417 small) # synonym for little
418 ENDIAN=little
421 echo "$0: Illegal endianess $ENDIAN" >&2
422 _usage
423 #NOTREACHED
425 esac
428 HOSTS=$OPTARG
429 if [ ! -f $OPTARG ]
430 then
431 echo "$0: Cannot open hostfile $OPTARG" >&2
432 _usage
433 #NOTREACHED
437 LOCAL=true
440 metric=`echo $OPTARG | sed -e 's/[ ]*//' -e 's/[=<>!].*//'`
441 value=`echo $OPTARG | sed -e 's/[ ]*//' -e 's/.*[=<>!]//'`
442 op=`echo $OPTARG | sed -e 's/[ ]*//' -e "s/$metric//" -e "s/$value//"`
443 case "$op"
445 '='|'<'|'<='|'>'|'>='|'!=')
448 echo "$0: Illegal metric argument: $OPTARG" >&2
449 _usage
450 #NOTREACHED
452 esac
453 echo "$metric $op $value" >> $tmp.metrics
454 $MSG && echo "---tmp.metrics---" >&2
455 $MSG && cat $tmp.metrics >&2
459 COUNT=$OPTARG
460 if [ $COUNT -eq 1 ]
461 then
462 LIST=false
466 PRIMARY=true
469 PROC=$OPTARG
472 SYSTEM=$OPTARG
475 item=`echo $OPTARG | sed -e 's/[ ]*//' -e 's/[=<>!].*//'`
476 value=`echo $OPTARG | sed -e 's/[ ]*//' -e 's/.*[=<>!]//'`
477 op=`echo $OPTARG | sed -e 's/[ ]*//' -e "s/$item//" -e "s/$value//"`
478 case "$item"
480 "ipc"|"libpcp")
481 echo "$0: Deprecated item \"$item\", ignored" >&2
482 continue
484 "pcp")
485 value=`echo "$value" | sed -e 's/\./ /g' | $PCP_AWK_PROG '
486 NF==1 { print $0 ".0.0" }
487 NF==2 { print $0 ".0" }
488 NF>2 { print $0 }' | sed -e 's/ /./g'`
491 echo "$0: Illegal item $item" >&2
492 _usage
493 #NOTREACHED
494 esac
495 case "$op"
497 '='|'<'|'<='|'>'|'>='|'!=')
500 echo "$0: Illegal metric argument: $OPTARG" >&2
501 _usage
502 #NOTREACHED
504 esac
505 echo "$item $op $value" >> $tmp.items
506 $MSG && echo "---tmp.items---" >&2
507 $MSG && cat $tmp.items >&2
511 VERBOSE=true
515 _usage
516 #NOTREACHED
518 esac
519 done
520 if [ $# -ne `expr $OPTIND - 1` ]
521 then
522 _usage
523 #NOTREACHED
526 # Verify the options
529 err=0
531 if [ "$BINFMT" != "_" -a "$BINFMT" != 32 -a "$BINFMT" != 64 ]
532 then
533 echo "$0: -b option takes 32 or 64" >&2
534 err=1
537 if [ "$PROC" != "_" -a "$PROC" != "multi" -a "$PROC" != "single" ]
538 then
539 echo "$0: -p options takes multi or single" >&2
540 err=1
543 if [ $err -eq 1 ]
544 then
545 _usage
546 exit 1
549 # Use qa_hosts file if environment variable $QA_HOSTS is not set (or null)
551 if [ -z "$QA_HOSTS" ]
552 then
553 if [ ! -f $HOSTS ]
554 then
555 if [ -f GNUmakefile.install ]
556 then
557 # running QA in the tree
558 ${MAKE:-make} -f GNUmakefile.install $HOSTS >$tmp.make.out 2>&1
559 else
560 ${MAKE:-make} $HOSTS >$tmp.make.out 2>&1
562 if [ $? -ne 0 ]
563 then
565 else
566 cat $tmp.make.out >&2
567 echo "$0: Unable to make \"$HOSTS\"" >&2
568 exit 1
571 QA_HOSTS=`cat $HOSTS`
574 # Remove the localhost if requested
576 if $LOCAL
577 then
578 localhost=`hostname | sed -e 's/\..*//'`
579 QA_HOSTS=`echo $QA_HOSTS | sed \
580 -e 's/$/ /' \
581 -e "s/$localhost\.[^ ]* //g" \
582 -e "s/$localhost //g"`
585 $MSG && ( echo "Checking hosts:"; echo "$QA_HOSTS"; echo ) >&2
587 # Iterate through hosts
591 for HOST in $QA_HOSTS
593 if _checkpmcdhost $HOST $AGENT $BINFMT $PRIMARY $PROC $PCP $MSG $SYSTEM $ENDIAN
594 then
595 if $LIST
596 then
597 if $MSG
598 then
599 echo "-> $HOST" >&2
600 else
601 $PCP_ECHO_PROG $PCP_ECHO_N "$HOST ""$PCP_ECHO_C"
603 else
604 echo "$HOST"
606 i=`expr $i + 1`
609 if [ $COUNT -gt 0 -a $i -ge $COUNT ]
610 then
611 break
613 done
615 # if been using \c then do final \n
618 $LIST && echo
620 if [ $i -lt $COUNT ]
621 then
622 echo "$0: unable to get $COUNT host(s) with options: \"$@\"" >&2
623 exit
626 status=0
627 exit