branchsubmit.sh #4

  • //
  • guest/
  • robert_cowham/
  • perforce/
  • utils/
  • benchmark/
  • p4/
  • branchsubmit.sh
  • View
  • Commits
  • Open Download .zip Download (22 KB)
#!/bin/sh

# Copyright (c) 2018, Perforce Software, Inc.  All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

RCSCHANGE="$Change: 1740258 $"
RCSDATE="$Date: 2018/12/11 $"

awk=awk
cut=cut
date=date
echo=echo
exit=exit
expr=expr
grep=grep
head=head
mkdir=mkdir
mv=mv
p4=p4
p4d=p4d
printf=printf
ps=ps
pwd=pwd
rm=rm
sed=sed
sh=sh
sleep=sleep
tail=tail
touch=touch
tr=tr
uname=uname
wc=wc

BENCHMARK=`$echo $0 | $sed 's/^.*\/\([^\/]*\)$/\1/' | $sed 's/^\(.*\)\.sh$/\1/'`

# Allow single environment var to specify root, with pwd as default.
# Other dirs are relative to this root dir.
# The sub-directories that must exist prior to running
# are ./bin and ./ckps - other subdirs are created as required.

BENCHROOT=${BENCHROOT:-`pwd`}
cd $BENCHROOT
p4=$BENCHROOT/bin/p4
p4d=$BENCHROOT/bin/p4d
# Make p4d distinct so that we can test for it via ps etc and not worry about others on the same server
if [ -L $BENCHROOT/bin/p4d-$BENCHMARK ]; then
    rm $BENCHROOT/bin/p4d-$BENCHMARK
fi
ln -s $BENCHROOT/bin/p4d $BENCHROOT/bin/p4d-$BENCHMARK
p4d=$BENCHROOT/bin/p4d-$BENCHMARK

BRANCHCMDS="integrate -v //depot/main/0... //depot/r36.0.0/0..."

DATETIME=`$date +%Y%m%d%H%M%S`

P4CLIENT=$BENCHMARK-client; export P4CLIENT
P4CLIENTdir=$BENCHROOT/clients/$BENCHMARK/$P4CLIENT

P4PORT=127.0.0.1:31696; export P4PORT	# must NOT be an existing server!

P4ROOT=$BENCHROOT/root/$BENCHMARK		# must NOT be an existing installation!

P4JOURNALdir=$BENCHROOT/journals/$BENCHMARK
P4JOURNAL=$P4JOURNALdir/journal		# must NOT be an existing journal!

P4LOGdir=$BENCHROOT/logs/$BENCHMARK
P4LOG=$P4LOGdir/log

P4USER=$USER; export P4USER

YAMLFILE=$BENCHMARK.$DATETIME.yml
YAMLINDENT="    "

ZCKP=$BENCHROOT/ckps/reference01.2018.2.ckp.gz

function bail() { echo -e "(line: ${BASH_LINENO[0]}) ${1:-Unknown Error}\n" >&2; exit ${2:-1}; }

[[ -e $p4d ]] || bail "p4d binary does not exist: $p4d"
[[ -e $ZCKP ]] || bail "Checkpoint $ZCKP not found - please download"

#
# If the machine on which this benchmark is being executed has the
# excess CPU capacity to handle a hard loop without adversely affecting
# the results, and "date +%N" returns nanoseconds on the platform, then
# toggling the guard below might result in more accurate measurements.
#
if [ 0 -eq 1 ]
then
	granularity=centiseconds
else
	granularity=seconds
fi

args=$*
if [ "$args" = "" ]
then
	#
	# No arguments provided; use default.
	#
	args="setup runme runme cleanup"
fi

printf2()
{
	#
	# printf to file descriptor 2.
	#
	$printf "$@" >&2
}

nop4ds()
{
	#
	# Since ps is used to determine when the server has completely
	# stopped, ensure that ps does not show any related p4d processes.
	#
	if $ps a | $grep p4d-$BENCHMARK | $grep -v $grep
	then
	    printf2 "ps shows related p4d processes.\n"
	    printf2 "The above p4d processes must be stopped.\n"

	    $exit 1
	fi
}

