#! /bin/sh
# set -xv
#=========================================================================
# Copyright (C) VMware, Inc. 1986-2011.  All Rights Reserved..
#
# Name - conv2gTo2x.sh
# Installed as - conv2gTo2x
#
# Purpose -
#
# This script is executed as step 7 of GemStone/S 2G to Gemstone 64 v2.x
# conversion as outlined below
# It is run with a running 2.x stone which has been started
# with a virgin extent0.dbf and a config file specifying all extents needed
# for the converted 2.x system. This script does the following steps:
#  1. destroy object table
#  2. launch 1-n conversion gems
#  3. wait for conversion to complete and shut down stone
#
# CUSTOMER UPGRADE PROCEDURE
#   Please refer to the GemStone/S 64 Bit 2.x Installation Guide for detailed
#   Instructions.
# STAGE 1:
# 1. maintain your 2G environment, e.g. GEMSTONE. DO NOT set GEMSTONE to
#    the 2.x product yet!
# 2. login to 2G stone, stop all other user sessions, and set SystemUser
#    password to 'swordfish'.
# 3. set environment variable upgradeLogDir to a writable directory
# 4. run the script convprep2g.  This script is found in the 2.x product tree, in
#    the upgrade directory.  This file should not be in your path, so it will need
#    to be invoked with an explicit path.
# STAGE 2:
# 5. set up your environment ($GEMSTONE) for the 2.x product tree. Maintain
#    your GS 2G extents; they will be read from during stage 2. The environment
#    variable upgradeLogDir must remain the same for stage 2 as it was for
#    stage 1.
# 6. start a 2.x gemstone with a virgin extent0.dbf and a config file specifying
#    all extents required for your 2.x system. Extent pregrow is recommended.
# 7. run the script conv2gTo2x. This script exists in the 2.x product tree
#    under the bin directory, so it needn't be called with an explicit path
# 8. wait for conv2gTo2x to exit.
# 9. restart the 2.x stone
# 10. run the script upgradeImageFrom2g. This script exists in the 2.x product
#     tree under the bin directory, so it needn't be called with an explicit
#     path.
# 11. run the script postconv. This script exists in the 2.x product tree under
#     the bin directory, so it needn't be called with an explicit path.
#
# $Id: conv2gTo2x.sh,v 1.6 2008-01-09 22:50:52 stever Exp $
#=========================================================================

if [ "a$GEMSTONE" = "a" ]; then
  echo "ERROR: GemStone scripts require a GEMSTONE environment variable."
  echo "       Please set it to the directory where GemStone resides."
  exit 1
fi

# maintenance symbols
comid="conv2gTo2x"                 # this script's name

# make sure of a minimum path
PATH=:/bin:/usr/bin:/usr/ucb:$PATH; export PATH

. $GEMSTONE/bin/misc.sh

defaultErrorControl

info() {
  echo $comid[INFO]: $*
}
error() {
  echo $comid[ERROR]: $*
}
usage() {
  cat <<EOF
Usage:
$comid -e <oldSysConf> [-h][-s <stoneName>][-n <numConversionGems>]
       [-o <oopsPerCommit>][-L]
Environment requirements:
    GEMSTONE          set to a 2.x GemStone/S 64 Bit product tree
    upgradeLogDir     set to a writable directory used in previous steps
Parameters:
    -e <oldSysConf>
        where <oldSysConf> is a config file containing the list of 2G 
        extents to read data from (required, no default)
    -h print this Usage and exit
    -s <stoneName>
        where <stoneName> is the name of a running 2.x stone, started with
        empty extents (default: gs64stone)
    -n <numConversionGems>
        where <numConversionGems> is the number of parallel gems that will
        do the conversion (default: 1)
    -o <oopsPerCommit>
        where <oopsPerCommit> is the number of oops per transaction
        (default: 1000000)
    -L During conversion, determine which objects reference one or more 
       instances of LargePositiveInteger or LargeNegativeInteger and write
       the object IDs to the binary bitmap file: $upgradeLogDir/AllLrgIntRefs.bm
EOF
}

# defaults
numConversionGems=1
oopsPerCommit=1000000
stoneName=gs64stone
listLrgObjRefs=0
listFloatRefs=0

#process command line
while getopts "e:hLn:o:s:" opt; do
  case $opt in
    h ) usage; exit 0 ;;
    e ) oldSysConf=$OPTARG ;;
    n ) numConversionGems=$OPTARG ;;
    o ) oopsPerCommit=$OPTARG ;;
    s ) stoneName=$OPTARG ;;
    L ) listLrgObjRefs=1 ;;
   \? ) error "bad arg: $opt"; usage; exit 1 ;;
  esac
done

# check oldSysConf
if [ "a$oldSysConf" = "a" ]; then
  error "no value specified for -e <oldSysConf>"
  usage
  exit 1
fi
if [ ! -f $oldSysConf ]; then
  error "$oldSysConf does not exist"
  exit 1
