#!/usr/bin/perl # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # perf720 src/perf/pmaix/usr/bin/pmcfg/shrpoolinfo 1.4 # # Licensed Materials - Property of IBM # # Restricted Materials of IBM # # COPYRIGHT International Business Machines Corp. 2012,2013 # 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 # @(#)11 1.1 src/perf/pmaix/usr/bin/pmcfg/shrpoolinfo, PMAIX, perf61Y 8/10/12 11:36:46 ## Check for RBAC authorization $viosfile="/usr/ios/cli/ioscli"; if( -e ${viosfile} ) { # If its vios, check for vios authorization `/usr/bin/ckauth vios.system.perfmgr.config`; if( $? ) { exit (1); } } else { # If its aix, check for aix authorization `/usr/bin/ckauth aix.system.perfmgr.config`; if( $? ) { exit (1); } } ##-- Output file name to be provided as the argument to this script if( $#ARGV < 0 ) { print "No output file provided. Please pass the output file name as the argument to this script\n"; exit(1); } ##-- Store filename provided as argument in OUTFILE variable my $OUTFILE = $ARGV[0]; ##-- Store config file pmconf path in PMCONF variable my $PMCONF="/var/perf/pm/config/pmconf"; ##-- LOGFILE contains the path for the pmcfg.log file and open the file to append the logs my $LOGFILE = "/var/perf/pm/daily/pmcfg.log"; open LOGFILE, ">>$LOGFILE"; ##-- Getting the file name of this script my $ScriptName = `/usr/bin/basename $0 2>/dev/null`; chomp($ScriptName); ##-- using temporary files which will be deleted at the end of the script my $tmpfile = "/tmp/${ScriptName}.$$"; my $tmpfile1 = "/tmp/${ScriptName}_1.$$"; ##-- Temporary output file opened to store the output of the script my $TMPOUTFILE = "/tmp/${ScriptName}_out.$$"; open TMPOUTFILE, ">$TMPOUTFILE"; ##-- Check to see if HMC is supported, if pmconf doesn't have HMC_Supported:, then update the pmconf file with HMC_Supported `/usr/bin/grep "HMC_Supported:" ${PMCONF}`; if( $? != 0 ) { `/usr/bin/cat ${PMCONF} > $tmpfile1`; `echo >> $tmpfile1`; `echo '# Is HMC Supported' >> $tmpfile1`; `echo "HMC_Supported:" >> $tmpfile1`; `echo >> $tmpfile1`; `/usr/bin/cp $tmpfile1 ${PMCONF}`; } ##-- Get the value of HMC_Supported from pmconf my $hmc_sup=`/usr/bin/grep "HMC_Supported:" ${PMCONF} | /usr/bin/cut -d ':' -f 2`; chomp($hmc_sup); ##-- Clearing the shrpoolinfo logs from pmcfg.log file `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: " > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; ##-- Function to write the logs passed to as string argument with time stamp and script name to the pmcfg.log file sub WriteLog { my $msg = shift; my $timestamp = `/usr/bin/date +'%T'`; chomp($timestamp); print LOGFILE "$timestamp:$ScriptName: $msg"; } ##-- Function to exit and cleanup temp files, normal exit if exitcode is 0, else exit with errors sub Grace_Exit { my $exitcode = shift; ##-- If the tmpfile exist, remove the tmpfile if( -e ${tmpfile} ) { $retval=""; $retval=`/usr/bin/rm ${tmpfile} 2>&1`; if( $? ) { WriteLog "Error: ${retval}"; WriteLog "Unable to delete temporary file ${tmpfile}!\n"; } } ##-- If tmpfile1 exist, remove tmpfile1 if( -e ${tmpfile1} ) { $retval=""; $retval=`/usr/bin/rm ${tmpfile1} 2>&1`; if( $? ) { WriteLog "Error: ${retval}"; WriteLog "Unable to delete temporary file ${tmpfile1}!\n"; } } ##-- If normal exit if( $exitcode == 0 ) { print TMPOUTFILE "\n"; ##-- Copy the output stored in temp output file to actual output file $retval=""; $retval=`/usr/bin/cp ${TMPOUTFILE} ${OUTFILE} 2>&1`; if( $? ) { WriteLog "Error: ${retval}"; WriteLog "Unable to write to output file ${OUTFILE}\n"; } } ##-- Close TEMPOUTFILE close TMPOUTFILE; ##-- Remove temporary output file $retval=""; $retval=`/usr/bin/rm ${TMPOUTFILE} 2>&1`; if( $? ) { WriteLog "Error: ${retval}"; WriteLog "Unable to delete temp output file ${TMPOUTFILE}\n"; } ##-- Close LOGFILE close LOGFILE; ##-- Exit with exitcode exit($exitcode); } ##-- Check to see if the /var filesystem has enough size to store the PM Oputput data ##-- Get the filesystem name my $filesys=`/usr/bin/df -m /var/perf/pm/daily | /usr/bin/grep -iv free | /usr/bin/awk '{print \$7}' 2>/dev/null`; chomp($filesys); ##-- Get the free space available in the filesystem my $freespace=`/usr/bin/df -m /var/perf/pm/daily | /usr/bin/grep -iv free | /usr/bin/awk '{print \$3}' 2>/dev/null`; chomp($freespace); ##-- If the freespace is less than 60 MB, exit with the error msg in log file if( $freespace < 60 ) { `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: Filesystem -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; ##-- If free space in the filesystem is less than 60 MB, quit. WriteLog "Filesystem - Not Enough Free Space in FileSystem $filesys!\n"; Grace_Exit 1; } ##-- Check to see if the /tmp filesystem has enough size to store the temporary files ##-- Get the filesystem name my $filesys=`/usr/bin/df -m /tmp | /usr/bin/grep -iv free | /usr/bin/awk '{print \$7}' 2>/dev/null`; chomp($filesys); ##-- Get the free space available in the filesystem my $freespace=`/usr/bin/df -m /tmp | /usr/bin/grep -iv free | /usr/bin/awk '{print \$3}' 2>/dev/null`; chomp($freespace); ##-- If the freespace is less than 60 MB, exit with the error msg in log file if( $freespace < 60 ) { `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: Filesystem -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; ##-- If free space in the filesystem is less than 60 MB, quit. WriteLog "Filesystem - Not Enough Free Space in FileSystem $filesys!\n"; Grace_Exit 1; } $count=2; $Machine_Name=""; $Partition_Name=""; $Interval=0; ##-- 24 hr * 60 min * 60 sec = 86400 sec for 24 hr $Schd_Inter = 86400; $lpar_type = ""; $lpar_mode = ""; $total = 0; @time; @procmode; @sharetype; @phypoolid; @logpoolid; @totphyproc; @totlogproc; @logtotcyc; @logusecyc; @phytotcyc; @phyusecyc; @cycpersec; ##-- Serial number of the machine my $Serial_Num=`/usr/bin/uname -u | /usr/bin/cut -d "," -f 2 | /usr/bin/sed 's/..//' 2>/dev/null`; chomp($Serial_Num); ##-- variables in temporary file to exchange values between parent and child process `echo "child:" > ${tmpfile}`; `echo "HmcVer:" >> ${tmpfile}`; `echo "HmcRel:" >> ${tmpfile}`; `echo "Machine:" >> ${tmpfile}`; `echo "AllowPerf:" >> ${tmpfile}`; ##-- Get partition name of the lpar $Partition_Name = `/usr/bin/lparstat -i | /usr/bin/grep "Partition Name" | /usr/bin/awk '{print \$4}' 2>/dev/null`; chomp($Partition_Name); ##-- Check for Hardware Power Porcessor my $Power = `/usr/sbin/prtconf | /usr/bin/grep "Processor Implementation Mode:" | /usr/bin/awk '{print \$5}' 2>/dev/null`; chomp($Power); ##-- If power processor is lower than Power 6, exit with error msg in the error log. if( $Power < 6 ) { `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: Hardware -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "Hardware - Need Power 6 or Higher Power Processor. Quitting!\n"; Grace_Exit 1; } ##-- To get the HMC name `/usr/bin/lsrsrc -l "IBM.MCP" 2>/dev/null | /usr/bin/grep MNName 2>/dev/null`; if( $? != 0 ) { ##-- If lpar is stand alone and not managed by HMC, quit with error msg `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: HMC Managed -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "HMC Managed - This Lpar ${Partition_Name} is Either not configured for RMC or is not managed by HMC!\n"; } ##-- Check if PM topasrec is enabled, if not, exit `/usr/bin/listtrec -P -l local_bin 2>/dev/null`; if( $? != 0 ) { ##-- If PM topasrec recording is not enabled, quit execution `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: Topas -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; ##-- If PM topasrec recording is not enabled, quit execution WriteLog "Topas - PM Recording is not enabled. Quitting!\n"; Grace_Exit 1; } ##-- Check if PM is enabled, if not enabled, exit the script `/usr/bin/grep "# Enabled" /var/perf/pm/config/pmconf 2>/dev/null`; if( $? != 0 ) { ##-- If PM Data Transmission is not enabled, quit execution `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: Performance Management -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "Performance Management - PM Data Transmission is not enabled, Quitting!\n"; Grace_Exit 1; } ##-- To check if lpar type is shared or dedicated and mode is capped or uncapped sub get_lpar_type { ##-- Get the processor type (Dedicated or Shared) of lpar from lparstat command output $lpar_type=`/usr/bin/lparstat -i | /usr/bin/grep -iw Type | /usr/bin/cut -d":" -f 2 | /usr/bin/cut -d"-" -f 1 2>/dev/null`; ##-- Get the processor mode (Capped or Uncapped) $lpar_mode=`/usr/bin/lparstat -i | /usr/bin/grep -iw "Mode" | /usr/bin/grep -v Memory | /usr/bin/grep -v Power | /usr/bin/cut -d":" -f 2 2>/dev/null`; chomp($lpar_type); chomp($lpar_mode); ##-- Removing unwanted space characters $lpar_type =~s/ +//g; $lpar_mode =~s/ +//g; ##-- If lpar is Dedicated, return to calling function with error code -1 if( $lpar_type =~ /Dedicated/ ) { `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: Partition Type -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "Partition Type - This Partition is of type $lpar_type. The Shared Processor Pool data can be collected only for Partitions of type Shared\n"; return -1; } return 0; } ##-- Check if Password-less ssh is setup from LPar to HMC sub check_lpar_ssh_to_hmc { ##-- Check password-less ssh connection to HMC `/usr/bin/ssh -o 'PreferredAuthentications=publickey' -o 'StrictHostKeyChecking=no' -l ${HMC_User} ${HMC_Name} echo 2>/dev/null`; ##-- If password-less ssh connection fails, return to calling function with code 1 if( $? != 0) { `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: HMC Login -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "HMC Login - Failed to login to HMC ${HMC_Name}. Password-Less SSH to HMC not setup!\n"; return -1; } ##-- If ssh connection passes, get HMC version $HmcVer = `/usr/bin/ssh -l $HMC_User $HMC_Name 'lshmc -V | grep Version | cut -d \":\" -f 2' 2>/dev/null`; chomp($HmcVer); $HmcVer =~s/"+//g; $HmcVer =~s/\s+//g; ##-- Get HMC release $HmcRel = `/usr/bin/ssh -l $HMC_User $HMC_Name 'lshmc -V | grep Release | cut -d \":\" -f 2' 2>/dev/null`; chomp($HmcRel); $HmcRel =~s/"+//g; $HmcRel =~s/\s+//g; my $HMC_FSM = `/usr/bin/ssh -l $HMC_User $HMC_Name 'lshmc -V | grep -i build | cut -d \" \" -f 1' 2>/dev/null`; chomp($HMC_FSM); if( $HMC_FSM =~ /HMC/ ) { ##-- Get first two values (x.x) of HMC release my $release = `echo $HmcRel | /usr/bin/awk -F \".\" '{print \$1 "." \$2}' 2>/dev/null`; ##-- Check if HMC version is below 7 and Release below 7.3, return to calling function with error code -1 if( $HmcVer < 7 || $release < 7.3 ) { `/usr/bin/sed "s/HMC_Supported:.*/HMC_Supported:0/" ${PMCONF} > ${tmpfile1}`; `/usr/bin/cp ${tmpfile1} ${PMCONF}`; `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: HMC Version -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "HMC Version - Current HMC version is $HmcVer, release $HmcRel, Required is version 7 and release 7.3.0 or above!\n"; return -1; } } ##-- Update config file pmconf if HMC is supported `/usr/bin/sed "s/HMC_Supported:.*/HMC_Supported:1/" ${PMCONF} > ${tmpfile1}`; `/usr/bin/cp ${tmpfile1} ${PMCONF}`; ##-- To get the machine names managed by HMC, filtering with the serial number $Machine_Name = `/usr/bin/ssh -l $HMC_User $HMC_Name 'lssyscfg -r sys -F name,serial_num | grep \"$Serial_Num\" | cut -d \",\" -f 1' 2>/dev/null`; chomp ( $Machine_Name); ##-- If machine name is not found, return to calling function with error code -1 if( $Machine_Name eq "" ) { ##-- If the machine name is blank, in case of lpar not belonging to this hmc `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: Machine Name -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "Machine Name - The HMC $HMC_Name does not have a machine name for this partition. Please check the HMC name!\n"; return -1; } ##-- Update the tmpfile with machine name to pass it from child process to parent process `/usr/bin/sed \"s/Machine:.*/Machine:${Machine_Name}/\" ${tmpfile} > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} ${tmpfile} 2>/dev/null`; ##-- Check if Allow Performance Collection is enabled for the partition $AllowPerf = `/usr/bin/ssh -l $HMC_User $HMC_Name 'lssyscfg -r lpar -m \"${Machine_Name}\" -F name,allow_perf_collection | grep -i ${Partition_Name} | cut -d \",\" -f 2' 2>/dev/null`; chomp($AllowPerf); ##-- If Allow Performance Collection is disabled, return to calling function with return code -1 if( $AllowPerf == 0 ) { `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: Allow Performance Collection -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "Allow Performance Collection - Partition not authorised to collect data. Quiting!!\n"; return -1; } return 0; } ##-- Check if HMC user name and HMC user id is updated in the pmconf file sub get_hmc_info { ##-- Call function get_lpar_type to get the partition type $retval = get_lpar_type; ##-- If return value of function get_lpar_type is not 0, return to calling function with error code -1 if( $retval != 0 ) { return -1; } ##-- Get HMC Name and HMC User name from config file pmconf $HMC_Name=`/usr/bin/grep Hmc_Name_PM ${PMCONF} | /usr/bin/cut -d ":" -f 2 2>/dev/null`; $HMC_User=`/usr/bin/grep Hmc_User_PM ${PMCONF} | /usr/bin/cut -d ":" -f 2 2>/dev/null`; chomp($HMC_Name); chomp($HMC_User); ##-- Validate HMC Name and HMC user name is not set to NULL in config pmconf file $valid_hmc = 0; $hmc_msg = ""; ##-- If HMC Name is NULL, set valid_hmc value to 1 if( $HMC_Name eq "" ) { $valid_hmc=1; $hmc_msg .= "HMC Name"; } ##-- If HMC Username is NULL, set valid_hmc value to 1 if( $HMC_User eq "" ) { if( $valid_hmc == 1 ) { $hmc_msg .= " and HMC User"; } else { $valid_hmc=1; $hmc_msg .= "HMC User"; } } ##-- If valid_hmc value is 1, means HMC Name or HMC Username is NULL, return to calling function with error code -1 if( $valid_hmc == 1 ) { `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: HMC Info Invalid -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "HMC Info Invalid - Hmc info is not valid. Please update ${PMCONF} with $hmc_msg\n"; return -1; } ##-- Check the ssh connection from partition to HMC $retval = check_lpar_ssh_to_hmc; ##-- If connection to HMC fails, return to calling function with code -1 if( $retval != 0 ) { return -1; } return 0; } ##-- Get the HMC Information $retval = get_hmc_info; ##-- If HMC Info function returns with error, grace exit if( $retval == -1 ) { Grace_Exit 1; } ##-- Set HMC Version and HMC release validating variables to 0 in the tmpfile, these values are read by child process my $HmcVer = 0; my $HmcRel = 0; `/usr/bin/sed \"s/HmcVer:.*/HmcVer:${HmcVer}/\" ${tmpfile} > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} ${tmpfile} 2>/dev/null`; `/usr/bin/sed \"s/HmcRel:.*/HmcRel:${HmcRel}/\" ${tmpfile} > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} ${tmpfile} 2>/dev/null`; ##-- Set child process return code to 0 in tmpfile my $inchild = 0; `/usr/bin/sed \"s/child:.*/child:${inchild}/\" ${tmpfile} > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} ${tmpfile} 2>/dev/null`; ##-- Convert the date format into seconds sub date_to_sec { my $date_time = shift; ##-- Split date and time my @tmp = split( / /, $date_time ); ##-- Split date and time again my @tmp = (split(/\//,$tmp[0]), split(/:/,$tmp[1])); my $year = $tmp[0]; my $mon = $tmp[1]; my $day = $tmp[2]; my $hr = $tmp[3]; my $min = $tmp[4]; my $sec = $tmp[5]; my $year_tmp = $year - 1970; use integer; ##-- Number of leap years since 1970 till $year my $leap = $year_tmp / 4; my $noleap = $year_tmp - $leap; ##-- Sum of number of days in non-leap years my $num_days1 = $noleap * 365; ##-- Sum of number of days in non-leap years my $num_days2 = $leap * 366; ##-- Sum of number of days in leap years and non-leap years my $days_in_years = $num_days1 + $num_days2; my $day_tmp = 0; ##-- Calculating the number of days from the begining of $year till $day ##-- For each month in a year for my $i ( 1,2,3,4,5,6,7,8,9,10,11,12 ) { ##-- Loop from first month 1 till the current month and add take sum of days in each month if( $i < $mon ) { use Switch; switch( $i ) { ##-- Jump here for the months which has 31 days case [1,3,5,7,8,10,12] { $day_tmp = $day_tmp + 31; } ##-- Jump here if it is second months case 2 { ##-- if $year is a leap year, $leapyr is 1, else 0 my $leapyr = $year % 4; if ( $leapyr == 0 ) { $day_tmp = $day_tmp + 29; } else { $day_tmp = $day_tmp + 28; } } ##-- Jump here for the months which has 30 days case [4,6,9,11] { $day_tmp = $day_tmp + 30; } } } } ##-- Sum of days in current month and total days in previous months $day_tmp = $day_tmp + $day; ##-- Sum of days in current year and total days in previous years $day_tmp = $day_tmp + $days_in_years - 1; ##-- Convert total days in hours my $hr_tmp = $day_tmp * 24; ##-- Add current hours to total hours from previous days $hr_tmp = $hr_tmp + $hr; ##-- Convert total hours to mins my $min_tmp = $hr_tmp * 60; ##-- Add current mins to total mins from previous mins $min_tmp = $min_tmp + $min; ##-- Convert total mins to seconds my $sec_tmp = $min_tmp * 60; ##-- Add current seconds to total seconds from previous seconds $sec_tmp = $sec_tmp + $sec; ##-- Return the date converted value in seconds return $sec_tmp; } sub time_difference { ##-- Get data in specific format from partition my $var = "/usr/bin/date +'%Y/%m/%d %T'"; my $localdat = `$var 2>/dev/null`; ##-- Get date in specific format from HMC my $hmcdat = `/usr/bin/ssh -l $HMC_User $HMC_Name \"date +'%Y/%m/%d %T'\" 2>/dev/null`; chomp($localdat); chomp($hmcdat); ##-- Convert local date to seconds my $localsec = date_to_sec ( $localdat ); ##-- Convert HMC date to seconds my $hmcsec = date_to_sec ( $hmcdat ); my $sign = ""; my $tmpsec = 0; ##-- If HMC time is greater than local time, difference is with negative sign if( $hmcsec > $localsec ) { $sign = "-"; $tmpsec = $hmcsec - $localsec; } else { $tmpsec = $localsec - $hmcsec; } my $difsec = 0; my $difmin = 0; my $difhr = 0; if( $tmpsec > 60 ) { $difsec = $tmpsec % 60; $tmpsec = $tmpsec - $difsec; if( $tmpsec > 60 ) { $tmpsec = $tmpsec / 60; $difmin = $tmpsec % 60; $tmpsec = $tmpsec - $difmin; $difhr = $tmpsec / 60 } else { $difmin = $tmpsec; } } else { $difsec = $tmpsec; } print TMPOUTFILE "Lpar date and time : $localdat\n"; print TMPOUTFILE "Hmc date and time : $hmcdat\n"; print TMPOUTFILE "Clock Offset : $sign$difhr:$difmin:$difsec\n\n"; } print TMPOUTFILE "\n"; #print TMPOUTFILE "#start_date_time,end_date_time,interval,mode,type,physical_pool_id,logical_pool_id,physical_cpu_in_pool,logical_cpu_in_pool,total_virtual_pool_cpu_time_millisec,busy_virtual_pool_cpu_time_millisec,total_physical_pool_cpu_time_millisec,busy_physical_pool_cpu_time_millisec\n"; my $curtime = time(); my $maxtime = $curtime + 30; my $toloop = 0; ##-- Create Child process my $pid = fork(); sleep 1; ##-- If child process fails, exit with error if (not defined $pid) { ##-- If child process failed to create, exit with error `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: Child Failed -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "Child Failed - Not enough resourse for child process!\n"; Grace_Exit 1; } elsif ($pid == 0) { ##-- If Child process created, check ssh connection from partition to HMC $inchild = check_lpar_ssh_to_hmc; ##-- Get the child exit status from tmpfile `/usr/bin/sed \"s/child:.*/child:${inchild}/\" ${tmpfile} > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} ${tmpfile} 2>/dev/null`; ##-- Set child exit status to 0 for new function call $inchild = 0; ##-- Update the tmpfile common to both child and parent process `/usr/bin/sed \"s/child:.*/child:${inchild}/\" ${tmpfile} > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} ${tmpfile} 2>/dev/null`; $inchild = time_difference; ##-- Get the child exit status from tmpfile `/usr/bin/sed \"s/child:.*/child:${inchild}/\" ${tmpfile} > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} ${tmpfile} 2>/dev/null`; ##-- Exit the child process exit(0); } else { ##-- Parent process running along with child process and monitoring the child to exit within time limit of 30 seconds, else kill the child process while( !$toloop ) { ##-- Get the child process exit status $inchild=`/usr/bin/cat ${tmpfile} | /usr/bin/grep child | /usr/bin/cut -d \":\" -f 2 2>/dev/null`; chomp($inchild); ##-- Get the current time $curtime = time(); ##-- If child process is complete, wait for the pid and set toloop to 1 to exit while loop if( $inchild == 1 ) { waitpid($pid,0); $toloop = 1; } elsif ( $maxtime < $curtime || $inchild == -1 ) { ##-- If child process is taking more than maxtime (30 seconds), kill the child process and exit with time out error $toloop = 1; kill 1, $pid; waitpid($pid,0); if( $maxtime < $curtime ) { `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: SSH To HMC -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "SSH To HMC - Timeout in checking for SSH connection to HMC ${HMC_Name} with user ${HMC_User}\n"; } Grace_Exit 1; } } } ##-- Function to analyse the HMC data sub AnalyseData { my @var1 = @{$_[0]}; $j = 0; for( $i=0; $i<$total; $i++ ) { if ( $j >= $count ) { $j = 0; } { use integer; $k = $i / $count; } use Switch; switch( $k ) { case 0 { my @values = split(",", $var1[$i]); $val = $values[0]; chomp($val); $time[$j] = $val; $val = $values[1]; chomp($val); $sharetype[$j] = $val; $val = $values[2]; chomp($val); $procmod[$j] = $val; $val = $values[4]; chomp($val); $totlogproc[$j] = $val; $phypoolid[$j]=0; } case 1 { my @values = split(",", $var1[$i]); $val = $values[1]; chomp($val); $phytotcyc[$j] = $val; $val = $values[2]; chomp($val); $phyusecyc[$j] = $val; } case 2 { if( $lpar_type =~ /Dedicated/ ) { $logpoolid[$j] = "NA"; $logtotcyc[$j] = "NA"; $logusecyc[$j] = "NA"; } else { my @values = split(",", $var1[$i]); $val = $values[1]; chomp($val); $logpoolid[$j] = $val; $val = $values[2]; chomp($val); $logtotcyc[$j] = $val; $val = $values[3]; chomp($val); $logusecyc[$j] = $val; } } case 3 { my @values = split(",", $var1[$i]); $val = $values[1]; chomp($val); $totphyproc[$j] = $val; $val = $values[2]; chomp($val); $cycpersec[$j] = $val; } } $j++; } } ##-- Function to get HMC data sub GetData { my $var = "/usr/bin/date +'%Y/%m/%d %T'"; my $localdat = `$var 2>/dev/null`; chomp($localdat); my @tmp = split( / /, $localdat ); my @tmp = (split(/\//,$tmp[0]), split(/:/,$tmp[1])); my $year = $tmp[0]; my $mon = $tmp[1]; my $day = $tmp[2]; my $prev_day = $day - 1; #my $Serial_Num=`/usr/bin/uname -u | /usr/bin/cut -d "," -f 2 | /usr/bin/sed 's/..//' 2>/dev/null`; #chomp($Serial_Num); #$Machine_Name = `/usr/bin/ssh -l $HMC_User $HMC_Name 'lssyscfg -r sys -F name | grep \"$Serial_Num\" | cut -d \",\" -f 1' 2>/dev/null`; #chomp ( $Machine_Name ); ##-- Get HMC name from tmpfile which is stored by the child process $Machine_Name=`/usr/bin/cat ${tmpfile} | /usr/bin/grep Machine: | /usr/bin/cut -d \":\" -f 2 2>/dev/null`; chomp ( $Machine_Name ); ##-- Get HMC sample rate interval my $Interval = `/usr/bin/ssh -l $HMC_User $HMC_Name 'lslparutil -r config -m \"${Machine_Name}\" -F sample_rate' 2>/dev/null`; chomp ( $Interval ); my $is_valid=1; my $msg = ""; if( $Interval =~ /^\d+\z/ ) { ##-- If interval is 0, HMC is not enabled to record server utilization statistics, if( $Interval == 0 ) { $is_valid = 0; $msg .= "Sampling Rate for the machine \"${Machine_Name}\" Interval is set to Disabled, Please enable the sampling rate in HMC going to Machine > Operations > Utilization Data > Change Sampling Rate -- "; } } else { ##-- Else if no interval set to record HMC utilization $is_valid = 0; if( $msg ne "" ) { $msg .= " and"; } $msg .= " HMC recording Interval is not set or not valid. HMC error msg: $Interval"; } ##-- If HMC is not enabled to record data utilization, exit return with error code -1 if( $is_valid != 1 ) { `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: Sample Rate -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "Sample Rate - Unable to continue: $msg\n"; return -1; } ##-- Total number of records = 24 hrs in seconds (86400 seconds) divided by HMC interval $count = $Schd_Inter / $Interval; if( $count <= 1 ) { $count = 2; } ##-- If partition is dedicated if( $lpar_type =~ /Dedicated/ ) { $procpool="lslparutil -m \"${Machine_Name}\" --filter \"event_types=sample\" -r procpool -F time,shared_proc_pool_id,total_pool_cycles,utilized_pool_cycles -n $count"; } else { ##-- If partition is shared ##-- Get the shared processor pool name ##-- With -F time, we need to use shared_proc_pool_name and without time field, its curr_shared_proc_pool_name $Pool_Name_cmd="'lslparutil -m \"${Machine_Name}\" --filter \"event_types=sample,lpar_names=$Partition_Name\" -r lpar -F curr_shared_proc_pool_name'"; $Pool_Name=`/usr/bin/ssh -l $HMC_User $HMC_Name $Pool_Name_cmd 2>/dev/null`; chomp($Pool_Name); ##-- If shared processor pool name not found, return to calling function with error code -1 if( $Pool_Name =~ /No results/ ) { `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: No Pool Info -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "No Pool Info - No results were found on hmc\n"; return -1; } ##-- If shared processor pool name is blank if($Pool_Name eq "") { ##-- If shared processor pool name is blank, get the shared processor pool data without pool name $procpool="lslparutil -m \"${Machine_Name}\" --filter \"event_types=sample\" -r procpool -F time,shared_proc_pool_id,total_pool_cycles,utilized_pool_cycles -n $count"; } else { ##-- Else, get the shared processor pool data from specific pool name $procpool="lslparutil -m \"${Machine_Name}\" --filter \"event_types=sample,pool_names=$Pool_Name\" -r procpool -F time,shared_proc_pool_id,total_pool_cycles,utilized_pool_cycles -n $count"; } } ##-- Complete command to be executed on HMC with one ssh call $fulcmd=</dev/null`; ##-- Get total number of lines in array of output $total=scalar(@mydata2); ##-- val = number of records per day multiplies with number of commands in fulcmd variable executed on HMC $val = $count * 4; ##-- If total number of lines in output array is not equal to expected value in val if ( $total != $val ) { chomp( $mydata2[0] ); if ( "$mydata2[0]" =~ /No results/ ) { ##-- If the HMC returned value has no proper data, update the error logs `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: HMC Data Not Found -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "HMC Data Not Found - No results were found on hmc\n"; } $val = $total / 4; ##-- Take the first line from the first command output my $firstval = $mydata2[0]; ##-- Split first line from first command output my @firstvals = split( ",", $mydata2[0] ); ##-- Split first line from second command output my @tmpvals = split( ",", $mydata2[$val]); chomp( $firstvals[0] ); chomp( $tmpvals[0] ); ##-- if the time values from first command and second command is equal if( $firstvals[0] eq $tmpvals[0] ) { $is_valid = 1; ##-- Split first line from third command output @tmpvals = split( ",", $mydata2[$val*2]); chomp( $tmpvals[0] ); ##-- Check time value from first command and third command is equal if( $firstvals[0] eq $tmpvals[0] ) { $is_valid = 1; ##-- Split first line from fourth command output @tmpvals = split( ",", $mydata2[$val*3]); chomp( $tmpvals[0] ); ##-- if the time values from first command and third command is equal if( $firstvals[0] eq $tmpvals[0] ) { $is_valid = 1; } else { $is_valid = 0; } } else { $is_valid = 0; } } else { $is_valid = 0; } ##-- If above checking is not matching, exit with error if( $is_valid != 1 ) { `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: Incorrect HMC Data -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "Incorrect HMC Data - OUTPUT CONTAINS INCORRECT HMC DATA TO ANALYSE\n"; return -1; } $count = $val; } ##-- Analyse the HMC output data AnalyseData ( \@mydata2 ); $n = $count - 1; ##--print "Start Time,End Time,Interval,procmod,sharetype,phypoolid,logpoolid,totphyproc,totlogproc,logtotcyc,logusecyc,phytotcyc,phyusecyc\n"; ##-- Formula to convert cycles to milli seconds ##-- Milli Seconds = (int) ((Val * 1000) / cycles_per_second) ##-- Where Val is the delta value of cycles recorded at two different intervals ##-- Val = Cycles_At_Current_Interval - Cycles_At_Previous_Interval for( $j=0; $j<$n; $j++ ) { ##-- Take delta value by substracting the two values of $val1 = $phytotcyc[$j] - $phytotcyc[$j+1]; $val2 = $phyusecyc[$j] - $phyusecyc[$j+1]; $val1 = $val1 * 1000; $val1 = int($val1 / $cycpersec[$j]); $val2 = $val2 * 1000; $val2 = int($val2 / $cycpersec[$j]); if( $lpar_type =~ /Dedicated/ ) { #if( $mode_status eq "ded" ) { $val3 = "NA"; $val4 = "NA"; } else { $val3 = $logtotcyc[$j] - $logtotcyc[$j+1]; $val4 = $logusecyc[$j] - $logusecyc[$j+1]; $val3 = $val3 * 1000; $val3 = int($val3 / $cycpersec[$j]); $val4 = $val4 * 1000; $val4 = int($val4 / $cycpersec[$j]); } print TMPOUTFILE "$time[$j+1], $time[$j], $Interval, $procmod[$j], $sharetype[$j], $phypoolid[$j], $logpoolid[$j], $totphyproc[$j], $totlogproc[$j], $val3, $val4, $val1, $val2\n"; } return 1; } ##-- Set child initial status to 0 $inchild = 0; ##-- Update the tmpfile with child initial status `/usr/bin/sed \"s/child:.*/child:${inchild}/\" ${tmpfile} > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} ${tmpfile} 2>/dev/null`; my $curtime = time(); ##-- Set the maximum time as 900 seconds limit for the child process to execute to get HMC data for shared processor pool utilization my $maxtime = $curtime + 900; $toloop = 0; ##-- Create child process my $pid1 = fork(); sleep 1; ##-- If child process fails to create, exit with error if (not defined $pid1) { `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: Child Failed -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "Child Failed - Not enough resourse for child process for Main!\n"; Grace_Exit 1; } elsif ($pid1 == 0) { ##-- Else if child process is created, call GetData function in child process $inchild = GetData; ##-- Update the child process return code in tmpfile to use it by parent process `/usr/bin/sed \"s/child:.*/child:${inchild}/\" ${tmpfile} > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} ${tmpfile} 2>/dev/null`; ##-- Exiting the child process exit(0); } else { ##-- In Parent process: loop until the child process exit or the maxtime limit while( !$toloop ) { ##-- Check child process status $inchild=`/usr/bin/cat ${tmpfile} | /usr/bin/grep child | /usr/bin/cut -d \":\" -f 2 2>/dev/null`; chomp($inchild); ##-- Get current time $curtime = time(); ##-- If child process has exited, set the loop variable to finish while loop if( $inchild ) { $toloop = 1; } elsif ( $maxtime < $curtime || $inchild == -1 ) { ##-- If child process is still running and maxtime is more than the limit, kill child process and exit with error $toloop = 1; kill 1, $pid1; ##-- If child process has exceeded time limit, update log file if( $maxtime < $curtime ) { `/usr/bin/cat $LOGFILE | /usr/bin/grep -v "$ScriptName: HMC Timedout -" > ${tmpfile1} 2>/dev/null`; `/usr/bin/cp ${tmpfile1} $LOGFILE 2>/dev/null`; WriteLog "HMC Timedout - Time out in collecting performance data from HMC ${HMC_Name}\n"; } Grace_Exit 1; } } } Grace_Exit 0;