getrcsvalue()
{
	#
	# Return an RCS value from a string. The RCS value is the
	# substring between the first and last space characters.
	#
	$echo $1 | $sed 's/^[^ ]* \(.*\) [^ ]*$/\1/'
}

createyamlfile()
{
	$touch $YAMLFILE
}

writeyamlfile()
{
	#
	# Indent the number of YAML levels desired.
	#
	i=$1
	while [ $i -ne 0 ]
	do
	    $printf "$YAMLINDENT" >> $YAMLFILE
	    i=`$expr $i - 1`
	done

	#
	# Write the desired text.
	#
	shift 1
	$printf "%s\n" "`$echo $*`" >> $YAMLFILE
}

absfilepath()
{
	raw="$@"
	if [ `$echo "$raw" | $cut -b1` != "/" ]
	then
	    #
	    # Raw filepath is relative to the current working directory;
	    # prepend the current working directory to the raw filepath.
	    #
	    raw="`$pwd`/$raw"
	fi

	#
	# Build the absolute filepath by evaluating each element.
	#
	abs=""
	while [ "$raw" != "" ]
	do
	    elem=`$echo "$raw" | $sed 's/^\(\/[^\/]*\).*$/\1/'`	# element
	    raw=`$echo "$raw" | $sed 's/^\/[^\/]*\(.*\)$/\1/'`	# remainder

	    if [ "$elem" = "/.." ]
	    then
		#
		# Back up one element.
		#
		abs=`$echo "$abs" | $sed 's/^\(.*\)\/[^/]*$/\1/'`

	    elif [ \( "$elem" != "/" -o "$raw" = "" \) -a "$elem" != "/." ]
	    then
		#
		# Element is not a single "/" (or it is a trailing "/", which
		# is allowed) and it's not a trivial "." path element;
		# append it to the absolute filepath being built.
		#
		abs="$abs$elem"

	    fi
	done

	$echo "$abs"
}

getos()
{
	#
	# Set the OS variable, and for interesting OS,
	# set the OSVER variable.
	#
	OS=`$uname -s | $tr \[:lower:\] \[:upper:\]`
	case $OS in
	CYGWIN*)
	    OS=CYGWIN
	    ;;
	FREEBSD)
	    OSVER=`$uname -r | $cut -b1,3`
	    case $OSVER in
	    4?)
		OSVER=4
		;;
	    esac
	    ;;
	LINUX)
	    OSVER=`$uname -r | $cut -b1,3`
	    ;;
	MINGW*)
	    OS=MINGW
	    ;;
	SUNOS)
	    OS=SOLARIS
	    OSVER=`$uname -r | $cut -b3-`
	    case OSVER in
	    5)
		OSVER=25
		;;
	    6)
		OSVER=26
		;;
	    7)
		OSVER=27
		;;
	    esac
	    ;;
	WINDOWSNT)
	    OS=NT
	    ;;
	esac

	#
	# Set the OSPLAT variable.
	#
	if [ $OS != "NT" ]
	then
	    OSPLAT=`$uname -p 2> /dev/null`
	    if [ -z $OSPLAT ]
	    then
		OSPLAT=`$uname -m 2> /dev/null`
	    fi
	    OSPLAT=`$echo $OSPLAT | $tr \[:lower:\] \[:upper:\]`
	    case $OSPLAT in
	    I?86)
		case $OS$OSVER in
		SOLARIS10)
		    if [ `/usr/bin/isainfo -b` = "64" ]
		    then
			OSPLAT=X86_64
		    fi
		    ;;
		*)
		    OSPLAT=X86
		    ;;
		esac
		;;
	    UNKNOWN)
		case $OS in
		CYGWIN)
		    OSPLAT=X86
		    ;;
		MINGW)
		    OSPLAT=X86
		    ;;
		esac
		;;
	    esac
	fi

	#
	# Set the OSINFO variable.
	#
	OSINFO=$OS$OSVER$OSPLAT
}