fi
GEMSTONE_SYS_CONF=$oldSysConf
export GEMSTONE_SYS_CONF

rm /tmp/extentTst.out >/dev/null 2>&1
$GEMSTONE/upgrade/extents.pl >/tmp/extentTst.out
hasDollarGemStone=`grep -c '\$GEMSTONE'  /tmp/extentTst.out`
rm /tmp/extentTst.out >/dev/null 2>&1

if [ $hasDollarGemStone -gt 0 ]; then
  error "Old config file $oldSysConf specifies paths to old extents using \$GEMSTONE"
  exit 1
fi

extents=`$GEMSTONE/upgrade/extents.pl`
if [ "a$extents" = "a" ]; then
  error "$oldSysConf does not appear to list any extents"
  exit 1
fi
 
# make sure $upgradeLogDir has been set
info "verifying upgradeLogDir..."
if [ a$upgradeLogDir = "a" ]; then
  error "The environment variable upgradeLogDir has not been set."
  usage
  exit 1
elif [ ! -d $upgradeLogDir ]; then
  error "upgradeLogDir $upgradeLogDir is not a directory."
  usage
  exit 1
fi
info "...found upgradeLogDir..."

# make sure $upgradeLogDir is writable
touch $upgradeLogDir/tmp$$ 2>/dev/null 
if [ "$?" != "0" ]; then
  error "$upgradeLogDir is not writable."
  usage
  exit 1
fi
rm $upgradeLogDir/tmp$$
info "...upgradeLogDir is writable."

if [ ! -r $upgradeLogDir/from2g_1.out ]; then
  if [ -r $upgradeLogDir/from2g_2.out ]; then
    error "conv2gTo2x conversion step was alredy completed."
    exit 1
  else
    error "previous upgrade step convprep2g was not completed successfully."
    exit 1
  fi
fi

# make sure stone is running
info "verifying $stoneName is running..."
$GEMSTONE/bin/waitstone $stoneName -1 > /dev/null 2>&1
status=$?
if [ $status -ne 0 ]; then
  error "...no stone named $stoneName found"
  usage
  exit $status
fi
info "...$stoneName is running."
stonePid=`$GEMSTONE/bin/gslist -x $stoneName | grep pid | cut -f 2 -d '='`

nukeOt(){
$GEMSTONE/bin/topaz -l -i << EOF
set gemstone $stoneName
set u SystemUser p swordfish
login

run
System _zeroArgPrim: 666
%
exit 0
EOF
}

count=1
delayTime=1
gemNum=0

rm  $upgradeLogDir/nukeOt.log > /dev/null 2>&1
rm $upgradeLogDir/convertgem* gem*.log > /dev/null 2>&1

info "Destroying the old object table..."
nukeOt > $upgradeLogDir/nukeOt.log 2>&1 
status=$?
if [ $status -eq 0 ]; then
  info "...successfully completed destroying the old OT"
else
  error "...OT nuking failed"
  exit 1
fi

info "Spawning $numConversionGems conversion gems..."
while [ $count -le $numConversionGems ]; do
  #							 fix 35196
  thisLogFile=$upgradeLogDir/convertGem-$gemNum.log
  logFiles="$thisLogFile $logFiles"
  echo loginForConversion $gemNum $numConversionGems \'$stoneName\' 128 \'$upgradeLogDir\' $oopsPerCommit $listLrgObjRefs $listFloatRefs 17 > $upgradeLogDir/convertgem$gemNum
  for extent in $extents; do
    echo openConversionExtent \'$extent\' >> $upgradeLogDir/convertgem$gemNum
  done
  echo startConversion >> $upgradeLogDir/convertgem$gemNum
  $GEMSTONE/sys/geml < $upgradeLogDir/convertgem$gemNum > $thisLogFile 2>&1 &
  thisPid=$!
  pids="$thisPid $pids"
  info "Starting conversion gem # $gemNum ($count of $numConversionGems)"
  info "This gem's process id: $thisPid"

  if [ $count -lt $numConversionGems ]; then
    sleep $delayTime
  else
    info "Finished spawning $count conversion gems."
  fi

  count=`expr $count + 1`
  gemNum=`expr $gemNum + 1`
done


info "waiting for processes with the following IDs to exit:"
info $pids
wait $pids $stonePid

# check gem logs for success message
errorsFound=0
for log in $logFiles; do
  grep "Successfully completed repository conversion" $log > /dev/null 2>&1
  status=$?
  if [ $status -ne 0 ]; then
    error "conversion failure found. Check log $log"
    errorsFound=1
  fi
done
 
if [ $errorsFound -ne 0 ]; then
  error "Errors found in conversion. Check logs listed above." 
  exit 1
else
  rm $upgradeLogDir/from2g_1.out >/dev/null 2>&1
  touch $upgradeLogDir/from2g_2.out
  info "Successful conversion."
  exit 0
fi

