File: //opt/perf/bin/pctl
#!/bin/sh
#Usage:pctl [status|start|stop|restart|version]
#==============================================================================
# @(#)pctl script 11.00.020 =*=
#
# This script performs basic startup and shutdown functions for the
# perfd daemon.
# The command line parameters and functions that are valid are:
#
# pctl <action>
#
# <action> status Report the daemon processes which are/not running
# start Start any daemon processes which are not running
# stop Terminate daemon processes.
# restart Terminate then start the daemon processes. This
# forces the daemons to reprocess their configuration
# files and reinitialize themselves.
# version Check whatstrings of product executables.
#
#============================================================================
# Note to developers: If you make any changes to this script, take care
# to insure that if the script is run non-interactively, then it will never
# perform a read to stdin. This script may be called as a part of the system
# startup processing and reading from stdin could hang the process!!
#============================================================================
#
# Performance Technology Center
# Hewlett-Packard
#
#==============================================================================
printusage() {
echo ""
echo "Usage = pctl <action>"
echo " <action> = status, start, stop, restart, version"
echo " Defaults: <action>=status"
} # printusage
#==============================================================================
PurgePSFILE () {
if [ -f "$PSFILE" ]; then
rm -f $PSFILE
fi
} # PurgePSFILE
#==============================================================================
getnewpidlist() {
# generate a "ps" list to a file for later processing by pidlist
if [ ! -f "$PSFILE" ]; then
if [ "$MKTEMP" = "X" ]; then
PSFILE="/var/tmp/pctlps$$"
else
PSFILE=`$MKTEMP $MKTEMP_OPTS pctlps.$$.XXXXXXXXXX 2>/dev/null`
if [ $? -ne 0 ]; then
PSFILE="/var/tmp/pctlps$$"
fi
fi
fi
$PS |head -1 >$PSFILE
$PS | cut -c 1-150 |tr -d '[\[]' |tr -d '[\]]' |grep "$OVPA_BIN_DIR" >>$PSFILE
if [ $? -ne 0 -o ! -s $PSFILE ]
then
echo "$PSFILE creation failed."
NicePCTLExit 1
fi
} # getnewpidlist
#==============================================================================
pidlist_p() {
# Print list of pids for which command name matches text passed as arg:
awk 'BEGIN { ORS=" " } \
$stime ~ /:/ { n=split($cmd1,arr,"/"); \
if ("'$*'" == arr[n]) print $pf; \
if ("'[$*]'" == arr[n]) print $pf; next } \
$cmd2 ~ /'$*'/ { n=split($cmd2,arr,"/"); \
if ("'$*'" == arr[n]) print $pf; \
if ("'[$*]'" == arr[n]) print $pf } ' \
stime=$STIMEFIELD cmd1=$CMDFIELD1 \
cmd2=$CMDFIELD2 pf=$PIDFIELD $PSFILE
} # end pidlist_p
pidlist() {
PIDLIST=`pidlist_p "$*"`
return `echo $PIDLIST | wc -w`
} # end pidlist
#==============================================================================
sets() {
# set shell variables according to host.
# the variable PIDFIELD then gets set to identify a field in the "ps" command.
LANG_FROM_ENV=$LANG
LC_ALL_FROM_ENV=$LC_ALL
LANG=C
export LANG
LC_ALL=C
export LC_ALL
SYS="`uname -s`"
REV="`uname -r`"
ARCH_NAME="`uname -m`"
VMWARE=" "
if [ `which mktemp 2>&1|grep "no mktemp"|wc -l` -eq 0 ]; then
MKTEMP="mktemp"
else
MKTEMP="X"
fi
OV_BIN_DIR="/opt/OV/bin"
case "$SYS" in
HP-UX)
SYS="HP-UX"
PS="/bin/ps -ef"
if [ "$ARCH_NAME" = "ia64" ]; then
SUB_LIB_DIR="/hpux64"
LIBEXT=".so"
else
SUB_LIB_DIR=""
LIBEXT=".sl"
fi
OVPA_BIN_DIR="/opt/perf/bin"
OVPA_LIB_DIR="/opt/perf/lib$SUB_LIB_DIR"
OVPA_DATA_DIR="/var/opt/perf/datafiles"
DEFAULT_PCTL_FILE="/etc/rc.config.d/pctl.default"
REV="11"
# if no command option is given, use the contents of this file:
if [ -f "$DEFAULT_PCTL_FILE" ]; then
. $DEFAULT_PCTL_FILE
fi
MKTEMP_OPTS="-d /var/tmp -p"
;;
Sun*)
SYS="SUN"
if [ `uname -p` = i386 ];
then
PLAT="i386"
else
PLAT=""
fi
OSVER=`echo $REV | cut -f2 -d .`
if [ $OSVER -ge 10 ] && [ -x /usr/bin/zonename ]; then
ZONENAME=`zonename`
if [ $? -eq 0 ] && [ $ZONENAME = "global" ]; then
PS="ps -fz global"
else
PS="ps -ef"
fi
else
PS="ps -ef"
fi
OVPA_BIN_DIR="/opt/perf/bin"
OVPA_DATA_DIR="/var/opt/perf/datafiles"
OVPA_LIB_DIR="/opt/perf/lib"
DEFAULT_PCTL_FILE="/etc/default/pctl.default"
LIBEXT=".so"
# if no command option is given, use the contents of this file:
if [ -f "$DEFAULT_PCTL_FILE" ]; then
. $DEFAULT_PCTL_FILE
fi
MKTEMP_OPTS="-p /var/tmp -q"
;;
Linux*)
SYS="LINUX"
# Don't know why other platforms try to source default file
PS="eval ps -ef 2>/dev/null" # Debian can output error messages.
OVPA_BIN_DIR="/opt/perf/bin"
if [ -f /opt/perf/lib64/libnums.so ]; then
OVPA_LIB_DIR="/opt/perf/lib64"
else
OVPA_LIB_DIR="/opt/perf/lib"
fi
OVPA_DATA_DIR="/var/opt/perf/datafiles"
DEFAULT_PCTL_FILE="/etc/sysconfig/pctl.default"
LIBEXT=".so"
# Only for the VMWare systems
if [ -d /proc/vmware ]; then
VMWARE="vmware"
fi
MKTEMP_OPTS="-p /var/tmp -q"
;;
AIX)
SYS="AIX"
if [ -f /usr/lpp/perf/lib64/libnums.a ]; then
OVPA_LIB_DIR="/usr/lpp/perf/lib64"
else
OVPA_LIB_DIR="/usr/lpp/perf/lib"
fi
if [ "$INSTALLED_BITS" = "64" ]; then
PS="ps -ef -@ Global"
else
PS="ps -ef"
fi
OVPA_BIN_DIR="/usr/lpp/perf/bin"
OVPA_DATA_DIR="/var/opt/perf/datafiles"
DEFAULT_PCTL_FILE="/etc/default/pctl.default"
OV_BIN_DIR="/usr/lpp/OV/bin"
LIBEXT=".a"
# if no command option is given, use the contents of this file:
if [ -f "$DEFAULT_PCTL_FILE" ]; then
. $DEFAULT_PCTL_FILE
fi
MKTEMP="X"
;;
*)
echo "Unsupported platform!"
exit 1
;;
esac
USERID=`/usr/bin/id | cut -d'(' -f1 | cut -d= -f2`
USERNAME=`/usr/bin/id | cut -d'(' -f2 | cut -f1 -d')'`
# if this script was called from perfstat then PSFILE should
# be defined, otherwise define it now:
STANDALONE=0
if [ "X$PSFILE" = "X" ]; then
getnewpidlist
STANDALONE=1
fi
# determine position of PID field in PS output
# (will differ by platform)
PIDFIELD=1
set `sed -n 1p $PSFILE`
while [ "X$1" != "XPID" ]
do
PIDFIELD=`expr $PIDFIELD + 1`
shift
done
# Determine position of STIME (sometimens STARTED) field in PS output
# (will differ between Sun, HP-UX, and "fair share scheduler" systems)
STIMEFIELD=1
set `sed -n 1p $PSFILE`
while [ "X$1" != "XSTIME" -a "X$1" != "XSTARTED" ]
do
STIMEFIELD=`expr $STIMEFIELD + 1`
shift
done
# Because time fields may look like one OR two fields to awk, need to
# assign two possible positions for command fields:
CMDFIELD1=1
set `sed -n 1p $PSFILE`
while [ "X$1" != "XCOMMAND" -a \
"X$1" != "XCMD" -a \
"X$1" != "XCOMD" ]
do
CMDFIELD1=`expr $CMDFIELD1 + 1`
shift
done
# Date format - Linux says Aug23, other unix Aug 23 so on Linux
# do not add 1 for CMDFIELD2. Set $TAB, also.
if [ "$SYS" = "LINUX" ]; then
TAB=`echo -e '\t'`
CMDFIELD2=`expr $CMDFIELD1`
else
TAB=`echo '\t'`
CMDFIELD2=`expr $CMDFIELD1 + 1`
fi
# Return value for perfstat, assume success:
OOPS=0
# For file/directory ownership
OV_OWNER=root:bin
# ovo switch user variables
CONF_TOOL="${OV_BIN_DIR}/ovconfget"
OVPA_OV_SUDO=""
OVPA_OV_SUDO_USER=""
OVPA_OV_SUDO_GROUP=""
OVPA_OV_MODE=""
OVPA_NPU_TASK=""
PA_NPU_CMD=""
if [ -x ${CONF_TOOL} ]; then
OVPA_OV_MODE=`${CONF_TOOL} eaagt |grep "^MODE=" | awk -F= '{print $2}' | grep -v \"\"`
OVPA_NPU_TASK=`${CONF_TOOL} eaagt |grep "^NPU_TASK_SET=" | awk -F= '{print $2}' | grep -v \"\"`
OVPA_OV_SUDO_USER=`${CONF_TOOL} |grep "^OV_SUDO_USER=" | awk -F= '{print $2}' | grep -v \"\"`
OVPA_OV_SUDO_GROUP=`${CONF_TOOL} |grep "^OV_SUDO_GROUP=" | awk -F= '{print $2}' | grep -v \"\"`
if [ "x${OVPA_OV_MODE}" = "xNPU" -a "x${USERNAME}" != "x${OVPA_OV_SUDO_USER}" ] ; then
PA_NPU_CMD="su - ${OVPA_OV_SUDO_USER} -c"
fi
if [ "x${OVPA_OV_MODE}" = "xMIXED" ] ; then
if [ "x${OVPA_NPU_TASK}" = "xAGENT_COEX" -a "x${USERNAME}" != "x${OVPA_OV_SUDO_USER}" ]; then
PA_NPU_CMD="su - ${OVPA_OV_SUDO_USER} -c"
fi
fi
fi
} # end sets
#==============================================================================
mustberoot() {
# Check if user is root or superuser in non-NPU mode, if not, bail out
if [ "x${OVPA_OV_MODE}" != "xNPU" ]; then
if [ $USERID -ne 0 ]; then
echo "ERROR: This function must be executed by superuser (root)"
PurgePSFILE
NicePCTLExit 1
fi
fi
} # mustberoot;
#==============================================================================
# Perfd Actions
#==============================================================================
StartPerfd () {
# Start the Perfd daemon
mustberoot
echo
echo "The Perf daemon is being started."
pidlist 'perfd'
if [ $? != 0 ]; then
echo " The perfd daemon"
echo " $OVPA_BIN_DIR/perfd, is already running."
else
if [ -x $OVPA_BIN_DIR/perfd ]; then # start perfd.
if [ "x" != "x${PA_NPU_CMD}" ]; then
eval ${PA_NPU_CMD} \"$OVPA_BIN_DIR/perfd\"
else
$OVPA_BIN_DIR/perfd
fi
if [ $? -eq 0 ]; then
echo " The Perfd daemon"
echo " $OVPA_BIN_DIR/perfd has been started."
else
echo "ERROR: The Perfd daemon"
echo " $OVPA_BIN_DIR/perfd failed to execute."
startup_exit_status=1
fi
else
echo "ERROR: Unable to execute $OVPA_BIN_DIR/perfd program."
startup_exit_status=1
fi
fi
echo " "
} # StartPerfd
#==============================================================================
StopPerfd () {
mustberoot
echo
echo "Shutting down Perfd"
RESULT=0;
pidlist 'perfd'
if [ $? != 0 ]; then
echo " Shutting down perfd, pid(s) $PIDLIST"
kill -TERM $PIDLIST >/dev/null 2>&1
# Wait in bunch of intervals
WAITTIMES=10
while [ $WAITTIMES -gt 0 ]
do
$SLEEP 2
getnewpidlist
pidlist 'perfd'
if [ $? != 0 ]; then
echo " Waiting on $PIDLIST ($WAITTIMES more tries)"
WAITTIMES=`expr $WAITTIMES - 1`
kill -TERM $PIDLIST >/dev/null 2>&1
else
RESULT=1
WAITTIMES=0
fi
done
if [ $RESULT -eq 1 ]; then
echo " The perfd daemon has been shut" \
"down successfully."
else # Try more severe termination request
$SLEEP 2
getnewpidlist
pidlist 'perfd'
if [ $? != 0 ]; then
echo " Issuing kill -KILL commands for pid(s) $PIDLIST"
kill -KILL $PIDLIST
fi
$SLEEP 5
getnewpidlist
pidlist 'perfd'
if [ $? != 0 ]; then
echo "ERROR: The Perfd daemon pid(s) $PIDLIST"
echo " has not terminated"
stop_exit_status=1
fi
fi
fi
} # StopPerfd
#==============================================================================
CheckPerfd () {
# Print the current status of the Perfd daemon
echo " Perfd status:"
pidlist 'perfd'
if [ $? != 0 ]; then
echo " Running perfd " \
"(Perfd daemon) pid $PIDLIST"
else
echo " WARNING: Perfd is not active"
OOPS=1
fi
} # CheckPerfd
#==============================================================================
# VERSION routines
#==============================================================================
p_what() {
# Platform-specific what function, Linux has no what command, this
# function handles one filename passed in arg1.
if [ "$SYS" != "LINUX" ]; then
what $1
elif [ -x $OVPA_BIN_DIR/ovwhat ]; then
$OVPA_BIN_DIR/ovwhat $1
else
key='@(#)'
echo $1:
strings $1 | grep "$key" | sed "s/$key/$TAB/"
fi
} # p_what
printwhat() {
# Looks for $DIR/files in arg list and prints what-strings:
for FILE in $@
do
if [ ! -f "$DIR/$FILE" ]; then
echo "WARNING: Expected file $DIR/$FILE does not exist"
OOPS=`expr $OOPS + 1`
else
p_what "$DIR/$FILE" | \
awk '
/\=\*\=/ { if (length(BestChoice)<=0) \
{ i = index( $0, "=*=" ) - 1
BestChoice = substr ( $0, 16, i-16 ) }
next }
/(700)|(800)/ { if (length(SecondChoice)<=0) \
{ i = index( $0, $2 )
SecondChoice=substr( $0 , i, length()-i+1) }
next }
END { if (length(BestChoice)>0)
printf "%20s %s\n", fn, BestChoice
else if (length(SecondChoice)>0)
printf "%20s %s\n", fn, SecondChoice
else
printf "%20s\n", fn
}
' fn=$FILE -
fi
done
} # printwhat
CheckPerfdVersion ()
{
# checks all version (whatstrings) for perfd
echo
DIR=$OVPA_BIN_DIR
printwhat perfd
printwhat padv
printwhat mpadv
printwhat cpsh
DIR=$OVPA_LIB_DIR
printwhat "libperfdaccess$LIBEXT"
printwhat "libcmdline$LIBEXT"
printwhat "libperfdadv$LIBEXT"
echo
} # CheckPerfdVersion
NicePCTLExit ()
{
# NicePCTLExit deletes PCTL_RUN
# This function can be used as a wrapper for any other on-exit tidying.
# if nodelete is supplied as $2, we do not delete the PCTL_RUN file
exitstatus=$1
if [ "$2" != "nodelete" ]; then
if [ -w $OVPA_DATA_DIR/PCTL_RUN ]; then
rm $PCTL_RUN_FILE
fi
fi
PurgePSFILE
exit $exitstatus
} # NicePCTLExit
#=========================================================
# Check if license is available for a given compnent
# returns 1, if license is available
# returns 0, if license is not available
#=========================================================
IsLicAvailable() {
retVal=0
if [ $# -gt 0 ]; then
OUTPUT=`$OV_BIN_DIR/oalicense -check $1`
if [ "$OUTPUT" = "Success" ]; then
retVal=1
fi
fi
return $retVal
}
CheckSingleInstance ()
{
mustberoot
# CheckSingleInstance creates PCTL_RUN
# It is called from start stop and restart functions in main
# (and not every time ovpa is started)
# check for the existance of datafiles directory.
# If not exist create that directory.
if [ ! -d $OVPA_DATA_DIR ];then
mkdir -p $OVPA_DATA_DIR
fi
# At this time we know, the user is superuser, we need to check if another
# pctl is run in a superuser mode
if [ -f $PCTL_RUN_FILE ]; then
# the PCTL_RUN file exists... Let's check for a pctl process running
# There could be a problem with this if the pctl script is renamed,
# also - if the user has a process containing pctl, the PCTL_RUN will have
# to be deleted manually - no way around this)
odg=`$PS | grep pctl | grep -v 'grep' | grep -v $$ | wc -l`
if [ $odg -ge 1 ]; then
echo "ERROR: Only one superuser (root) type of pctl command can be"
echo " run at the same time. If this is the only instance, please"
echo " delete $PCTL_RUN_FILE"
PurgePSFILE
NicePCTLExit 1 nodelete
fi
fi
# create $OVPA_DATA_DIR/PCTL_RUN
echo "$CMD script running in a root-required mode." > $PCTL_RUN_FILE
} # CheckSingleInstance
#-------- Process the command ---------------#
execute ()
{
if [ "$FUNCTION" = "status" ]; then
CheckPerfd
fi
#-----------------------------------------------VERSION Command
if [ "$FUNCTION" = "version" ]; then
CheckPerfdVersion
fi
#-----------------------------------------------START Command
if [ "$FUNCTION" = "start" ]; then
CheckSingleInstance
if [ ${licRTMA} -eq 1 -o ${licRTM} -eq 1 -o ${licGP} -eq 1 ]; then
StartPerfd
else
echo "Appropriate license is not set for Perfd to be started, Please set the required license for Perfd process to start."
fi
PurgePSFILE
if [ $startup_exit_status -ne 0 ]
then
NicePCTLExit 1
fi
NicePCTLExit 0
fi
#-----------------------------------------------STOP Command
if [ "$FUNCTION" = "stop" ]; then
CheckSingleInstance
pidlist 'perfd'
if [ $? != 0 ]; then
StopPerfd
fi
PurgePSFILE
if [ $stop_exit_status -ne 0 ]
then
NicePCTLExit 1
fi
NicePCTLExit 0
fi
#-----------------------------------------------RESTART Command
if [ "$FUNCTION" = "restart" ]; then
CheckSingleInstance
pidlist 'perfd'
if [ $? != 0 ]; then
StopPerfd
fi
if [ $stop_exit_status -ne 0 ]; then
NicePCTLExit 1
fi
getnewpidlist
if [ ${licRTMA} -eq 1 -o ${licRTM} -eq 1 -o ${licGP} -eq 1 ]; then
StartPerfd
else
echo "Appropriate license is not set for Perfd to be started, Please set the required license for Perfd process to start."
fi
if [ $startup_exit_status -ne 0 ]
then
NicePCTLExit 1
fi
NicePCTLExit 0
fi
PurgePSFILE
NicePCTLExit $OOPS nodelete
}
#==============================================================================
# MAIN
#==============================================================================
SLEEP="/bin/sleep"
if [ "`uname -s`" = "AIX" -a -f /usr/lpp/perf/lib64/libnums.a ]; then
INSTALLED_BITS=64
else
INSTALLED_BITS=32
fi
# Added this for Sun so we can find utilities like "what".
# If SUNWsprot package not installed (and /usr/ccs/bin/what doesn't exist),
# /opt/perf/bin/what is used instead.
cd /
PATH=$PATH:/usr/bin:/bin:/usr/ucb:/usr/sbin:/usr/ccs/bin
INTERACTIVE=`tty -s;echo $?`; export INTERACTIVE
# The colums = 160 is for large ps commands that exceed 80 columns.
COLUMNS=160; export COLUMNS
#-----------------------------------------------Parse Input Parameters
CMD=`basename "$0"`
if [ $# -eq 0 ]; then
FUNCTION="status"
elif [ "$1" = "?" \
-o "$1" = "-?" ]; then
printusage
PurgePSFILE
NicePCTLExit 0 nodelete
elif [ "$1" = "status" -o "$1" = "-status" \
-o "$1" = "start" -o "$1" = "-start" \
-o "$1" = "stop" -o "$1" = "-stop" \
-o "$1" = "restart" -o "$1" = "-restart" \
-o "$1" = "version" -o "$1" = "-version" ]; then
FUNCTION=`echo $1 | sed 's/-//'`
else
echo
echo "Invalid parameter \"$1\" "
printusage
PurgePSFILE
NicePCTLExit 1 nodelete
fi
# note this sets must be done after the option parsing above because sh
# as opposed to ksh does not preserve args in functions:
sets
IsLicAvailable "RTMA"
licRTMA=$?
IsLicAvailable "RTM"
licRTM=$?
IsLicAvailable "GP"
licGP=$?
PATH=$PATH:$OVPA_BIN_DIR
PCTL_RUN_FILE="$OVPA_DATA_DIR/PCTL_RUN"
startup_exit_status=0
stop_exit_status=0
execute
# Delete pctlps$$ if leftover:
PurgePSFILE