computeseconds()
{
	#
	# Compute and return the number of seconds from an "hhmmss" string.
	#
	tmp=`$echo $1 | $cut -b1-2`
	tmp=`$expr \`$expr $tmp \* 60\` + \`$echo $1 | $cut -b3-4\``
	$expr `$expr $tmp \* 60` + `$echo $1 | $cut -b5-6`
}

getseconds()
{
	#
	# Compute and return the number of seconds since midnight.
	#
	computeseconds `$date +%H%M%S`
}

getcentiseconds()
{
	#
	# Compute and return the number of centiseconds since midnight.
	# Centiseconds are rounded from milliseconds.
	#
	raw=`$date +%H%M%S%N`
	tmp=`computeseconds $raw`
	tmp=`$expr \`$expr $tmp \* 1000\` + \`$echo $raw | $cut -b7-9\``
	$expr `$expr $tmp + 5` / 10
}

getelapsed()
{
	#
	# Compute and return the elapsed time (in seconds or centiseconds)
	# between the starting number of seconds or centiseconds since
	# midnight, passed as an argument, and the ending number of
	# seconds or centiseconds since midnight, which is either
	# passed as an argument or computed as of now. The longest
	# elapsed time that can be correctly computed is 86,399 seconds or
	# 8,639,999 centiseconds (one second or centisecond short of 24 hours).
	#

	if [ $3 ]
	then
	    #
	    # Use the provided ending number of seconds or centiseconds
	    # since midnight.
	    #
	    end=$3
	else
	    #
	    # Get the number of seconds or centiseconds
	    # since midnight as of now.
	    #
	    end=`get$1`
	fi

	if [ $end -lt $2 ]
	then
	    #
	    # Start time was sometime yesterday; adjust for it.
	    #
	    if [ $1 = "seconds" ]
	    then
		end=`$expr $end + 86400`
	    else
		end=`$expr $end + 8640000`
	    fi
	fi

	#
	# Return the elapsed time.
	#
	$expr $end - $2
}

hundredths()
{
	#
	# Format centiseconds into seconds and hundredths of seconds.
	#
	$printf %d.%02d `$expr $1 / 100` `$expr $1 % 100`
}

waitlistener()
{
	#
	# Wait until the parent p4d process is listening by
	# periodically attempting a "p4 info" command.
	#
	until $p4 info > /dev/null 2>&1
	do
	    $sleep 1
	done
}

waitchildren()
{
	#
	# Wait for all the server's child processes to exit by
	# periodically checking for a single p4d process. The
	# remaining p4d process is the server parent process.
	#
	while [ `$ps a | $grep p4d-$BENCHMARK | $grep -v $grep | $wc -l` -gt 1 ]
	do
	    if [ $granularity = "seconds" ]
	    then
		$sleep 1
	    fi
	done
}

waitstopped()
{
	#
	# Wait for the server to completely stop by
	# periodically checking for related p4d processes.
	#
	while $ps a | $grep p4d-$BENCHMARK | $grep -v $grep > /dev/null
	do
	    $sleep 1
	done
}

run()
{
	#
	# Start the server and wait for it to listen and quiesce.
	#
	$start $p4d -d -p $P4PORT -r $P4ROOT -J $P4JOURNAL \
	    -q -L $P4LOG -v server=3 -v track=1
	waitlistener
	printf2 " sleeping..."
	$sleep 10

	#
	# Run the command, computing the elapsed time and the amount of time
	# to completely terminate the command after releasing the client
	# (which is useful in determining the fsync() time).
	#
	printf2 " executing..."
	begin=`get$granularity`
	$sh -c "$*"
	released=`get$granularity`
	waitchildren
	exited=`get$granularity`
	elapsed=`getelapsed $granularity $begin $exited`
	exiting=`getelapsed $granularity $released $exited`

	#
	# Stop the server and wait for it to quiesce.
	#
	$p4 admin stop
	waitstopped
	printf2 " sleeping..."
	$sleep 10
}

