#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2004,2007 
# 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 
#
# sr_migrate.sh:  Migrate system registry tables.
#
# Invocation:
#
# sr_migrate <type> [path]
#
# where:
#
# "type" is one of:
#
# aix    - Standard migration when installing new system registry
#          library on AIX, including IW and all Peer Domain tables.
#
# linux  - Standard migration when installing new system registry
#          library on Linux, including IW and all Peer Domain tables.
#
# custom - Migrates only the tables found directly in "path".  (For
#          tables created pre-Vega, this must be the directory
#          containing the "Data" and "Metadata" subdirectories.)
#
# "path" is either:
#
# 1) Absolute TOP of path to all cluster tables as follows:
#
#    TOP/<CLUSTER_ID>/registry/local_tree
#
#    where CLUSTER_ID is "IW" and all other cluster ids returned
#    by the lsclcfg command.  This form of "path" is expected when
#    "type" is "aix" or "linux".  If unspecified, it defaults to
#    "/var/ct".
#
# 2) Absolute path to a directory containing registry tables.  This
#    is required when "type" is "custom".
#    
#
# NOTES:
#
# - A standard (i.e. non-custom) migration results in the following
#   directories:
#
#   - TOP/<CLUSTER_ID>/registry/local_tree.$build_level.save
#
#     Contains the original tables.
#
#   - TOP/<CLUSTER_ID>/registry/local_tree
#
#     Either contains the migrated tables (if migration was successful)
#     -OR- is empty (if migration was unsuccessful).
#
#   In addition, migration of CLUSTER_ID's other than "IW" are
#   attempted only if the "IW" registry is migrated successfully.
#
#   NOTE: see how $build_level is obtained, below.
#
# - A custom migration results in the following directories:
#
#   - PATH.save
#
#     Contains the original tables.
#
#   - PATH
#
#     Either contains the migrated tables (if migration was successful)
#     -OR- is empty (if migration was unsuccessful).
#
#
# @(#)55   1.9   src/rsct/sr/Migration/sr_migrate.sh, registry, rsct_relgh, relghs001a 1/10/06 09:19:16

# establish where system binaries are
bin=/bin

# remember when we were called
date=`$bin/date`

# discover the build level of the code being installed
build_level=`LC_ALL=C /usr/sbin/rsct/install/bin/ct_sr_version`

if [ -z "$build_level" ]
then
	build_level="no_ct_sr_version"
fi

# establish variables

indent=""
invoke=silent
rmMigrateTrace=/tmp/rmTrace
logfile="/tmp/.sr_migrate.log"
rpttr=/usr/sbin/rsct/bin/rpttr
mknodeid=/usr/sbin/rsct/bin/mknodeid

# uncomment the following to run in debug mode
# debug=debug

if [ -z "$debug" ]
then
	ct_top=/var/ct
	lsclcfg=/usr/sbin/rsct/bin/lsclcfg
	srMigrate=/usr/sbin/rsct/install/bin/srMigrate
	rmMigrate=/usr/sbin/rsct/install/bin/rmMigrate
else
	ct_top=/tmp/bubbly/var/ct
	lsclcfg=/tmp/bubbly/lsclcfg
	srMigrate=/tmp/bubbly/srMigrate
	rmMigrate=/tmp/bubbly/rmMigrate
fi

function log
{
	if [ -z "$debug" ]
	then
		if [[ -f $logfile ]]
		then
			$bin/echo "$indent$*" >>$logfile
		fi
	else
		$bin/echo "$indent$*"
	fi
}

function enter
{
	log "Entering $*"
	indent="$indent  "
}

