#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos720 src/bos/diag/sysx/hxemem/hxemem.setup.sh 1.5 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 1998,2006 
# 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 
# @(#)09        1.5  src/bos/diag/sysx/hxemem/hxemem.setup.sh, dsysx, bos720 9/27/06 10:26:34
# Input parameters:
# $1 = cycle count (1 or 0)
# $2 = data equals address test (1 or 0)
# $3 = memory to memory test (1 or 0)
# $4 = disk to memory test (1 or 0)
#
# Return Codes:
# 0 - Successful
# 1 - /bin/vmstat does not exist, put out message and terminate.
# 2 - Not enough paging space to exercise all the memory.
#######################################################
# create mdt stanza for each processor
#######################################################
function create_mdt {
ARCH32_64=`/usr/sbin/bootinfo -y`
N=0
MDT="sysx.mdt"
/usr/bin/cat $SYSXPATH/mdt.default > $DIAGDATA/$MDT
while (( N < NUM_PROCESSORS ))
do
  echo "mem$N:" >> $DIAGDATA/$MDT
  if [[ $ARCH32_64 = 32 ]]
  then
    echo "HE_name = \"hxemem32\"" >> $DIAGDATA/$MDT
  else
    echo "HE_name = \"hxemem64\"" >> $DIAGDATA/$MDT
  fi
  echo "description = \"memory\"" >> $DIAGDATA/$MDT
  echo "reg_rules = \"sysx.rule.hxemem\"" >> $DIAGDATA/$MDT
  echo "emc_rules = \"sysx.rule.hxemem\"" >> $DIAGDATA/$MDT
  echo "max_cycles = \"$MAX_CYCLES\"" >> $DIAGDATA/$MDT
  echo "" >> $DIAGDATA/$MDT
  ((N=N+1))
done
} # end create_mdt