extractlog()
{
	#
	# Find the last occurrence of the desired operation in the server log.
	#
	off=`$grep -n "$1" "$2" \
	    | $tail -1 \
	    | $sed 's/^\([0-9]*\):.*$/\1/'`

	#
	# Extract through the end of the tracking information
	# for this occurrence.
	#
	$sed -n "$off,\$p" "$2" \
	    | $awk 'BEGIN { p = 1 } /^$/ { p = 0 } { if( p ) print $0 }' > $3
}

gettable()
{
	#
	# Find the tracking information for the desired table
	# in the extract from the server log.
	#
	off=`$grep -n "^\-\-\- $2$" $1 \
	    | $sed 's/^\([0-9]*\):.*$/\1/'`
	off2=`$sed -n "\`$expr $off + 1\`,\\$p" $1 \
	    | $grep -n "^\-\-\- db\..*$" \
	    | $head -1 \
	    | $sed 's/^\([0-9]*\):.*$/\1/'`
	if [ "$off2" != "" ]
	then
	    #
	    # The start of the tracking information for the next table
	    # was found; the end of the tracking information for the
	    # desired table is one line prior.
	    #
	    off2=`$expr \`$expr $off + $off2\` - 1`
	else
	    #
	    # The start of the tracking information for the next table
	    # was not found; the end of the tracking information for the
	    # desired table is the end of the extract from the server log.
	    #
	    off2=\$
	fi

	#
	# Extract the tracking information for the desired table.
	#
	$sed -n "${off},${off2}p" $1 > $3
}

getheld()
{
	#
	# Extract the line containing the desired held time.
	#
	if [ $2 != "peek" ]
	then
	    line=`$grep "^\-\-\-   [total ]*lock[s]* wait+held read/write " $1`
	else
	    line=`$grep "^\-\-\-   peek count [0-9]* wait+held total/max " $1`
	fi

	if [ "$line" = "" ]
	then
	    #
	    # The line containing the desired held time is not present;
	    # return nothing.
	    #
	    return
	fi

	if [ $2 = "read" ]
	then
	    #
	    # Caller requested the read lock held time; return it.
	    #
	    $echo "$line" \
		| $sed 's/^\-\-\-   [total ]*lock[s]* wait+held read\/write [0-9]*ms+\([0-9]*\)ms\/[0-9]*ms+[0-9]*ms.*$/\1/'

	elif [ $2 = "write" ]
	then
	    #
	    # Caller requested the write lock held time; return it.
	    #
	    $echo "$line" \
		| $sed 's/^\-\-\-   [total ]*lock[s]* wait+held read\/write [0-9]*ms+[0-9]*ms\/[0-9]*ms+\([0-9]*\)ms.*$/\1/'

	else
	    #
	    # Caller requested the peek held time; return it.
	    #
	    $echo "$line" \
		| $sed 's/^\-\-\-   peek count [0-9]* wait+held total\/max [0-9]*ms+\([0-9]*\)ms\/[0-9]*ms+[0-9]*ms.*$/\1/'

	fi
}

getcpu()
{
	#
	# Extract the line containing the CPU times from the server log extract.
	#
	line=`$grep "^\-\-\- usage " $1`

	if [ $2 = "user" ]
	then
	    #
	    # Caller requested the CPU user time; return it.
	    #
	    echo "$line" | $sed 's/^\-\-\- usage \([0-9]*\)+[0-9]*us .*$/\1/'
	else
	    #
	    # Caller requested the CPU system time; return it.
	    #
	    echo "$line" | $sed 's/^\-\-\- usage [0-9]*+\([0-9]*\)us .*$/\1/'
	fi
}

printcpu()
{
	printf2 "%sCPU user time: %d milliseconds\n" "$2" `getcpu $1 user`
	printf2 "%sCPU system time: %d milliseconds\n" "$2" `getcpu $1 system`
}