function leave
{
	indent=${indent#  }
	log "Leaving $*"
}

function silent
{
	$* 1>/dev/null 2>&1
}

function noisy
{
	$*
}

function log_rmMigrate_trace
{
	enter log_rmMigrate_trace

	if [ -f $rmMigrateTrace ] && [ -f $rpttr ]
	then
		log "--->rmMigrate Trace Start"
		$rpttr $rmMigrateTrace >> $logfile
		log "<---rmMigrate Trace End"
	fi

	leave log_rmMigrate_trace
}

function make_registry_directory
{
	$invoke $bin/mkdir -p $1
	$invoke $bin/chown bin $1
	$invoke $bin/chgrp bin $1
	$invoke $bin/chmod 775 $1
}

# caller must establish source, target, save, and parent variables
# before calling migrate_registry_tables

function migrate_registry_tables
{
	enter "migrate_registry_tables: source($source) target($target) save($save)"

	if [[ -d $save ]]
	then
		$invoke $bin/rm -r -f $save
	fi

	$invoke $bin/rm -r -f $target
	make_registry_directory $target

	errata=`$srMigrate $source $target 2>&1`
	rc=$?

	log "srMigrate $source $target rc($rc) errata($errata)"

	# save the original source tables

	$invoke $bin/mv $source $save

	# if source successfully migrated to target,
	# make target the new source
	# otherwise establish an empty source
	# and remove all version update (*.vu) files

	if [[ $rc -eq 0 ]]
	then
		log "srMigrate SUCCEEDED"
		$invoke $bin/mv $target $source
	else
		if [[ -d $target ]]
		then
			$invoke $bin/rm -r -f $target
		fi

		log "srMigrate FAILED"
		log "Establishing empty registry/local_tree directory"
		make_registry_directory $source

		if [ -n "$parent" ]
		then
			log "Removing .vu files from registry directory"
			$invoke $bin/rm -f $parent/*.vu
		fi
	fi

	leave "migrate_registry_tables: rc($rc)"

	return $rc
}

function migrate_resource_handles
{
	enter migrate_resource_handles

	# test to see if resource handle migration needed

	$rmMigrate -t
	rc=$?

	log "rmMigrate: test for migration rc($rc)"

	if [[ $rc -eq 0 ]]
	then
		$invoke $bin/rm -f $rmMigrateTrace
		$rmMigrate
		rc=$?
		log "rmMigrate SUCCEEDED"
	fi

	if [[ $rc -ne 0 ]]
	then	# check for registry already migrated
		if [[ $rc -eq 1 ]]
		then
			rc=0
		else
			if [[ $rc -eq 2 ]]
			then
				log "rmMigrate FAILED : insufficient space in /var" 
			else
				log "rmMigrate FAILED rc($rc)"
			fi

			rc=1
		fi
	fi

	log_rmMigrate_trace

	leave "migrate_resource_handles: rc($rc)"

	return $rc
}

# migrate_cluster_registries returns:
#
# 0 if successful
# 1 if unsuccessful or migration is unnecessary

function migrate_cluster_registries
{
	enter migrate_cluster_registries

	# generate a node id, if one doesn't already exist
	$invoke $mknodeid -k

	log "Checking if IW registry has already been migrated"

	source=$ct_top/IW/registry/local_tree
	target=$ct_top/IW/registry/local_tree.new

	errata=`$srMigrate $source $target TEST 2>&1`
	rc=$?

	log "srMigrate $source $target TEST rc($rc) errata($errata)"

	if [[ $rc -eq 2 ]]
	then
		log "IW registry is already migrated"
		log "Assuming peer domain registries are also already migrated"
		leave migrate_cluster_registries
		return 1
	fi

	if [[ $rc -ne 0 ]]
	then
		log "Probably no registry directory"
		leave migrate_cluster_registries
		return 1
	fi

	log "Migrating IW registry"

	source=$ct_top/IW/registry/local_tree
	target=$ct_top/IW/registry/local_tree.new
	save=$ct_top/IW/registry/local_tree.$build_level.save
	parent=$ct_top/IW/registry

	migrate_registry_tables

	log "Migrating peer domain registries:"

	$lsclcfg -ax -D' ' |&

	while read -p name id
	do	if [[ "$name" = "IW" ]]
		then	continue
		fi

		log "Peer Domain name($name) id($id) :"

		source=$ct_top/$id/registry/local_tree
		target=$ct_top/$id/registry/local_tree.new
		save=$ct_top/$id/registry/local_tree.$build_level.save
		parent=$ct_top/$id/registry

		migrate_registry_tables
	done

	leave migrate_cluster_registries

	return 0
}

# main

# establish log file
$invoke $bin/rm -f $logfile
$invoke $bin/touch $logfile

enter "sr_migrate args($*) timestamp($date)"

if [ -n "$2" ]
then
	ct_top="$2"
fi

case "$1" in
	"aix")
		migrate_cluster_registries
		rc=$?

		if [[ $rc -eq 0 ]]
		then
			migrate_resource_handles
		fi
	;;
	"linux")
		migrate_cluster_registries
	;;
	"custom")
		if [ -n "$2" ]
		then
			source=$2
			target=$2.new
			save=$2.save
			parent=""     # .vu files in parent ignored for custom

			migrate_registry_tables
		else
			log "A path argument must be specified for a custom migration!"
		fi
	;;
	*)
		log "Invalid arguments passed to sr_migrate!"
		log "Invocation:  sr_migrate <aix|linux|custom> [path]"
	;;
esac

leave sr_migrate

# always exit with a 0 rc
exit 0
