#!/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 "</shrpool>\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 "<shrpool>\n";
	#print TMPOUTFILE "#<datacols>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</datacols>\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=<<EOF;
'lslparutil -m \"${Machine_Name}\" --filter \"event_types=sample,lpar_names=$Partition_Name\" -r lpar -F time,curr_proc_mode,curr_sharing_mode,curr_shared_proc_pool_name,curr_procs -n $count;
lslparutil -m \"${Machine_Name}\" --filter \"event_types=sample\" -r pool -F time,total_pool_cycles,utilized_pool_cycles -n $count;
$procpool;
lslparutil -m \"${Machine_Name}\" --filter \"event_types=sample\" -r sys -F time,configurable_sys_proc_units,proc_cycles_per_second -n $count';
EOF
		
		my @mydata2 = `/usr/bin/ssh -l $HMC_User $HMC_Name $fulcmd 2>/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;

	