sumpages()
{
	total=0

	#
	# Extract the pages read, written, and cached for each table
	# from the server log extract and sum the pages requested.
	#
	$grep "^\-\-\-   pages in+out+cached " $1 \
	    | $cut -b27- \
	    | while read pages
	do

	    if [ $2 = "in" ]
	    then
		#
		# Caller requested the pages read; sum them.
		#
		total=`$expr $total + \
		    \`echo $pages | $sed 's/^\([0-9]*\)+[0-9]*+[0-9]*$/\1/'\``
	    elif [ $2 = "out" ]
	    then
		#
		# Caller requested the pages written; sum them.
		#
		total=`$expr $total + \
		    \`echo $pages | $sed 's/^[0-9]*+\([0-9]*\)+[0-9]*$/\1/'\``
	    else
		#
		# Caller requested the pages cached; sum them.
		#
		total=`$expr $total + \
		    \`echo $pages | $sed 's/^[0-9]*+[0-9]*+\([0-9]*\)$/\1/'\``
	    fi

	    #
	    # Echo out of this subshell the total after each iteration.
	    # Only the last total echoed will be returned to the caller.
	    #
	    echo $total

	done | $tail -1		# return only the last total echoed
}

printpages()
{
	printf2 "%spages read: %d\n" "$2" `sumpages $1 in`
	printf2 "%spages written: %d\n" "$2" `sumpages $1 out`
}

setup()
{
	yamllevel=$1

	#
	# Create the directories.
	#
	printf2 "Creating directories as needed..."
	$mkdir -p $P4CLIENTdir
	$mkdir -p $P4ROOT
	$mkdir -p $P4JOURNALdir
	$mkdir -p $P4LOGdir
	printf2 " done.\n"

	#
	# Populate the db.* files by recovering from a checkpoint.
	#
	printf2 "Replaying checkpoint..."
	begin=`getseconds`
	$p4d -r $P4ROOT -z -jr $ZCKP > /dev/null
	elapsed=`getelapsed seconds $begin`
	printf2 " done.\n"

	printf2 "  checkpoint replay duration: %d seconds\n" $elapsed

	writeyamlfile $yamllevel \
	    checkpointName: `echo $ZCKP | $sed 's/.*\/\([^\/]*\)/\1/'`
	writeyamlfile $yamllevel "checkpointReplay: $elapsed"

	#
	# Create the client.
	#
	printf2 "Creating client..."
	run "$p4 client -o \
	    | $sed \"s~^Host:.*$~~\" \
	    | $sed \"s~^Root:.*$~Root:	$P4CLIENTdir~\" \
	    | $p4 client -i" > /dev/null
	printf2 " done.\n"
}

