diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2014-10-26 12:33:50 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2014-10-26 12:33:50 +0400 |
commit | 47e6e7c84f008a53061e661f31ae96629bc694ef (patch) | |
tree | 648a07f3b5b9d67ce19b0fd72e8caa1175c98f1a /src/pmcd/rc_pmcd | |
download | pcp-debian/3.9.10.tar.gz |
Debian 3.9.10debian/3.9.10debian
Diffstat (limited to 'src/pmcd/rc_pmcd')
-rw-r--r-- | src/pmcd/rc_pmcd | 540 |
1 files changed, 540 insertions, 0 deletions
diff --git a/src/pmcd/rc_pmcd b/src/pmcd/rc_pmcd new file mode 100644 index 0000000..49b7430 --- /dev/null +++ b/src/pmcd/rc_pmcd @@ -0,0 +1,540 @@ +#!/bin/sh +# +# Copyright (c) 2013 Red Hat. +# Copyright (c) 2000-2008 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Start or Stop the Performance Co-Pilot Collection Daemon (PMCD) +# +# The following is for chkconfig on RedHat based systems +# chkconfig: 2345 95 05 +# description: pmcd is the collection daemon for the Performance Co-Pilot (PCP) +# +# The following is for insserv(1) based systems, +# e.g. SuSE, where chkconfig is a perl script. +### BEGIN INIT INFO +# Provides: pmcd +# Required-Start: $local_fs +# Should-Start: $network $remote_fs $syslog $time +# Required-Stop: $local_fs +# Should-Stop: $network $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Control pmcd (the collection daemon for PCP) +# Description: Configure and control pmcd (the collection daemon for the Performance Co-Pilot) +### END INIT INFO + +. $PCP_DIR/etc/pcp.env +. $PCP_SHARE_DIR/lib/rc-proc.sh + +PMCD=$PCP_BINADM_DIR/pmcd +PMCDOPTS=$PCP_PMCDOPTIONS_PATH +PCPLOCAL=$PCP_PMCDRCLOCAL_PATH +RUNDIR=$PCP_LOG_DIR/pmcd +prog=$PCP_RC_DIR/`basename $0` + +# search for your mail agent of choice ... +# +MAIL='' +for try in Mail mail email +do + if which $try >/dev/null 2>&1 + then + MAIL=$try + break + fi +done + +tmp=`mktemp -d /var/tmp/pcp.XXXXXXXXX` || exit 1 +status=1 +trap "rm -rf $tmp; exit \$status" 0 1 2 3 15 + +case "$PCP_PLATFORM" +in + mingw) + # nothing we can usefully do here, skip the test + # + IAM=0 + ;; + + *) + # standard Unix/Linux style test + # + ID=id + IAM=`$ID -u 2>/dev/null` + if [ -z "$IAM" ] + then + # do it the hardway + # + IAM=`$ID | sed -e 's/.*uid=//' -e 's/(.*//'` + fi + ;; +esac + +_pmcd_logfile() +{ +default=$RUNDIR/pmcd.log +$PCP_AWK_PROG <$PMCDOPTS ' +BEGIN { logf = "'$default'" } +$1 == "-l" { if (NF > 1) logf = $2 } +END { print logf }' +} + +_reboot_setup() +{ + # base directories and house-keeping for daemon processes + # + # For most packages, $PCP_RUN_DIR is included in the package, + # but for Debian and cases where /var/run is a mounted filesystem + # it may not exist, so create it here before it is used to create + # any pid/lock files + # + # $PCP_RUN_DIR creation is also done in pmlogger_daily, but if pmcd + # is running, we'd expect do this one first + # + if [ ! -d "$PCP_RUN_DIR" ] + then + mkdir -p -m 775 "$PCP_RUN_DIR" + chown $PCP_USER:$PCP_GROUP "$PCP_RUN_DIR" + fi + + # setup and clean up base directories and house-keeping for tracking + # pmlogger instances ... needs to be done here because pmcd needs the + # information, even if no pmlogger instances are started (and even if + # $PCP_RC_DIR/pmlogger is not run) + # + if [ ! -d "$PCP_TMP_DIR/pmlogger" ] + then + mkdir -p -m 777 "$PCP_TMP_DIR/pmlogger" + chown $PCP_USER:$PCP_GROUP "$PCP_TMP_DIR/pmlogger" + else + rm -rf $tmp/ent $tmp/pid + here=`pwd` + cd "$PCP_TMP_DIR/pmlogger" + rm -f primary vcr + _get_pids_by_name pmlogger | sort >$tmp/pid + ls [0-9]* 2>&1 | sed -e '/\[0-9]\*/d' \ + | sed -e 's/[ ][ ]*//g' | sort >$tmp/ent + # remove entries without a pmlogger process + # + rm -f `comm -23 $tmp/ent $tmp/pid` + rm -f $tmp/ent $tmp/pid + cd "$here" + fi + + # Rebuild PMNS? + # + PMNSDIR=$PCP_VAR_DIR/pmns + + rebuild=false + if [ -d $PMNSDIR -a \( -f $PMNSDIR/.NeedRebuild -o ! -f $PMNSDIR/root \) ] + then + rebuild=true + else + num=`find $PMNSDIR -newer $PMNSDIR/root -iname 'root_*' 2>/dev/null | wc -l` + [ "$num" -gt 0 ] && rebuild=true + fi + + if $rebuild + then + if [ -x $PMNSDIR/Rebuild ] + then + $ECHO $PCP_ECHO_N "Rebuilding PMNS ..." "$PCP_ECHO_C" + here=`pwd` + cd $PMNSDIR + ./Rebuild -du $REBUILDOPT + $RC_STATUS -v + # The 'root' file does not get updated when data did not change, + # so we must touch it to update date. + [ $? -eq 0 ] && { rm -f .NeedRebuild; touch root; } + cd "$here" + fi + fi +} + +_pmda_setup() +{ + # Auto-Install PMDAs? + # + if [ -d $PCP_PMDAS_DIR ] + then + here=`pwd` + cd $PCP_PMDAS_DIR + for file in */.NeedInstall + do + [ "$file" = '*/.NeedInstall' ] && break + pmda=`dirname $file` + if [ -d "$pmda" -a -f "$pmda/.NeedInstall" ] + then + cd $pmda + $PCP_ECHO_PROG "Installing $pmda PMDA ..." + + # rename .NeedInstall _before_ calling Install because + # Install can call this start script (recursively) and + # we don't want to get stuck in an infinite loop. + # + rm -f .NeedInstall.sav + mv .NeedInstall .NeedInstall.sav + if ./Install </dev/null >/dev/null + then + # success + $PCP_BINADM_DIR/pmpost "PMDA setup: automated install: $pmda" + rm -f .NeedInstall.sav + else + # put the file back, maybe we'll be luckier next time + $PCP_BINADM_DIR/pmpost "PMDA setup: automated install FAILED (exit=$?): $pmda" + mv .NeedInstall.sav .NeedInstall + fi + + cd $PCP_PMDAS_DIR + fi + done + cd "$here" + fi +} + +_start_pmcheck() +{ + if [ ! -z "$PMCD_WAIT_TIMEOUT" ] + then + wait_option="-t $PMCD_WAIT_TIMEOUT" + else + wait_option='' + fi + + if pmcd_wait $wait_option + then + : + else + status=$? + $PCP_BINADM_DIR/pmpost "pmcd_wait failed in $prog: exit status: $status" + if [ ! -z "$MAIL" ] + then + echo "pmcd_wait exit status: $status" | $MAIL -s "pmcd_wait failed in $prog" root + else + echo "$prog: pmcd_wait failed: exit status: $status" + fi + fi +} + +# Use $PCP_PMCDCONF_PATH to find and terminate pipe/socket PMDAs. +# (First join up continued lines in config file) +# +_killpmdas() +{ + if [ ! -f $PCP_PMCDCONF_PATH ] + then + echo "$prog:"' +Warning: pmcd control file '"$PCP_PMCDCONF_PATH"' is missing, cannot identify PMDAs + to be terminated.' + return + fi + # Give each PMDA 2 seconds after a SIGTERM to die, then SIGKILL + for pmda in `$PCP_AWK_PROG <$PCP_PMCDCONF_PATH ' +/\\\\$/ { printf "%s ", substr($0, 0, length($0) - 1); next } + { print }' \ +| $PCP_AWK_PROG ' +$1 ~ /^#/ { next } +tolower($3) == "pipe" && NF > 4 { print $5; next } +tolower($3) == "socket" && NF > 5 { print $6; next }' \ +| sort -u` + do + pmsignal -a -s TERM `basename $pmda` > /dev/null 2>&1 & + done + sleep 2 + for pmda in `$PCP_AWK_PROG <$PCP_PMCDCONF_PATH ' +/\\\\$/ { printf "%s ", substr($0, 0, length($0) - 1); next } + { print }' \ +| $PCP_AWK_PROG ' +$1 ~ /^#/ { next } +tolower($3) == "pipe" && NF > 4 { print $5; next } +tolower($3) == "socket" && NF > 5 { print $6; next }' \ +| sort -u` + do + pmsignal -a -s KILL `basename $pmda` > /dev/null 2>&1 & + done + + wait +} + +_shutdown() +{ + # Is pmcd running? + # + _get_pids_by_name pmcd >$tmp/tmp + if [ ! -s $tmp/tmp ] + then + [ "$1" = verbose ] && echo "$prog: pmcd not running" + rm -f $PCP_RUN_DIR/pmcd.pid $PCP_RUN_DIR/pmcd.socket + return 0 + fi + + # If pmcd is running but we can't find a pidfile, or a logfile at the + # configured or default location, assume this script is being run via + # a chroot build environment (and hence we do not want to signal pmcd). + # + logf=`_pmcd_logfile` + [ -f $logf ] || logf=$RUNDIR/pmcd.log + if [ ! -f $PCP_RUN_DIR/pmcd.pid -a ! -f $logf ] + then + pmcdpid=`cat $tmp/tmp` + echo "PMCD process ... $pmcdpid" + echo "$prog: +Warning: found no $PCP_RUN_DIR/pmcd.pid + and no $logf. + Assuming an uninstall from a chroot: pmcd not killed. + If this is incorrect, \"pmsignal -s TERM $pmcdpid\" can be used." + exit + elif [ -f $PCP_RUN_DIR/pmcd.pid ] + then + TOKILL=`cat $PCP_RUN_DIR/pmcd.pid` + if grep "^$TOKILL$" $tmp/tmp >/dev/null + then + : + else + echo "PMCD process ... "`cat $tmp/tmp` + echo "$prog: +Warning: process ID in $PCP_RUN_DIR/pmcd.pid is $TOKILL. + Check logfile $logf. When you are ready to proceed, remove + $PCP_RUN_DIR/pmcd.pid before retrying." + exit + fi + else + TOKILL= + fi + + # Send pmcd a SIGTERM, which is noted as a pending shutdown. + # When finished the currently active request, pmcd will close any + # connections, wait for any agents, and then exit. + # On failure, resort to SIGKILL. + # + $ECHO $PCP_ECHO_N "Waiting for pmcd to terminate ...""$PCP_ECHO_C" + delay=200 # tenths of a second + for SIG in TERM KILL + do + if [ "x$TOKILL" = "x" ] + then + pmsignal -a -s $SIG pmcd > /dev/null 2>&1 + else + pmsignal -s $SIG $TOKILL >/dev/null 2>&1 + rm -f $PCP_RUN_DIR/pmcd.pid $PCP_RUN_DIR/pmcd.socket + fi + while [ $delay -gt 0 ] + do + _get_pids_by_name pmcd >$tmp/tmp + [ ! -s $tmp/tmp ] && break 2 + pmsleep 0.1 + delay=`expr $delay - 1` + [ "$SIG" = "TERM" ] && [ `expr $delay % 10` -eq 0 ] \ + && $ECHO $PCP_ECHO_N ".""$PCP_ECHO_C" + done + echo + echo "Process ..." + if [ "$SIG" = "TERM" ] + then + $PCP_PS_PROG $PCP_PS_ALL_FLAGS >$tmp/ps + sed 1q $tmp/ps + for pid in `cat $tmp/tmp` + do + $PCP_AWK_PROG <$tmp/ps "\$2 == $pid { print }" + done + echo "$prog: Warning: Forcing pmcd to terminate!" + delay=20 + else + cat $tmp/tmp + echo "$prog: Warning: pmcd won't die!" + exit + fi + done + _killpmdas + $RC_STATUS -v + $PCP_BINADM_DIR/pmpost "stop pmcd from $prog" +} + +_usage() +{ + echo "Usage: $prog [-v] {start|restart|condrestart|stop|status|reload|force-reload}" +} + +VERBOSE_CTL=on +while getopts v c +do + case $c + in + v) # force verbose ... for historical reasons only as $VERBOSE_CTL + # is always "on" + ;; + + *) + _usage + exit 1 + ;; + esac +done +shift `expr $OPTIND - 1` + +if [ $VERBOSE_CTL = on ] +then # For a verbose startup and shutdown + ECHO=$PCP_ECHO_PROG + REBUILDOPT='' + VFLAG='-v' +else # For a quiet startup and shutdown + ECHO=: + REBUILDOPT=-s + VFLAG= +fi + +if [ "$IAM" != 0 -a "$1" != "status" ] +then + if [ -n "$PCP_DIR" ] + then + : running in a non-default installation, do not need to be root + else + echo "$prog:"' +Error: You must be root (uid 0) to start or stop the Performance Co-Pilot pmcd.' + exit + fi +fi + +# First reset status of this service +$RC_RESET + +# Return values acc. to LSB for all commands but status: +# 0 - success +# 1 - misc error +# 2 - invalid or excess args +# 3 - unimplemented feature (e.g. reload) +# 4 - insufficient privilege +# 5 - program not installed +# 6 - program not configured +# +# Note that starting an already running service, stopping +# or restarting a not-running service as well as the restart +# with force-reload (in case signalling is not supported) are +# considered a success. +case "$1" in + + 'start'|'restart'|'condrestart'|'reload'|'force-reload') + if [ "$1" = "condrestart" ] && ! is_chkconfig_on pmcd + then + status=0 + exit + fi + _shutdown quietly + + # Clean the environment for PMCD: + # PMCD and PMDA messages should go to stderr, not the GUI notifiers + # Clients in these scripts should test PMCD status without TLS/SSL. + # + unset PCP_STDERR PCP_SECURE_SOCKETS + + _reboot_setup + + if [ -x $PMCD ] + then + if [ ! -f $PCP_PMCDCONF_PATH ] + then + echo "$prog:"' +Error: pmcd control file '"$PCP_PMCDCONF_PATH"' is missing, cannot start pmcd.' + exit + fi + if [ ! -d "$RUNDIR" ] + then + mkdir -p -m 775 "$RUNDIR" + chown $PCP_USER:$PCP_GROUP "$RUNDIR" + fi + cd "$RUNDIR" + + # salvage the previous versions of any PMCD and PMDA logfiles + # + for log in pmcd `sed -e '/^#/d' -e '/\[access\]/q' -e 's/[ ].*//' <$PCP_PMCDCONF_PATH` + do + if [ -f $log.log ] + then + rm -f $log.log.prev + mv $log.log $log.log.prev + fi + done + + $ECHO $PCP_ECHO_N "Starting pmcd ..." "$PCP_ECHO_C" + + # only consider lines which start with a hyphen + # get rid of the -f option + # ensure multiple lines concat onto 1 line + OPTS=`sed <$PMCDOPTS 2>/dev/null \ + -e '/^[^-]/d' \ + -e 's/^/ /' \ + -e 's/$/ /' \ + -e 's/ -f / /g' \ + -e 's/^ //' \ + -e 's/ $//' \ + | tr '\012' ' ' ` + + $PMCD $OPTS + $RC_STATUS -v + + $PCP_BINADM_DIR/pmpost "start pmcd from $prog" + + _pmda_setup + + # force removal of primary pmlogger link ... if primary + # pmlogger is started, this will re-create the link + # + rm -f "$PCP_TMP_DIR/pmlogger/primary" + + # site-local customisations after PMCD startup + # + [ -x $PCPLOCAL ] && $PCPLOCAL $VFLAG start + + fi + status=0 + ;; + + 'stop') + # site-local customisations before pmcd shutdown + # + [ -x $PCPLOCAL ] && $PCPLOCAL $VFLAG stop + _shutdown verbose + status=0 + ;; + + 'status') + # NOTE: $RC_CHECKPROC returns LSB compliant status values. + $ECHO $PCP_ECHO_N "Checking for pmcd:" "$PCP_ECHO_C" + if [ -r /etc/rc.status ] + then + # SuSE + $RC_CHECKPROC $PMCD + $RC_STATUS -v + status=$? + else + # not SuSE + $RC_CHECKPROC $PMCD + status=$? + if [ $status -eq 0 ] + then + $ECHO running + else + $ECHO stopped + fi + fi + ;; + + *) + _usage + ;; +esac + |