######################################################################
# Determine number and size of shared memory segments for rules file
######################################################################
function calc_shm_segs {
PAGE_SIZE=4096
KB_MEMORY=`/usr/sbin/bootinfo -r`
MB_DISK=`/usr/sbin/lsps -s | /usr/bin/grep MB | /usr/bin/sed 's/MB/  /' | /usr/bin/cut -d" " -f1-18`
let KB_DISK=MB_DISK*1024
let LIMIT=KB_MEMORY+KB_MEMORY/2 # KB_MEMORY*1.5
FREE_PAGES_MEMORY=`/usr/bin/vmstat|/usr/bin/awk 'NR==4 {print $4}'`
if ((KB_DISK < LIMIT))
then
  let EXTRA=LIMIT-KB_DISK
  /usr/bin/cat >&2 <<EOT2
System has $KB_DISK kbytes of disk paging space
and $KB_MEMORY kbytes of memory.

Disk paging space should be at least 1.5 times
the system memory. i.e. a system with 32 meg
of memory should have 48 meg of paging space.

Increase paging space by $EXTRA kbytes using
\"smit lvm\" or not all the memory will be
exercised.
EOT2
  RETURN_CODE=2
  # Limit memory usage to 50% of the available paging space
  # MAX_FREE_PAGES_MEMORY = KB_DISK*1024/4096/2
  let MAX_FREE_PAGES_MEMORY=KB_DISK/8
  if ((MAX_FREE_PAGES_MEMORY < FREE_PAGES_MEMORY))
  then
    let FREE_PAGES_MEMORY=MAX_FREE_PAGES_MEMORY
  fi
fi

let MEMORY_PER_PROCESSOR=FREE_PAGES_MEMORY/NUM_PROCESSORS

let NUM_SEG=1
let SEG_SIZE=MEMORY_PER_PROCESSOR*PAGE_SIZE
while ((SEG_SIZE > 268435456))
do
let NUM_SEG=NUM_SEG+1
let SEG_SIZE=SEG_SIZE-268435456
done
let SEG_SIZE=MEMORY_PER_PROCESSOR/NUM_SEG*PAGE_SIZE
let WORK1=MEMORY_PER_PROCESSOR*PAGE_SIZE
let WORK2=NUM_SEG*SEG_SIZE
while ((WORK2 < WORK1))
do
let SEG_SIZE=SEG_SIZE+1
let WORK2=WORK2+NUM_SEG
done
} # end calc_shm_segs
function create_rules_file {
# create stanza to allocate shared memory segments
MEM_RULE="sysx.rule.hxemem"
echo "RULE_ID = ALLOCATE"   >  $DIAGDATA/$MEM_RULE
echo "OPER = ALLOCATE"      >> $DIAGDATA/$MEM_RULE
echo "NUM_SEG = $NUM_SEG"   >> $DIAGDATA/$MEM_RULE
echo "SEG_SIZE = $SEG_SIZE" >> $DIAGDATA/$MEM_RULE
echo ""                     >> $DIAGDATA/$MEM_RULE
# create stanzas to exercise memory
if ((DATA_EQUALS_ADDRESS==1))
then
  echo "RULE_ID = ADDRESS"  >> $DIAGDATA/$MEM_RULE
  echo "OPER = ADDRESS"     >> $DIAGDATA/$MEM_RULE
  echo ""                   >> $DIAGDATA/$MEM_RULE
fi

if ((MEMORY_TO_MEMORY==1))
then
  echo "RULE_ID = MEM_55"   >> $DIAGDATA/$MEM_RULE
  echo "OPER = MEMORY"      >> $DIAGDATA/$MEM_RULE
  echo "BIT_PATTERN = 55"   >> $DIAGDATA/$MEM_RULE
  echo ""                   >> $DIAGDATA/$MEM_RULE

  echo "RULE_ID = MEM_AA"   >> $DIAGDATA/$MEM_RULE
  echo "OPER = MEMORY"      >> $DIAGDATA/$MEM_RULE
  echo "BIT_PATTERN = AA"   >> $DIAGDATA/$MEM_RULE
  echo ""                   >> $DIAGDATA/$MEM_RULE
fi

if ((DISK_TO_MEMORY==1))
then
  echo "RULE_ID = DISK_55"  >> $DIAGDATA/$MEM_RULE
  echo "OPER = DISK"        >> $DIAGDATA/$MEM_RULE
  echo "BIT_PATTERN = 55"   >> $DIAGDATA/$MEM_RULE
  echo ""                   >> $DIAGDATA/$MEM_RULE

  echo "RULE_ID = DISK_AA"  >> $DIAGDATA/$MEM_RULE
  echo "OPER = DISK"        >> $DIAGDATA/$MEM_RULE
  echo "BIT_PATTERN = AA"   >> $DIAGDATA/$MEM_RULE
  echo ""                   >> $DIAGDATA/$MEM_RULE
fi
# create stanza to release shared memory segments
echo "RULE_ID = RELEASE"    >> $DIAGDATA/$MEM_RULE
echo "OPER = RELEASE"       >> $DIAGDATA/$MEM_RULE
echo ""                     >> $DIAGDATA/$MEM_RULE
} # end create_rules_file
##############################################################
# main
##############################################################
RETURN_CODE=0
[ ! -f /usr/bin/vmstat ] &&
{
/usr/bin/cat >&2 <<EOT1
The \"bos.acct\" fileset must be installed in
order to run the Memory Exerciser.
Press \"enter\" to return to the Task
Selection Menu.
EOT1
RETURN_CODE=1
exit $RETURN_CODE
}

[ "X$SYSXPATH" = X ] && SYSXPATH=/usr/lpp/diagnostics/sysx/
[ "X$DIAGDATA" = X ] && DIAGDATA=/etc/lpp/diagnostics/data/
NUM_PROCESSORS=`/usr/sbin/lsdev -C -cprocessor -Sa | /usr/bin/wc -l`
if (($#==0))
then
  MAX_CYCLES=0
  DATA_EQUALS_ADDRESS=1
  MEMORY_TO_MEMORY=0
  DISK_TO_MEMORY=0
else
  MAX_CYCLES=$1
  DATA_EQUALS_ADDRESS=$2
  MEMORY_TO_MEMORY=$3
  DISK_TO_MEMORY=$4
fi
create_mdt
calc_shm_segs
create_rules_file
exit $RETURN_CODE