runme()
{
	yamllevel=$1

	writeyamlfile $yamllevel \
	    numberOfBranches: `$echo "$BRANCHCMDS" | $wc -l`
	writeyamlfile $yamllevel branches:
	yamllevel=`$expr $yamllevel + 1`

	EXTRACT=/tmp/extract.$$
	TABLE=/tmp/table.$$

	#
	# Execute the commands to open the files for branch and save the
	# number of files opened. Allowing for multiple branch commands
	# complicates the logic: since the "while read" loop executes
	# within a subshell, contortions are required to surface the
	# total number of files opened so that this number is
	# available to the rest of the script.
	#
	nfiles=`total=0
	ibranch=0
	$echo "$BRANCHCMDS" | $sed 's/^[ ]*\(.*\)$/\1/' | while read branchcmd
	do
	    ibranch=\`$expr $ibranch + 1\`
	    writeyamlfile $yamllevel "$ibranch:"
	    yamllevel=\`$expr $yamllevel + 1\`

	    printf2 "Branching files..."
	    nfiles=\`run $p4 $branchcmd | $wc -l\`
	    printf2 " done.\n"

	    extractlog "user-integrate -v" "$P4LOG" $EXTRACT
	    gettable $EXTRACT db.rev $TABLE

	    held=\`getheld $TABLE read\`
	    if [ "$held" = "" ]
	    then
		#
		# No read lock held time was recorded;
		# get the peek held time if it was recorded.
		#
		held=\`getheld $TABLE peek\`
	    fi

	    if [ "$held" != "" ]
	    then
		printf2 "  compute phase duration: %d milliseconds\n" $held
		writeyamlfile $yamllevel "branchComputeTime: $held"
	    fi

	    printf2 "  files opened: %d\n" $nfiles
	    writeyamlfile $yamllevel "filesOpened: $nfiles"

	    $rm $EXTRACT
	    $rm $TABLE

	    #
	    # Sum the total number of files opened by the branch commands.
	    #
	    total=\`$expr $total + $nfiles\`

	    # 
	    # Echo out of this subshell the total number of files opened
	    # after each iteration. Only the last total echoed will be used.
	    #
	    $echo $total

	    yamllevel=\`$expr $yamllevel - 1\`

	done | $tail -1`	# use only the last total echoed

	yamllevel=`$expr $yamllevel - 1`
	writeyamlfile $yamllevel totalFilesOpened: $nfiles

	#
	# Create the changelist and save the changelist number.
	#
	printf2 "Creating changelist..."
	changenumber=`run "$p4 change -o \
	    | $sed \"s~^	<enter .*$~	$BENCHMARK changelist.~\" \
	    | $p4 change -i" \
	    | $sed "s~^Change \([0-9]*\) created.*$~\1~"`
	printf2 " done.\n"

	#
	# Submit the changelist.
	#
	printf2 "Submitting changelist..."
	run $p4 submit -c $changenumber > /dev/null
	printf2 " done.\n"

	if [ $granularity = "centiseconds" ]
	then
	    elapsed=`hundredths $elapsed`
	    exiting=`hundredths $exiting`
	fi

	printf2 "  elapsed time: %s seconds\n" $elapsed
	printf2 "  exiting time (including fsyncs): %s seconds\n" $exiting

	writeyamlfile $yamllevel "submitElapsedTime: $elapsed"
	writeyamlfile $yamllevel "submitExitTime: $exiting"

	if [ 0 -eq 1 ]
	then
	    #
	    # Not all releases print separate tracking information for
	    # phases of the submit prior to the dm-CommitSubmit phase.
	    #
	    extractlog "user-submit -c" "$P4LOG" $EXTRACT
	    printf2 "  user-submit -c statistics:\n"
	    printcpu $EXTRACT "    "
	    printpages $EXTRACT "    "
	    $rm $EXTRACT
	fi

	extractlog dm-CommitSubmit "$P4LOG" $EXTRACT

	if [ 0 -eq 1 ]
	then
	    #
	    # Since the commit is just a portion of the dm-CommitSubmit phase
	    # (albeit almost all of the dm-CommitSubmit phase in this case),
	    # printing the dm-CommitSubmit phase statistics could be
	    # confusing.
	    #
	    printf2 "  dm-CommitSubmit statistics:\n"
	    printcpu $EXTRACT "    "
	    printpages $EXTRACT "    "
	fi

	gettable $EXTRACT db.integed $TABLE
	held=`getheld $TABLE write`
	rate=`$expr \`$expr $nfiles \* 1000\` / $held`

	printf2 "  commit duration: %d milliseconds\n" $held
	printf2 "  commit rate: %d files/second\n" $rate

	writeyamlfile $yamllevel "submitCommitTime: $held"
	writeyamlfile $yamllevel "submitCommitRate: $rate"

	$rm $EXTRACT
	$rm $TABLE

	#
	# Obliterate the changelist.
	#
	printf2 "Obliterating changelist..."
	run $p4 obliterate -y @$changenumber,@$changenumber > /dev/null
	printf2 " done.\n"

	#
	# Delete the changelist.
	#
	printf2 "Deleting changelist..."
	run $p4 change -d -f $changenumber > /dev/null
	printf2 " done.\n"

	#
	# Reset the changelist counter.
	#
	if [ 0 -eq 1 ]
	then
	    #
	    # Required for strict repeatability, but too dangerous to execute
	    # unless potential ramifications have been mitigated (i.e. this
	    # cannot be executed against a production server).
	    #
	    printf2 "Reseting changelist counter..."
	    run $p4 counter -f change `$expr $changenumber - 1` > /dev/null
	    printf2 " done.\n"
	fi
}

