#!/usr/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # perf720 src/perf/perfagent/usr/lib/libSpmi/spmiclean.sh 1.6 # # Licensed Materials - Property of IBM # # Restricted Materials of IBM # # COPYRIGHT International Business Machines Corp. 2011,2012 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG DUMP_FILE=/var/perf/spmi.dump LOG_FILE=/var/perf/spmiclean.log DBX_FILE=/usr/bin/dbx INETD_FILE=/etc/inetd.conf OPT=$1 PID=$2 GREP="grep" commented="no" print_usage() { print "Usage: " print " spmiclean -d => To dump the stack of the processes that uses SPMI." print " spmiclean -c => To clean the shared memory used by SPMI." print " spmiclean -dc => To dump the stack of the processes that uses SPMI and clean the shared memory." print " spmiclean -p => To dump the stack of the process of the given pid." print " [NOTE: Dump file location: $DUMP_FILE]" } print_error() { print "Error occurred.. See $LOG_FILE for more details.\n" exit } check_dump_file_size() { echo "Dump file size check.. " >> $LOG_FILE if [ ! -f $DUMP_FILE ]; then touch $DUMP_FILE fi # Check for the dump file size. # If it is greater than 7000, then clear the file. size=`ls -la $DUMP_FILE | awk '{ print $5 }'` if [[ $size -gt 7000 ]]; then echo "$DUMP_FILE size huge. Clearing the file." >> $LOG_FILE : > $DUMP_FILE fi # Have this header info to ease the life of us when we get confused on # date of this log echo "================================================================" >> $DUMP_FILE echo "SPMI Dump log for $(date +%d/%m/%Y-%H:%M:%S)" >> $DUMP_FILE echo "================================================================" >> $DUMP_FILE echo "[OK]\n" >> $LOG_FILE } find_spmi_processes() { pids1=`/usr/bin/genld -l | grep -p Spmi | grep Proc | awk '{ print $2 }'` ; echo "Find SPMI processes: " >> $LOG_FILE echo "No process using SPMI. " >> $LOG_FILE if [[ $pids1 == '' ]]; then echo "[NOT OK]\n" >> $LOG_FILE else set -A pids $(echo "$pids1") fi echo "[OK] \n" >> $LOG_FILE } check_valid_pid() { tpids=`/usr/bin/ps -eaf | grep $PID | grep -v $GREP | awk '{ print $2 }'` echo " PID validity check: " >> $LOG_FILE if [[ $tpids == '' ]]; then echo "$PID does not exist. " >> $LOG_FILE echo "[NOT OK]\n" >> $LOG_FILE print_error else set -A tpid $(echo "$tpids") tp=0 while (( tp <= ${#tpid[*]}-1 )) do if [[ ${tpid[tp]} == $PID ]]; then echo "$PID exists. " >> $LOG_FILE echo "[OK]\n" >> $LOG_FILE return fi ((tp=tp+1)) done echo "$PID does not exist. " >> $LOG_FILE echo "[NOT OK]\n" >> $LOG_FILE print_error fi } print_process_dump_header() { echo "--------------------------------" >> $DUMP_FILE echo "Dump of $pname : " >> $DUMP_FILE echo "--------------------------------" >> $DUMP_FILE } dump_stack() { # Check if the binary is debug binary or not. # If it is not a debug binary, then do not dump the variable list # as it wont be of much help for debugging purpose check_debug_binary print_process_dump_header echo " Dumping $PID stack to $DUMP_FILE.. Wait!.. " >> $LOG_FILE echo "where \n $DUMP_CMD \n detach" | $DBX_FILE -a $PID >> $DUMP_FILE 2>&1 echo "[OK]\n" >> $LOG_FILE } check_debug_binary() { pname=`ps -eaf | grep $PID | grep -v $GREP | awk '{print $2,"\t",$8}' | grep $PID | awk '{print $2}'` pnamepath=`/usr/bin/type $pname | awk '{ print $3 }'` dbg=`/usr/bin/file $pnamepath | grep "not stripped"` if [[ $dbg == '' ]]; then echo " $pnamepath is not a debug binary.." >> $LOG_FILE DUMP_CMD="" else echo " $pnamepath is a debug binary.." >> $LOG_FILE DUMP_CMD=" dump . " fi } dump_stacks() { echo "Stack Dumping status: " >> $LOG_FILE if [[ $OPT == "-p" ]]; then check_valid_pid ; dump_stack else curpid=0; while (( curpid <= ${#pids[*]}-1 )) do PID=${pids[curpid]} ; dump_stack ; ((curpid=curpid+1)); done fi } add_inetd_entry() { if [[ $commented == "yes" ]]; then return fi echo " Adding back xmtopas entry in inetd.conf file .." >> $LOG_FILE sed "s/.*xmquery/xmquery/g" $INETD_FILE > temp; mv temp $INETD_FILE; echo " Refreshing inetd.." >> $LOG_FILE refresh -s inetd > /dev/null } remove_inetd_entry() { if [[ $commented == yes ]]; then return fi echo " Removing xmtopas entry from inetd.conf file.." >> $LOG_FILE sed "s/xmquery/#xmquery/g" $INETD_FILE > temp; mv temp $INETD_FILE; echo " Refreshing inetd.." >> $LOG_FILE refresh -s inetd > /dev/null } clean_memory() { echo " Cleaning shared memory.." >> $LOG_FILE for id in `/usr/bin/ipcs -a | grep 0x78 | awk '{ print \$2 }' ` do /usr/bin/ipcrm -m $id done } kill_pids() { if [[ ${#pids[*]} -gt 0 ]]; then echo " Killing existing SPMI consumer processes.." >> $LOG_FILE kill ${pids[*]} slibclean else echo " No process to kill.." >> $LOG_FILE fi } check_inetd_entry() { echo " Check if the inetd entry is already removed.." >> $LOG_FILE entry=`cat $INETD_FILE | grep "#xmquery"` if [[ $entry == "" ]]; then echo " Entry not commented.. so comment it and proceed.." >> $LOG_FILE commented="no" else echo " Entry already commented.. so dont touch it.." >> $LOG_FILE # Refresh inetd just in case user forgot to issue refresh after commenting the entry # in inetd.conf file echo " Refreshing inetd.." >> $LOG_FILE refresh -s inetd > /dev/null commented="yes" fi } clean_shared_memory() { echo "Shared memory cleanup: " >> $LOG_FILE check_inetd_entry remove_inetd_entry kill_pids clean_memory add_inetd_entry echo "[OK]\n" >> $LOG_FILE } check_dbx() { echo "DBX Fileset Check: " >> $LOG_FILE if [ ! -f $DBX_FILE ]; then echo " Please install bos.adt.debug fileset and try again." >> $LOG_FILE echo "[NOT OK]\n" >> $LOG_FILE exit else echo " DBX fileset bos.adt.debug installed." >> $LOG_FILE echo "[OK]\n" >> $LOG_FILE fi } dispatch() { # Print header info print_log_header # Check if DBX is installed check_dbx # Find SPMI processes that uses SPMI find_spmi_processes if [[ $OPT != -c ]]; then check_dump_file_size dump_stacks fi if [[ $OPT == *c ]]; then clean_shared_memory fi } print_log_header() { if [ ! -f $LOG_FILE ]; then /usr/bin/touch $LOG_FILE fi : > $LOG_FILE echo "================================================================" > $LOG_FILE echo "SPMI Clean log for $(date +%d/%m/%Y-%H:%M:%S)" >> $LOG_FILE echo "================================================================" >> $LOG_FILE } # Check for the correct usage of this script if [[ $# -lt 1 || $# -gt 2 || ( $OPT != -c && $OPT != -d && $OPT != -dc && $OPT != -p ) ]]; then print_usage exit fi if [[ $# -eq 1 && $OPT == -p ]]; then print_usage exit fi # Dispatch the queries. The script's main(). dispatch #if [[ $tty_id != - ]]; then echo "\nSUCCESS!!..." #fi exit;