2 # common preliminary check procedures for QA scripts
4 # Copyright (c) 2014-2016 Red Hat.
5 # Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
8 if [ ! -f localconfig ]
13 # need to know what version we're running
16 # common routine for preventing a test from running on some platforms
17 # use: _notrun "Reason for not running this test is ..."
21 echo $@ >$here/$seq.notrun
22 echo "$seq: [not run] `cat $here/$seq.notrun`"
26 # common routine for failing a test in a standard way
27 # use: _fail "Reason for failing this test is ..."
36 # calculate the size of a given fail, echo it on standard output
42 if [ $PCP_PLATFORM = darwin ]
46 # 234881026 5304024 -rwxr-xr-x 1 kenj kenj 0 2016 "May 4 14:00:42 2011" "Apr 27 20:14:16 2011" "Apr 27 20:14:16 2011" "Apr 27 20:14:16 2011" 4096 8 0 441
47 stat $filename 2>&1 | $PCP_AWK_PROG '{ print $8 }'
51 # Size: 2016 Blocks: 8 IO Block: 4096 regular file
52 # Device: 816h/2070d Inode: 758237 Links: 1
53 # Access: (0755/-rwxr-xr-x) Uid: ( 1000/ kenj) Gid: ( 1000/ kenj)
54 # Access: 2011-05-09 06:52:58.000000000 +1000
55 # Modify: 2011-02-27 14:42:30.000000000 +1100
56 # Change: 2011-02-28 19:21:27.000000000 +1100
57 stat $filename 2>&1 | $PCP_AWK_PROG '$1 == "Size:" { print $2 }'
61 # determine whether sufficient free space exists to run a test;
62 # passed in parameter is the size needed, in megabytes.
68 # Filesystem 1M-blocks Used Available Use% Mounted on
69 # /dev/sda5 57349 24838 29621 46% /
73 free=`df -m . | $PCP_AWK_PROG 'NR == 2 { print $4 }'`
76 free=`df -mP . | $PCP_AWK_PROG 'NR == 2 { print $4 }'`
82 echo "Cannot determine free space (df -mP fails)"
83 elif [ "$free" -lt "$needspace" ]
85 echo "Insufficient free space ($free MB, need $needspace MB)"
89 # save and restore configuration files in a way that labels which test
90 # was responsible in the event of a test abort, but also preserves the
91 # mode and ownership of the configuration file
98 $sudo mv "$1" "$1.$seq"
99 $sudo cp "$1.$seq" "$1"
102 $sudo rm -rf "$1.$seq"
103 $sudo mv "$1" "$1.$seq"
104 $sudo cp -r "$1.$seq" "$1"
106 echo "Botch: _save_config: $1 does not exist"
115 $sudo mv "$1.$seq" "$1"
116 elif [ -d "$1.$seq" ]
119 $sudo mv "$1.$seq" "$1"
121 echo "Warning: _restore_config: $1.$seq does not exist"
125 # check that a given agent (argument 1) is up and running;
126 # indicated by return status and agent warnings to stdout.
134 [ X"$quiet" = "X" ] && quiet=false
136 pminfo -f $agent 2>&1 | \
138 BEGIN { value=0; metric=0; warn=0 }
140 / value / { value++; next }
141 /^'$agent'/ { metric++
145 END { if (warn) printf "%d warnings, ",warn
146 printf "%d metrics and %d values\n",metric,value
149 pminfo -v $agent 2>&1 | LC_COLLATE=POSIX sort >$tmp.verify
150 $quiet || cat $tmp.fetch
151 if grep warnings $tmp.fetch > /dev/null 2>&1
153 # X warnings, Y metrics and Z values
154 num_warn=`sed -n -e '/warnings/s/ .*//p' < $tmp.fetch`
155 if [ "$num_warn" -gt 0 ]
157 echo "Warnings when fetching $agent metrics:"
169 # prepare and cleanup pmda routines work together to ensure
170 # pmcd+pmda state is left as it was at the start of a test.
178 [ "X$__names" = "X" ] && __names=$iam
180 install_on_cleanup=false
181 pminfo $__names >/dev/null 2>&1 && install_on_cleanup=true
182 # copy the pmcd config file to restore state later.
183 _save_config $PCP_PMCDCONF_PATH
196 _restore_config $PCP_PMCDCONF_PATH
197 $sudo $PCP_RC_DIR/pcp restart | _filter_pcp_start
200 if $install_on_cleanup
202 [ "X$__iopts" = "X" ] && __iopts=/dev/null
203 ( cd $PCP_PMDAS_DIR/$__agent; $sudo ./Install <$__iopts >/dev/null 2>&1 )
205 ( cd $PCP_PMDAS_DIR/$__agent; $sudo ./Remove >/dev/null 2>&1 )
219 if [ -f $PCP_PMDAS_DIR/$__pmda/help.dir ]
221 # ./Install already run, or QA stumbled past to run newhelp
225 cd $PCP_PMDAS_DIR/$__pmda
226 $sudo $PCP_BINADM_DIR/newhelp -n root help >$tmp.out 2>&1
227 if [ -f $PCP_PMDAS_DIR/$__pmda/help.dir ]
232 echo "Arrgh ... failed to create help.dir for $pmda PMDA"
240 # Get all IPv6 connection strings for a hosts interfaces, excluding loopback
244 ADDRESS=`pminfo -f -h "$1" network.interface.ipv6_addr | \
245 sed -e '/^$/d' -e '/^network/d' -e '/"lo"/d' -e 's/\/[0-9][0-9]*//g'`
246 LOCAL_LINK=`echo $ADDRESS | awk -F\" '{ printf "%s\n", $4 }' | grep -i "^fe80::"`
247 if [ ! -z "$LOCAL_LINK" ]; then
248 echo $ADDRESS | awk -F\" '{ printf "%s%%%s\n", $4, $2 }'
250 echo $ADDRESS | awk -F\" '{ printf "%s\n", $4 }'
257 my $packed_ip = gethostbyname("'$1'");
258 if (defined $packed_ip) {
259 my $ip_address = inet_ntoa($packed_ip);
267 my $iaddr = inet_aton("'$1'");
268 if (defined $iaddr) {
269 my $name = gethostbyaddr($iaddr, AF_INET);
276 ans=`hostname -f 2>/dev/null | grep '\.'`
279 if which nslookup >/dev/null 2>&1
281 ans=`nslookup $1 2>&1 | sed -n -e '/^Name:[ ][ ]*/s///p'`
286 if which domainname >/dev/null 2>&1
288 ans=`domainname | fgrep -v '(none)'`
289 [ -z "$ans" ] || ans="$1.$ans"
294 # fake out localhost.localdomain if no working DNS
295 ans=localhost.localdomain
302 if [ ! -f /etc/hosts ]
304 echo >&2 "Arrgh ... cannot find /etc/hosts to determine IPv6 localhost name"
307 for sniff in localhost6 ip6-localhost ipv6-localhost
309 if sed -e '/^#/d' -e 's/$/ /' /etc/hosts | grep -q "[ ]$sniff "
315 echo >&2 "Arrgh ... cannot determine IPv6 localhost name from /etc/hosts"
321 if pminfo -h ${2-localhost} -f $1 2>&1 | grep " value " >/dev/null
325 echo "Check failed for metric \"$1\" at host \"${2-localhost}\" ... is PMDA installed?"
330 # wait_for_pmcd [maxdelay [host]]
334 # 20 seconds default seems like a reasonble max time to get going
340 #debug# ping -c 2 $_host
341 #debug# pcp -h $_host
342 #debug# pcp -h `hostname`
343 while [ $_i -lt $_can_wait ]
345 #debug# pmprobe -n $PCP_VAR_DIR/pmns/root_pmcd -h $_host pmcd.numclients
346 _sts=`pmprobe -n $PCP_VAR_DIR/pmns/root_pmcd -h $_host pmcd.numclients 2>/dev/null | $PCP_AWK_PROG '{print $2}'`
347 if [ "${_sts:-0}" -gt 0 ]
349 # numval really > 0, we're done
360 echo "Arrgghhh ... pmcd at $_host failed to start after $_can_wait seconds"
361 echo "=== failing pmprobe ==="
362 echo "+ pmprobe -n $PCP_VAR_DIR/pmns/root_pmcd -h $_host pmcd.numclients"
363 pmprobe -n $PCP_VAR_DIR/pmns/root_pmcd -h $_host pmcd.numclients
366 localhost|unix:|local:|`hostname`)
367 # these are all local PMCD's
369 echo "=== pmcd.log ==="
370 cat $PCP_LOG_DIR/pmcd/pmcd.log
372 echo "likely looking processes ..."
373 ps "$PCP_PS_ALL_FLAGS" | egrep "[p]m|[P]ID"
376 # assume a remote PMCD
378 ssh pcpqa@$_host "sh -c '. \$PCP_DIR/etc/pcp.env; echo; echo "=== pmcd.log ==="; [ -f \$PCP_LOG_DIR/pmcd/pmcd.log ] && cat \$PCP_LOG_DIR/pmcd/pmcd.log; [ -f \$PCP_LOG_DIR/pmcd.log ] && cat \$PCP_LOG_DIR/pmcd.log; echo; echo likely looking processes ...; ( ps \$PCP_PS_ALL_FLAGS | egrep \"[p]m|[P]ID\" )'" </dev/null
386 # wait_for_pmlogger [pid logfile [maxdelay]]
390 # 20 seconds default seems like a reasonable max time to get going
396 dir_hostname=`hostname || echo localhost`
397 _logfile="$PCP_LOG_DIR/pmlogger/$dir_hostname/pmlogger.log"
412 echo "_wait_for_pmlogger(): wrong number of arguments"
421 rm -f $tmp._wait_for_pmlogger.pmlc
422 while [ $_i -lt $_maxdelay ]
424 #debug# ps -ef | grep "[^0-9]$_pid[^0-9]"
425 echo "pmlc $_pid" >> $tmp._wait_for_pmlogger.pmlc
426 if pmlc $_pid </dev/null 2>&1 \
427 | tee -a $tmp._wait_for_pmlogger.pmlc \
428 | egrep "Connection refused|Transport endpoint is not connected" >/dev/null
433 # pmlogger socket has been set up ...
435 # give pmlogger a chance to detect that pmlc has gone away
436 # so the port is free
444 echo "Arrgghhh ... pmlogger ($_iam) failed to start after $_maxdelay seconds"
446 echo "pmlogger log ($_logfile) ..."
450 # If pmlc could not connect to pmlogger, report details
451 if [ -s $tmp._wait_for_pmlogger.pmlc ]
453 echo "pmlc output ..."
454 cat $tmp._wait_for_pmlogger.pmlc
458 # If pmlogger could not connect to PMCD, find which host it was
459 # connecting to, and get the pmcd.log file from that host.
460 cat $_logfile | $PCP_AWK_PROG '/pmlogger: Cannot connect to PMCD on host/' \
461 | sed -e ' s/pmlogger: Cannot connect to PMCD on host "//g' \
462 -e ' s/": .*//g' >$tmp._wait_for_pmlogger.host
463 if [ -s $tmp._wait_for_pmlogger.host ]
465 _pmcdhost=`cat $tmp._wait_for_pmlogger.host`
466 echo "pmcd log ($_pmcdhost:$PCP_LOG_DIR/pmcd/pmcd.log) ..."
467 if [ -r /hosts/$_pmcdhost$PCP_LOG_DIR/pmcd/pmcd.log ]
469 cat /hosts/$_pmcdhost$PCP_LOG_DIR/pmcd/pmcd.log
470 elif [ -r /hosts/$_pmcdhost$PCP_LOG_DIR/pmcd.log ]
472 cat /hosts/$_pmcdhost$PCP_LOG_DIR/pmcd.log
474 if [ "`hostname | sed -e 's/\..*//'`" != $_pmcdhost ]
476 if scp -q $_pmcdhost:$PCP_LOG_DIR/pmcd/pmcd.log \
477 $tmp._wait_for_pmlogger.pmcdlog
479 cat $tmp._wait_for_pmlogger.pmcdlog
480 elif scp -q $_pmcdhost:$PCP_LOG_DIR/pmcd.log \
481 $tmp._wait_for_pmlogger.pmcdlog
483 cat $tmp._wait_for_pmlogger.pmcdlog
486 cat $PCP_LOG_DIR/pmcd/pmcd.log
490 base=`cat $_logfile | sed -n '/^Archive basename:[ ]*/s///p'`
491 if [ -n "$base" -a -f $base.0 ]
493 echo "archive created ..."
495 nres=`pmdumplog $base.0 | grep '^[0-9]' | wc -l | sed -e 's/ //g'`
496 echo "archive contains $nres records"
498 echo "archive not created"
501 echo "local pmlogger map ..."
502 for map in $PCP_TMP_DIR/pmlogger/*
504 if [ "`echo $map`" = "$PCP_TMP_DIR"'/pmlogger/*' ]
506 echo "No files in $PCP_TMP_DIR/pmlogger !?"
513 echo "Likely looking processes ..."
514 ps $PCP_PS_ALL_FLAGS | egrep '[p]m|[P]ID'
518 rm -f $tmp._wait_for_pmlogger.*
521 # Start a pmlogger with appropriate privs that it can create
522 # portmap files in PCP_TMP_DIR (requires pcp or root account)
524 # Couple of side-effects to be aware of:
525 # Returns with $pid containing the backgrounded pmlogger PID;
526 # Creates the pmlogger archive, logfile, etc as root/pcp, not
527 # as the user running QA (so, tmp cleanup needs to use sudo).
531 cat >$tmp.cmd <<End-of-File
538 id pcp >/dev/null 2>&1 && __user=pcp
540 $sudo -u $__user sh $tmp.cmd $@ >$tmp.pid
544 # wait for a pmlogger process to end that is not our child
545 # (else we could just use shell wait command). Instead we
546 # must keep tabs on the PID file and bail when its gone.
556 if [ -f "$PCP_TMP_DIR/pmlogger/$_pid" ]
561 echo "_wait_pmlogger_end: failed to see $PCP_TMP_DIR/pmlogger/$_pid removed after 100 iterations"
567 # now there is an ugly race condition at the end of pmloger
568 # ... once the control file has been removed (as per the test
569 # above) the pmlogger log file is not complete until the atexit()
570 # code is run ... so hang around waiting for the process to
576 if sudo kill -s 0 $_pid 2>/dev/null
578 # process still exists
582 echo "_wait_pmlogger_end: failed to see pid $_pid exit after 100 iterations"
588 # process has really exited
597 # Wait for pmcd to end
603 _pid=`cat $PCP_RUN_DIR/pmcd.pid 2>/dev/null`
606 # no $PCP_RUN_DIR/pmcd.pid file, try ps(1) the hard way
608 _pid=`$PCP_PS_PROG $PCP_PS_ALL_FLAGS \
609 | sed -n -e '/\[p]mcd /{
625 if sudo kill -s 0 $_pid 2>/dev/null
627 # process still exists
631 echo "_wait_pmcd_end: failed to see pid $_pid exit after 100 iterations"
637 # process has really exited
644 # ensure primary logger allows pmlc state changes
646 _writable_primary_logger()
648 _configfile="$PCP_VAR_DIR/config/pmlogger/config.default"
650 echo "_open_primary_logger checking config file: $_configfile" >>$here/$seq.full
652 # first, move aside the default configuration file
653 _save_config "$_configfile"
655 # next, create a new default configuration file
656 PMLOGCONF="$PCP_BINADM_DIR/pmlogconf"
657 test -f "$_configfile" || \
658 $sudo $PMLOGCONF -q -h localhost "$_configfile" >>$here/$seq.full 2>&1
660 # finally, open it up to local access from pmlc
661 sed <"$_configfile" >$tmp.sed-i \
662 -e 's/^allow localhost.*$/allow localhost : all;/g' \
663 -e 's/^allow local:.*$/allow local:* : all;/g'
664 $sudo cp $tmp.sed-i "$_configfile"
668 # restore primary logger pmlc access restrictions
670 _restore_primary_logger()
672 _configfile="$PCP_VAR_DIR/config/pmlogger/config.default"
674 # if there was an initial configuration, put it back
675 if test -f "$_configfile.$seq"
677 _restore_config "$_configfile"
679 # otherwise, close out access from local pmlc once more
680 if test -f "$_configfile"
682 sed <"$_configfile" >$tmp.sed-i \
683 -e 's/^allow localhost.*$/allow localhost : enquire;/g' \
684 -e 's/^allow local:.*$/allow local:* : enquire;/g'
685 $sudo cp $tmp.sed-i "$_configfile"
695 # At the top before outputting $seq.out but after setting $seq ...
700 # _run_purify [arg1] [arg2]
703 # initial setup for running purify
704 # creates purified binary in $_purify_dir
708 # Need to change these to match Purify setup locally, if you
711 LM_LICENSE_FILE=27000@snort.melbourne.sgi.com
712 RSU_LICENSE_MAP=/usr/Rational/config/LICENSE_MAP
713 export LM_LICENSE_FILE RSU_LICENSE_MAP
715 rm -f $here/$seq.full
717 _prog=`echo $_path | sed -e 's#.*/##'`
718 _pure_prog="$_prog.pure"
719 _purify_dir=$tmp.purify
723 cp $_path $_purify_dir
731 unset PURIFYOPTIONS PUREOPTIONS
732 purify -log-file=stderr $_prog >out 2>&1
733 if [ ! -x $_prog.pure ]
736 echo "Hmm ... purify failed to create $_prog.pure"
748 $_purify_dir/$_pure_prog $args > $tmp._purify.out 2>&1
749 cat $tmp._purify.out >>$_here/$seq.full
750 if grep -i expired $tmp._purify.out >/dev/null; then
753 _filter_purify < $tmp._purify.out
761 state == 0 && /License successfully checked out/ { state = 1; next }
762 state == 0 && /Purify checking enabled/ { state = 1; next }
763 state == 1 { print }' \
765 -e 's/pid [0-9][0-9]*/pid PID/g' \
766 -e "s;$_purify_dir;TMP;g" \
767 -e '/reserved for Purify internal use/d' \
768 -e 's/suppressed chunks/suppressed blocks/g' \
769 | $PCP_AWK_PROG -v extra="$PURIFY_FILTER_EXTRA" '
770 /Purify instrumented/ { skip = 0 }
771 /bytes leaked\./ { print "..."; skip = 1; next }
774 /Purify Heap Analysis/ { print "..."; skip = 1 }
775 /Basic memory usage \(including Purify/ { print "..."; skip = 1 }
776 extra != "" && /Current file descriptors/ { print "..."; skip = 1 }' \
777 | (if [ "$PURIFY_FILTER_EXTRA" ]
778 then sed -e 's/in use: [0-9][0-9]*/in use: N/'
785 [ $# -eq 1 ] || _notrun "_check_purify needs executable as argument"
787 which purify >/dev/null 2>&1
788 [ $? -eq 0 ] || _notrun "No purify binary found"
793 # note: non-X systems (MacOSX, Windows) must pass here unchallenged
794 if [ -z "$PCPQA_CLOSE_X_SERVER" ]
796 _notrun "\$PCPQA_CLOSE_X_SERVER not set in ./common.config"
799 which xdpyinfo >/dev/null 2>&1
802 DISPLAY=$PCPQA_CLOSE_X_SERVER xdpyinfo >/dev/null 2>&1 || \
803 _notrun "Failed sanity check on DISPLAY $PCPQA_CLOSE_X_SERVER"
805 export DISPLAY=$PCPQA_CLOSE_X_SERVER
810 [ $PCP_PLATFORM = linux ] || _notrun "Linux-specific containers testing"
811 _contain=`pmprobe -v pmcd.feature.containers | awk '{ print $3 }'`
812 [ $_contain = 1 ] || _notrun "Running kernel does not support containers"
813 pminfo -f pmcd.agent.type 2>/dev/null | grep linux | grep -q 'value 4'
814 [ $? = 0 ] || _notrun "pmdalinux has insufficient privileges as a DSO"
817 # good output from dbpmda looks like ...
818 # dbpmda> open pipe /var/lib/pcp/pmdas/papi/pmdapapi -d 126
820 # dbpmda> fetch papi.system.TOT_INS
822 # pmResult dump from 0x25c6e00 timestamp: 0.000000 10:00:00.000 numpmid: 1
823 # 126.0.14 (<noname>): numval: 1 valfmt: 1 vlist[]:
828 [ -f $PCP_PMDAS_DIR/papi/pmdapapi ] || _notrun "no executable for the papi PMDA"
829 [ -f $PCP_PMDAS_DIR/papi/root ] || _notrun "no PMNS for the papi PMDA"
831 $sudo dbpmda -n $PCP_PMDAS_DIR/papi/root -ie <<EOF >$tmp.papi.check
832 open pipe $PCP_PMDAS_DIR/papi/pmdapapi -d 126 -l $tmp.papi.log
833 attr "username" "root"
835 fetch papi.system.TOT_INS
837 echo "papi.log ..." >>$here/$seq.full
838 cat $tmp.papi.log >>$here/$seq.full
839 $sudo rm $tmp.papi.log
840 echo "_check_papi ..." >>$here/$seq.full
841 cat $tmp.papi.check >>$here/$seq.full
842 if grep ' value [0-9][0-9]*$' <$tmp.papi.check >/dev/null
846 _notrun "PAPI counters not available on this platform"
852 $sudo dbpmda -n $PCP_PMDAS_DIR/papi/root -ie <<EOF >$tmp.papi.check
853 open pipe $PCP_PMDAS_DIR/papi/pmdapapi -d 126
854 attr "username" "root"
856 traverse papi.system.perf
858 echo "_check_papi_native ..." >>$here/$seq.full
859 cat $tmp.papi.check >>$here/$seq.full
860 if grep "Error PDU: Unknown metric name" <$tmp.papi.check >/dev/null
862 _notrun "PAPI native metrics not available on this platform"
870 # At the top before outputting $seq.out but after setting $seq ...
874 # _run_valgrind app [arg1 [arg2] ... ]
879 which valgrind >/dev/null 2>&1
880 [ $? -eq 0 ] || _notrun "No valgrind binary found"
883 # Note: because we may be avoiding leaks in system libraries
884 # via the suppressions, there is potential indeterminism for
885 # the following case:
886 # -All heap blocks were freed -- no leaks are possible
888 # +definitely lost: 0 bytes in 0 blocks
889 # +indirectly lost: 0 bytes in 0 blocks
892 # last 5 sed expressions are for broken valgrind(1) on
893 # Debian strech circa 2016
897 noleak="LEAK SUMMARY:\ndefinitely lost: 0 bytes in 0 blocks\nindirectly lost: 0 bytes in 0 blocks"
899 -e 's/^==*[1-9][0-9]*==* *//' \
901 -e '/^Copyright (/d' \
902 -e '/^Using Valgrind-/d' \
903 -e '/^Parent PID:/d' \
904 -e '/^HEAP SUMMARY:/d' \
905 -e '/^in use at exit:/d' \
906 -e '/^total heap usage:/d' \
907 -e '/^possibly lost:/d' \
908 -e '/^still reachable:/d' \
909 -e '/^suppressed:/d' \
910 -e '/^Reachable blocks (those to which a pointer was found)/d' \
911 -e '/^To see them, rerun with:/d' \
912 -e '/^For counts of detected and suppressed errors,/d' \
913 -e '/^ERROR SUMMARY:/s/ (suppressed: [^)]*)/ .../' \
914 -e "s/^All heap blocks were freed -- .*/$noleak/g" \
915 -e '/WARNING: Serious error when reading debug info/d' \
916 -e '/When reading debug info from /d' \
917 -e '/Ignoring non-Dwarf2\/3\/4 block in .debug_info/d' \
918 -e '/Last block truncated in .debug_info; ignoring/d' \
919 -e '/parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4/d' \
925 __version=`valgrind --version | sed -e 's/valgrind-//'`
926 if [ -f $here/valgrind-suppress-$__version ]
928 __extra="--suppressions=$here/valgrind-suppress-$__version"
929 echo "Warning: using extra $__extra" >>$here/$seq.full
934 --leak-check=full --read-var-info=yes --gen-suppressions=all \
935 --suppressions=$here/valgrind-suppress $__extra \
936 --log-file=$tmp._valgrind \
937 $* 2>$tmp._valgrind.err >$tmp._valgrind.out
938 echo "=== std out ==="
939 cat $tmp._valgrind.out
940 echo "=== std err ==="
941 cat $tmp._valgrind.err
942 echo "=== valgrind report ===" >>$here/$seq.full
943 cat $tmp._valgrind >>$here/$seq.full
944 echo "=== filtered valgrind report ==="
945 _filter_valgrind <$tmp._valgrind
948 # Alternate invocation, using valgrind-silence as an assertion.
949 # Produces no stdout/stderr from valgrind - except in case of errors!
950 # Uses same suppression logic as _run_valgrind.
952 # Usage: $_valgrind_clean_assert CMD ARGS ...
953 # just as you'd have used CMD ARGS ...
954 # alone, or |filtered
957 # It works even if valgrind is not available (expanding to nothing).
959 _valgrind_clean_assert=
960 if which valgrind >/dev/null 2>&1; then
961 __version=`valgrind --version | sed -e 's/valgrind-//'`
962 if [ -f $here/valgrind-suppress-$__version ]
964 __extra="--suppressions=$here/valgrind-suppress-$__version"
965 echo "Warning: using extra $__extra" >>$here/$seq.full
969 valgrind --help >$tmp.valgrind.help 2>&1
970 grep -q .--vgdb= <$tmp.valgrind.help && __extra="$__extra --vgdb=no"
971 valgrind --help 2>&1 | grep -q show-leak-kinds
972 if grep -q .--show-leak-kinds= <$tmp.valgrind.help
974 __extra="$__extra --show-leak-kinds=definite"
976 if grep -q .--show-possibly-lost= <$tmp.valgrind.help
978 __extra="$__extra --show-reachable=no --show-possibly-lost=no"
980 __extra="$__extra --show-reachable=no"
983 rm -f $tmp.valgrind.help
984 _valgrind_clean_assert="valgrind -q \
985 --leak-check=full --read-var-info=yes --gen-suppressions=all \
986 --suppressions=$here/valgrind-suppress $__extra \
991 # Checks that given_value is in range of correct_value +/- tolerance.
992 # Tolerance can be an absolute value or a percentage of the correct value
993 # (see examples with tolerances below).
994 # Outputs suitable message to stdout if it's not in range.
996 # A verbose option, -v, may be used as the LAST argument
999 # foo: 0.0298 = 0.03 +/- 5%
1000 # _within_tolerance "foo" 0.0298 0.03 5%
1002 # foo: 0.0298 = 0.03 +/- 0.01
1003 # _within_tolerance "foo" 0.0298 0.03 0.01
1005 # foo: 0.0298 = 0.03 -0.01 +0.002
1006 # _within_tolerance "foo" 0.0298 0.03 0.01 0.002
1008 # foo: verbose output of 0.0298 = 0.03 +/- 5%
1009 # _within_tolerance "foo" 0.0298 0.03 5% -v
1021 # maxtol arg is optional
1022 # verbose arg is optional
1034 [ "$6" = "-v" ] && _verbose=1
1037 # find min with or without %
1038 _mintolerance=`echo $_mintol | sed -e 's/%//'`
1039 if [ $_mintol = $_mintolerance ]
1041 _min=`echo "scale=5; $_correct_val-$_mintolerance" | bc`
1043 _min=`echo "scale=5; $_correct_val-$_mintolerance*0.01*$_correct_val" | bc`
1046 # find max with or without %
1047 _maxtolerance=`echo $_maxtol | sed -e 's/%//'`
1048 if [ $_maxtol = $_maxtolerance ]
1050 _max=`echo "scale=5; $_correct_val+$_maxtolerance" | bc`
1052 _max=`echo "scale=5; $_correct_val+$_maxtolerance*0.01*$_correct_val" | bc`
1055 $_debug && echo "min = $_min"
1056 $_debug && echo "max = $_max"
1058 cat <<EOF > $tmp._bc.1
1060 if ($_min <= $_given_val) 1;
1061 if ($_min > $_given_val) 0;
1064 cat <<EOF > $tmp._bc.2
1066 if ($_given_val <= $_max) 1;
1067 if ($_given_val > $_max) 0;
1070 _above_min=`bc < $tmp._bc.1`
1071 _below_max=`bc < $tmp._bc.2`
1073 _in_range=`expr $_above_min \& $_below_max`
1075 # fix up min, max precision for output
1076 # can vary for 5.3, 6.2
1077 _min=`echo $_min | sed -e 's/0*$//'` # get rid of trailling zeroes
1078 _max=`echo $_max | sed -e 's/0*$//'` # get rid of trailling zeroes
1080 if [ $_in_range -eq 1 ]
1082 [ $_verbose -eq 1 ] && echo $_name is in range
1085 [ $_verbose -eq 1 ] && echo $_name has value of $_given_val
1086 [ $_verbose -eq 1 ] && echo $_name is NOT in range $_min .. $_max
1091 # comment pmlogger_check and pmsnap entries in the crontab file
1092 # (also cron.pmcheck and cron.pmsnap entries for backwards compatibility)
1093 # Usage: _remove_cron backup sudo
1095 # backup - where to keep the old crontab file
1096 # sudo - location of sudo
1100 rc_backup=${1:-crontab}
1103 $rc_sudo rm -f $rc_backup
1104 if $rc_sudo crontab -l 2>/dev/null >$rc_backup
1108 # error, make sure the backup is empty so no changes are made
1112 if [ -s $rc_backup ]
1114 $rc_sudo cat $rc_backup \
1116 -e 's/^[^#].*pmlogger_check/#&/' \
1117 -e 's/^[^#].*pmsnap/#&/' \
1118 -e 's/^[^#].*cron.pmcheck/#&/' \
1119 -e 's/^[^#].*cron.pmsnap/#&/' \
1120 | $rc_sudo crontab > /dev/null 2>&1
1124 # restore crontab back to original state
1125 # Usage: _restore_cron backup sudo
1127 # backup - where to keep the old crontab file
1128 # sudo - location of sudo
1132 rc_backup=${1:-crontab}
1135 if [ -s $rc_backup ]
1137 $rc_sudo rm -f rc_cron_out rc_cron_check rc_cron_diff
1138 if $rc_sudo crontab $rc_backup >rc_cron_out 2>&1
1140 # check everything is OK
1142 $rc_sudo crontab -l >rc_cron_check
1143 sed -e '/^#/d' $rc_backup >$rc_backup.clean
1144 sed -e '/^#/d' rc_cron_check >rc_cron_check.clean
1145 if diff -u $rc_backup.clean rc_cron_check.clean >rc_cron_diff 2>&1
1149 echo "_restore_cron: Warning: could not restore crontab to original state"
1150 echo " Unexpected differences ..."
1151 diff -u $rc_backup rc_cron_check
1153 $rc_sudo rm -f rc_cron_check rc_cron_diff
1155 echo "_restore_cron: Warning: could not restore crontab to original state"
1156 echo " crontab(1) failed ..."
1159 $rc_sudo rm -f rc_cron_out rc_cron_check rc_cron_diff
1163 # get offset into an archive relative to the first pmResult
1166 # Usage: _arch_start archive [offset]
1172 /^[0-9][0-9]:[0-9][0-9]:/ { if ($3 ~ /pmcd.pmlogger.host/) next
1195 printf "@%02d:%02d:%06.3f",t[1],t[2],t[3]
1200 # get an unused ipc port ... returned on std out, empty for failure
1201 # Usage: _get_port tcp|udp low_port high_port
1205 [ $# -ne 3 ] && return
1208 while [ $__port -le "$3" ]
1210 if fuser $__port/$__proto >/dev/null 2>&1
1217 __port=`expr $__port + 1`
1221 # get host endianness ("le" or "be")
1224 check=`echo a | od -x 2>&1 | sed -e 's/^0[^ ]* *//' -e 's/ //g' -e '/^$/d'`
1230 echo "Arrgh ... od -x returned something odd ($check)"
1238 # get host word size ("32" or "64")
1246 # but, apps are 64-bit on my Mac OS X
1247 [ $PCP_PLATFORM = darwin ] && size=64
1249 x86_64|ia64|ppc64|ppc64le|s390x|aarch64)
1253 echo "uname gave machine type with unknown word size ($machine)"
1261 # _all_hostnames host - generate all hostnames (or IP addresses) for this host,
1262 # that map to some network interface, excluding loopback
1267 ssh pcpqa@$1 </dev/null netstat -in 2>/dev/null >$tmp._tmp
1268 if grep 'Network.*Address' $tmp._tmp >/dev/null
1270 # This is the IRIX version of netstat -in, get IP addr from the
1273 # Name Mtu Network Address Ipkts Ierrs ...
1274 # ef0 1500 134.14.55.128 134.14.55.149 712168207 10 ...
1277 # ef2* 1500 none none 0 0 ...
1278 # lo0 32992 127 127.0.0.1 23628402 0 ...
1280 $PCP_AWK_PROG <$tmp._tmp >$tmp._addr '
1282 NF >= 4 && $4 ~ /^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$/ { print $4 }
1283 NF == 1 && $1 ~ /^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$/ { print $1 }
1284 END { print "End-of-List" }'
1286 ssh pcpqa@$1 </dev/null /sbin/ifconfig 2>/dev/null >$tmp._tmp
1287 if grep 'UP.*RUNNING' $tmp._tmp >/dev/null
1289 # This is the Linux version of ifconfig, get IP addr from the
1292 # eth0 Link encap:Ethernet HWaddr 00:90:27:98:EE:A8
1293 # inet addr:134.14.55.176 Bcast:134.14.55.255 ...
1294 # UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
1297 # lo Link encap:Local Loopback
1298 # inet addr:127.0.0.1 Mask:255.0.0.0
1299 # UP LOOPBACK RUNNING MTU:16436 Metric:1
1302 # Note addr: tag is not present in some ifconfig output
1304 $PCP_AWK_PROG <$tmp._tmp '
1305 /^lo/ { skip=1; next }
1306 skip == 1 && NF > 0 { next }
1307 skip == 1 { skip = 0 }
1308 $1 == "inet" && $2 ~ /addr:/ { print $2 }
1309 $1 == "inet" && $2 ~ /^[0-9]/ { print $2 }
1310 END { print "End-of-List" }' \
1311 | sed -e 's/addr://' >$tmp._addr
1313 # Nothing we can do really, as there is no way of passing
1314 # an error back from here, other than returning an empty
1322 if [ "$__ip" = "End-of-List" ]
1327 # check that ip addr is reachable
1328 if ping -c 1 $__ip >/dev/null 2>&1
1330 __host=`_ipaddr_to_host $__ip`
1331 if [ ! -z "$__host" ]
1333 $PCP_ECHO_PROG $PCP_ECHO_N ",$__host""$PCP_ECHO_C"
1335 $PCP_ECHO_PROG $PCP_ECHO_N ",$__ip""$PCP_ECHO_C"
1342 # _all_ipaddrs - generate all IP addresses for this host,
1343 # that map to some network interface, excluding
1344 # loopback, slip, ppp
1346 # See _all_hostnames() above for comments on the method used.
1351 if [ "$1" = "localhost" ]
1353 netstat -in 2>/dev/null >$tmp._tmp
1355 ssh pcpqa@$1 </dev/null netstat -in 2>/dev/null >$tmp._tmp
1357 if grep 'Network.*Address' $tmp._tmp >/dev/null
1359 # this is the IRIX version of netstat -in, get IP addr from the
1362 $PCP_AWK_PROG <$tmp._tmp >$tmp._addr '
1363 /^lo/ || /^sl/ || /^pp/ { next }
1364 NF >= 4 && $4 ~ /^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$/ { print $4 }
1365 NF == 1 && $1 ~ /^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$/ { print $1 }
1366 END { print "End-of-List" }'
1368 if [ "$1" = "localhost" ]
1370 /sbin/ifconfig 2>/dev/null >$tmp._tmp
1372 ssh pcpqa@$1 </dev/null /sbin/ifconfig 2>/dev/null >$tmp._tmp
1374 if grep 'UP.*RUNNING' $tmp._tmp >/dev/null
1376 # This is the Linux version of ifconfig, get IP addr from the
1379 # ppp0 Link encap:Point-to-Point Protocol
1380 # inet addr:134.14.52.219 P-t-P:134.14.52.189 Mask:255.255.255.255
1381 # UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1522 Metric:1
1382 # RX packets:50119 errors:0 dropped:0 overruns:0 frame:0
1383 # TX packets:47474 errors:0 dropped:0 overruns:0 carrier:0
1384 # collisions:0 txqueuelen:3
1385 # RX bytes:7017171 (6.6 Mb) TX bytes:3952015 (3.7 Mb)
1387 # Note addr: tag is not present in some ifconfig output,
1388 # AND UP comes first!
1390 $PCP_AWK_PROG <$tmp._tmp '
1391 /^[a-z]/ { loopback = 0 }
1392 /^lo/ { loopback = 1; next }
1393 $1 == "inet" && $2 ~ /addr:/ { save = $2; next }
1394 $1 == "inet" && $2 ~ /^[0-9]/ { save = $2; next }
1395 $1 == "TX" { if (loopback == 0 && save != 0)
1399 END { print "End-of-List" }' \
1400 | sed -e 's/addr://' >$tmp._addr
1402 # Nothing we can do really, as there is no way of passing
1403 # an error back from here, other than returning an empty
1411 if [ "$__ip" = "End-of-List" ]
1416 $PCP_ECHO_PROG $PCP_ECHO_N ",$__ip""$PCP_ECHO_C"
1421 # fqdn for localhost
1425 _host_to_fqdn `hostname`
1428 # Distro-specific filtering for init, rc scripts, chkconfig, et al
1430 _filter_init_distro()
1432 if [ -f /etc/mandriva-release ]
1434 # looks like this is a Mandriva bug ... see
1435 # http://mandriva.598463.n5.nabble.com/Bug-24409-initscripts-New-netfs-provides-local-fs-scripts-can-t-be-turned-off-td869820.html
1438 -e '/Warning: netfs is needed by pcp in runlevel/d'
1444 # deal with chkconfig et al
1445 # assumes $sudo is set correctly
1446 # try very hard to _not_ emit messages unless serious errors encountered
1450 if [ $PCP_PLATFORM = linux ]
1453 [ "$1" = "verbose" ] && pat=""
1455 _have_systemctl=false
1456 which systemctl >/dev/null 2>&1 && _have_systemctl=true
1460 elif [ -n "$PCP_SYSTEMDUNIT_DIR" -a -f $PCP_SYSTEMDUNIT_DIR/$pat.service ]
1466 if $_have_systemctl && $_have_service
1468 # Run with systemd whenever it is available now
1475 echo "_change_config: Error: \$2=$2 not \"on\" or \"off\" as expected"
1481 $sudo systemctl $act $pat.service >$tmp._tmp 2>$tmp._err
1482 [ $? -eq 0 ] || cat $tmp._tmp
1484 elif which chkconfig >/dev/null 2>&1
1486 # Try the older RedHat and SuSE way ..
1488 [ -n "$pat" ] && $sudo chkconfig $pat $2 2>&1 \
1490 -e '/^insserv: warning: current start runlevel(s) .* of script .pcp./d' \
1491 -e '/^insserv: Service .* is missed in the runlevels /d' \
1493 elif [ -x /usr/sbin/sysv-rc-conf ]
1495 # Try the Debian and Ubuntu way ..
1497 [ -n "$pat" ] && $sudo /usr/sbin/sysv-rc-conf $pat $2
1498 elif which rc-update >/dev/null 2>&1
1500 # Try the Gentoo way ..
1509 echo "_change_config: Error: \$2=$2 not \"on\" or \"off\" as expected"
1513 $sudo rc-update $act $pat default >$tmp._tmp 2>&1
1514 [ $? -eq 0 ] || cat $tmp._tmp
1516 elif [ -f /etc/slackware-version ]
1518 # Slackware uses BSD-style init, so no control
1523 echo "_change_config: Error: cannot change config \"$1 $2\""
1526 elif [ $PCP_PLATFORM = solaris ]
1528 # Try the Solaris way ..
1530 if which svcadm >/dev/null 2>&1
1535 pmlogger) pat=pmlogger ;;
1543 state=`svcs -l svc:/application/pcp/$pat | sed -n '/^state[ ]/s///p'`
1544 [ -n "$state" -a "$state" != "online" ] \
1545 && $sudo svcadm clear svc:/application/pcp/$pat
1546 $sudo svcadm enable svc:/application/pcp/$pat
1549 $sudo svcadm disable svc:/application/pcp/$pat
1551 echo "_change_config: Error: \$2=$2 not \"on\" or \"off\" as expected"
1556 echo "_change_config: Error: cannot find svcs for Solaris"
1559 elif [ $PCP_PLATFORM = darwin ]
1564 pmlogger) pat=PMLOGGER ;;
1566 pmproxy) pat=PMPROXY ;;
1568 pmwebd) pat=PMWEBD ;;
1574 state=`sed -n -e "/^$pat=/{"'
1581 echo "_change_config: Error: No $pat control line in /etc/hostconfig"
1582 echo "You need to add a $pat=-YES- line to this file"
1588 elif [ "$2" = "off" ]
1592 echo "_change_config: Error: bad state ($2) should be on or off"
1595 if [ "$state" != "$req_state" ]
1597 sed </etc/hostconfig >$tmp._state \
1598 -e "/^$pat=/s/-.*/-$req_state-/"
1599 sudo cp $tmp._state /etc/hostconfig
1602 elif [ $PCP_PLATFORM = freebsd ]
1604 # no control for FreeBSD
1606 elif [ $PCP_PLATFORM = netbsd ]
1608 # no control for NetBSD
1610 elif [ $PCP_PLATFORM = openbsd ]
1612 # no control for OpenBSD
1615 # I have no idea what to do for this platform!
1617 echo "_change_config: Error: cannot \"$1 $2\" for $PCP_PLATFORM"
1620 | _filter_init_distro
1625 if [ "$PCP_PLATFORM" = linux ]
1629 pmlogger|pmcd) pat=$1 ;;
1634 _have_systemctl=false
1635 which systemctl >/dev/null 2>&1 && _have_systemctl=true
1639 elif [ -n "$PCP_SYSTEMDUNIT_DIR" -a -f $PCP_SYSTEMDUNIT_DIR/$pat.service ]
1645 if $_have_systemctl && $_have_service
1647 # Run with systemd whenever it is available now
1651 # unconditionally "on", or no such option
1655 if systemctl -q is-enabled $pat.service >/dev/null 2>&1
1662 elif which chkconfig >/dev/null 2>&1
1664 # Try the older RedHat and SuSE way ..
1668 # unconditionally "on", or no such option
1672 if chkconfig $pat >$tmp.__tmp 2>&1
1674 # success from chkconfig is only useful if no output
1675 # was generated ... in the latter case, grep the output
1676 # for hints (this is for SuSE SLES9 in particular)
1678 if [ -s $tmp.__tmp ]
1680 if grep ' on$' $tmp.__tmp >/dev/null
1683 elif grep ' off$' $tmp.__tmp >/dev/null
1696 elif [ -x /usr/sbin/sysv-rc-conf ]
1698 # Try the Debian and Ubuntu way ..
1702 # unconditionally "on", or no such option
1706 if $sudo /usr/sbin/sysv-rc-conf $pat
1713 elif which rc-update >/dev/null 2>&1
1715 # Try the Gentoo way ..
1719 # unconditionally "on", or no such option
1723 if rc-update show default | grep $pat >/dev/null
1730 elif [ -f /etc/slackware-version ]
1732 # Slackware uses BSD-style init, so no control
1735 echo "_change_config: Error: don't know how to change config for Linux"
1738 elif [ $PCP_PLATFORM = solaris ]
1740 if which svcs >/dev/null 2>&1
1744 pmlogger|pmcd) pat=$1 ;;
1750 # unconditionally "on", or no such option
1754 state=`svcs -H svc:/application/pcp/$pat | sed -e 's/[ ].*//'`
1764 echo "_change_config: Error: smf ($state) from svcs not expected"
1770 echo "_change_config: Error: cannot find svcs for Solaris"
1773 elif [ $PCP_PLATFORM = darwin ]
1778 pmlogger) pat=PMLOGGER ;;
1785 state=`sed -n -e "/^$pat=/{"'
1792 echo "_change_config: Error: No $pat control line in /etc/hostconfig" >&2
1793 echo "You need to add a $pat=-YES- line to this file" >&2
1796 if [ "$state" = "YES" ]
1799 elif [ "$state" = "NO" ]
1803 echo "_change_config: Error: bad state ($state) should be YES or NO" >&2
1807 elif [ $PCP_PLATFORM = freebsd ]
1809 # no control for FreeBSD
1811 elif [ $PCP_PLATFORM = netbsd ]
1813 # no control for NetBSD
1815 elif [ $PCP_PLATFORM = openbsd ]
1817 # no control for OpenBSD
1820 echo "_change_config: Error: cannot \"$1 $2\" for $PCP_PLATFORM"
1824 # disable all system pmloggers running via the control file(s)
1828 [ -z "$PCP_PMLOGGERCONTROL_PATH" ] && \
1829 PCP_PMLOGGERCONTROL_PATH="$PCP_VAR_DIR/config/pmlogger/control"
1830 if [ -f $PCP_PMLOGGERCONTROL_PATH ]
1832 [ ! -f $tmp.control ] && \
1833 $sudo cp $PCP_PMLOGGERCONTROL_PATH $tmp.control
1835 if [ -d $PCP_PMLOGGERCONTROL_PATH.d ]
1837 [ ! -d $tmp.control.d ] && \
1838 $sudo cp -a $PCP_PMLOGGERCONTROL_PATH.d $tmp.control.d
1839 $sudo rm -fr $PCP_PMLOGGERCONTROL_PATH.d
1841 cat <<End-of-File >$tmp._tmp
1842 # dummy file created by qa/$seq on `date`
1843 # the goal here is to have a controlled primary logger that does
1844 # not make requests to pmcd!
1846 LOCALHOSTNAME y n PCP_LOG_DIR/pmlogger/LOCALHOSTNAME -c /dev/null
1848 $sudo cp $tmp._tmp $PCP_PMLOGGERCONTROL_PATH
1853 [ -z "$PCP_PMLOGGERCONTROL_PATH" ] && \
1854 PCP_PMLOGGERCONTROL_PATH="$PCP_VAR_DIR/config/pmlogger/control"
1855 if [ -d $tmp.control.d ]
1857 $sudo cp -a $tmp.control.d $PCP_PMLOGGERCONTROL_PATH.d
1858 $sudo rm -fr $tmp.control.d
1860 [ -f $tmp.control ] && \
1861 $sudo cp $tmp.control $PCP_PMLOGGERCONTROL_PATH
1865 # checks for core files in dir (defaults to .)
1877 echo "_check_core: aaargh $1 is not a directory!"
1881 if [ "`echo ${dir}core*`" != "${dir}core*" ]
1883 [ -z "$here" ] && here=/tmp
1884 [ -z "$seq" ] && seq=9999
1885 $PCP_ECHO_PROG $PCP_ECHO_N "Dumped core! (saved in $here as""$PCP_ECHO_C"
1886 for c in ${dir}core*
1889 $sudo mv $c $here/$seq.$d
1890 $PCP_ECHO_PROG $PCP_ECHO_N " $seq.$d""$PCP_ECHO_C"
1897 # prepare for a save-able pmcd and pmda configuration.
1899 _prepare_pmda_install()
1901 [ -z "$1" ] && echo "Error: bad _prepare_pmda_install call"
1904 # copy the pmcd config file to restore state later.
1905 _save_config $PCP_PMCDCONF_PATH
1907 cd $PCP_PMDAS_DIR/$iam
1908 if [ -f Makefile -o -f GNUmakefile ] ; then
1909 if $sudo ${MAKE:-make} clobber >$tmp._tmp 2>&1 ; then
1913 echo "Arrgh, ${MAKE:-make} clobber failed"
1918 # start from a known starting point
1919 $sudo ./Remove >/dev/null 2>&1
1920 [ -f $PCP_VAR_DIR/config/$iam/$iam.conf ] && \
1921 $sudo mv $PCP_VAR_DIR/config/$iam/$iam.conf $tmp.$iam.conf
1924 # restore a saved pmcd configuration and ensure pmda back in place.
1926 _restore_pmda_install()
1928 [ -z "$1" ] && echo "Error: bad _restore_pmda_install call"
1930 signal=$PCP_BINADM_DIR/pmsignal
1932 [ -f $PCP_VAR_DIR/config/$iam/$iam.conf.$seq ] \
1933 && $sudo mv $PCP_VAR_DIR/config/$iam/$iam.conf.$seq $PCP_VAR_DIR/config/$iam/$iam.conf
1935 if diff $PCP_PMCDCONF_PATH.$seq $PCP_PMCDCONF_PATH > /dev/null 2>&1
1937 _restore_config $PCP_PMCDCONF_PATH
1939 # do a default install which ensures the pmns and any views are installed
1941 cd $PCP_PMDAS_DIR/$iam
1942 $sudo ./Install < /dev/null > /dev/null 2>&1
1944 # PMDA may have been installed differently to default. As everything is
1945 # installed we can use the old pmcd.conf file to restore state.
1947 if diff $PCP_PMCDCONF_PATH.$seq $PCP_PMCDCONF_PATH > /dev/null 2>&1
1949 _restore_config $PCP_PMCDCONF_PATH
1951 _restore_config $PCP_PMCDCONF_PATH
1952 $sudo $signal -a -s HUP pmcd
1957 # find a local port that is not in use, optionally starting from a suggested port
1962 [ -z "$base" ] && base=54321
1964 while $PCP_BINADM_DIR/telnet-probe -c localhost $base
1966 base=`expr $base + 1`
1971 # get pid for the running primary pmlogger
1973 _get_primary_logger_pid()
1975 root="$PCP_TMP_DIR/pmlogger/primary"
1979 elif which realpath >/dev/null 2>&1
1981 symroot=`realpath "$root"`
1984 symroot=`ls -l "$root" | sed -e 's/.*-> //'`
1985 if [ -z "$symroot" ]
1987 echo "Arrgh, cannot get symlink for device for root fs ..."
1995 _get_libpcp_config()
1997 pmconfig -L -s > $tmp.config