#! /bin/sh
# set -xv

#=========================================================================
# Copyright (C) VMware, Inc. 1986-2011.  All Rights Reserved..
#
# Name - conv62To2xForFastGc.sh
# Installed as - conv62To2xForFastGc
#
# Purpose - This script is used in step 6 below.  It converts a 6.2 
#           database to a GemStone/64 2.x database for the sole 
#           purpose of running a fast findDisconnectedObjects operation 
#           on it.  
#
#  *** Normal conversions should run conv62To2x instead of this one! ***
#
# Steps for converting for a GS64 fast FDC
#
#  1) File in $GEMSTONE_22/upgrade/preConvFor62Gc.topaz to the 6.x 
#     production database.  This must be done BEFORE making the copy for
#     the conversion and offline GC.  This step needs to be performed only
#     once on the 6.x production system.
#
#  2) Shutdown the 6.x production database and make a copy of the extents.
#
#  3) Start the copy of 6.x production using startstone.
#
#  4) Run $GEMSTONE_22/upgrade/convprepForGc6x on the copy.  This will
#     shutdown the database when finished.
#
#  5) Start a new 2.x stone with a large shared page cache and pregrow 
#     the extents .
#
#  6) run $GEMSTONE_22/bin/conv62To2xForFastGc to perform the low level 
#     conversion.  The new 2.x database will be shutdown automatically 
#     when this step is completed.
#
#  7) Restart the new 2.x stone using startstone
#
#  8) Run the $GEMSTONE_22/bin/startotcachewarmers script.  This will 
#     start object table cache warmer gems to load the object table into 
#     the shared page cache.
#
#  9) Run the $GEMSTONE_22/bin/startfastfdcto6xfile script to start 
#     the fast offline FDC.  This will produce a binary file containing
#     a list of dead objects found by the FDC.  The file will be in 
#     GemStone 6.x oop format.
#
# 10) Build the offline GC user action library in
#     $GEMSTONE_22/examples/offlinegc6x.  Only this version of the 
#     offline GC user action will work correctly with the file produced
#     in step 9.  Remember to set $GEMSTONE to reference your 6.x 
#     GemStone tree when compiling and linking.  If you cannot build
#     the user action library, contact GemStone support to obtain it.
#
# 11) Use the user action library built in step 10 to run the MGC on
#     the production database at a convenient time.  See documentation
#     in $GEMSTONE_22/examples/offlinegc6x for more details.
#
# $Id: conv62To2xForFastGc.sh,v 1.2 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="conv62To2xForFastGc"                 # 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>]
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 6.2.x 
        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)
EOF
}

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

#process command line
while getopts "e:hn:o:s:" opt; do
  case $opt in
    h ) usage; exit 0 ;;
    e ) oldSysConf=$OPTARG ;;
    n ) numConversionGems=$OPTARG ;;
    o ) oopsPerCommit=$OPTARG ;;
    s ) stoneName=$OPTARG ;;
   \? ) 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/from62_1.out ]; then
  if [ -r $upgradeLogDir/from62_2.out ]; then
    error "conv62To20 conversion step was alredy completed."
    exit 1
  else
    error "previous upgrade step convprep62 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 390 > $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/from62_1.out >/dev/null 2>&1
  touch $upgradeLogDir/from62_2.out
  info "Successful conversion."
  exit 0
fi