cleanup()
{
	yamllevel=$1

	target=`$pwd`/$BENCHMARK.$DATETIME.log
	printf2 "Moving server log to %s..." $target
	$mv $P4LOG $target
	printf2 " done.\n"

	printf2 "Removing db.* files and journal file..."
	$rm -f $P4ROOT/db.* $P4JOURNAL
	printf2 " done.\n"

	if [ -d $P4ROOT/server.locks ]
	then
	    printf2 "Removing server.locks subdirectory..."
	    $rm -rf $P4ROOT/server.locks
	    printf2 " done.\n"
	fi
}

#
# Ensure no related p4d processes are present.
#
nop4ds

rcschange=`getrcsvalue "$RCSCHANGE"`
rcsdate=`getrcsvalue "$RCSDATE"`
p4dversion=`$p4d -V | $grep '^Rev\..*$' | $sed 's/^Rev\. \(.*\)\.$/\1/'`
p4version=`$p4 -V | $grep '^Rev\..*$' | $sed 's/^Rev\. \(.*\)\.$/\1/'`
machinfo=`uname -a | sed "s/\`uname -n | sed 's/\./\\./g'\`/\`uname -n | sed 's/^\([^\.]*\)\..*$/\1/'\`/g"`

printf2 "Using versions:\n"
printf2 "  BRANCHSUBMIT.SH/%s (%s)\n" $rcschange $rcsdate
printf2 "  $p4dversion\n"
printf2 "  $p4version\n"
printf2 "On machine:\n"
printf2 "  `$echo "$machinfo" | $cut -b-78`\n"

createyamlfile
printf2 "BRDB file:\n"
printf2 "  `absfilepath $YAMLFILE`\n"

yamllevel=0
writeyamlfile $yamllevel "benchmark: $BENCHMARK"
writeyamlfile $yamllevel "args: $args"
writeyamlfile $yamllevel "testInfo:"
yamllevel=`$expr $yamllevel + 1`
writeyamlfile $yamllevel "rcsChange: $rcschange"
writeyamlfile $yamllevel "rcsDate: $rcsdate"
yamllevel=`$expr $yamllevel - 1`
writeyamlfile $yamllevel "versions:"
yamllevel=`$expr $yamllevel + 1`
writeyamlfile $yamllevel "p4d: $p4dversion"
writeyamlfile $yamllevel "p4: $p4version"
yamllevel=`$expr $yamllevel - 1`
writeyamlfile $yamllevel "uname: \"$machinfo\""

#
# Determine the environment within which we're running.
#
getos

#
# Set environment-dependent variables.
#
case $OS in
CYGWIN)
	start=cygstart
	;;
MINGW)
	start=start
	;;
NT)
	start=start
	;;
*)
	start=""
	;;
esac

#
# Run phases in the order specified.
#
irunme=0
for arg in $args
do
	if [ $arg = "setup" -o $arg = "runme" -o $arg = "cleanup" ]
	then
	    printf2 "\nStarting %s %s phase...\n" $BENCHMARK $arg

	    if [ $arg = "runme" ]
	    then
		if [ $irunme -eq 0 ]
		then
		    writeyamlfile $yamllevel "runme:"
		    yamllevel=`$expr $yamllevel + 1`
		fi
		irunme=`$expr $irunme + 1`
		writeyamlfile $yamllevel "$irunme:"
		yamllevel=`$expr $yamllevel + 1`
	    fi

	    #
	    # Execute phase in a subshell so that our context
	    # (e.g. yamllevel) is not disturbed.
	    #
	    ( $arg $yamllevel )

	    if [ $arg = "runme" ]
	    then
		yamllevel=`$expr $yamllevel - 1`
	    fi

	else
	    printf2 "\nPhase \"%s\" unknown! Terminating.\n" $arg
	    $exit 1

	fi
done

$exit 0
# Change User Description Committed
#4 25266 Robert Cowham Validate against shelved version for release.
#3 25265 Robert Cowham Default to 18.2 checkpoint
#2 19131 Robert Cowham Finish branchsubmit benchmark
#1 19100 Robert Cowham Initial version