#! /bin/ksh
#
#
# Copyright (c) 1998-2000 by Sun Microsystems, Inc.
# All rights reserved.
#
#ident  "@(#)nfs_upgrade.ksh 1.8     00/12/04 SMI"
#
# cmd/ha-services/nfs/nfs_upgrade.ksh
#
# ***************************************************************
# This script will upgrade the nfs dataservice from SC2.2 SC3.0.
# ***************************************************************

# ***************************************************************
# I18N
# ***************************************************************

typeset -x TEXTDOMAIN=SUNW_SC_NFS
typeset -x TEXTDOMAINDIR=/opt/SUNWscnfs/lib/locale

# *************************************************************
# openfile() "filename"
#
#       Create the given "filename", if it does
#       not exist.  Any needed directories are created.
#
#       The filename must begin with slash.
#
#       Return values:
#               0       - success
#               1       - error
#
# *************************************************************

function openfile {

        typeset dir

        if [[ $# -ne 1 ]]; then
		printf "$(gettext '%s:  Internal error - bad call to openfile()'
)\n" ${PROG} >&2
                exit 2
        fi

        typeset filename=${1}

        # make sure filename begins with /
        if [[ "${filename}" != /* ]]; then
                printf "$(gettext '%s:  Internal error - bad filename passed to
		    openfile()')\n" ${PROG} >&2
                exit 2
        fi


        # create each directory with group sys
	dir=`dirname ${filename}`

	mkdir -p -m 0755 ${dir} 
	if [[ $? -ne 0 ]]; then
		printf "$(gettext '%s: Error in creating the directory')\n" ${dir} ${PROG} 
		exit 1
	fi

	chgrp sys ${dir} || return 1
	if [[ $? -ne 0 ]]; then
		printf "$(gettext '%s: Error in changing the group')\n" ${dir} ${PROG} 
		exit 1
	fi

        # create the file
        touch ${filename} || return 1

        return 0
}


# *************************************************************
# openlog() -
#       Create the install log file.  If it does not
#       exist, "logmsg" and "logerr" will not create it.
# *************************************************************

function openlog
{
        openfile ${install_log}

        return $?
}

# *************************************************************
# logmsg()
#
#       Print stdin to stdout and to the install log file.
#       If the install log has not been created, just
#       print to stdout.
# *************************************************************

function logmsg
{
        if [[ ! -f "${install_log}" ]]; then
                cat
        else
                tee -a ${install_log}
        fi
}

# *************************************************************
# logerr()
#
#       Print stdin to stderr and to the install log file.
#       If the install log has not been created, just
#       print to stderr.
# *************************************************************

function logerr
{
        if [[ ! -f "${install_log}" ]]; then
                cat >&2
        else
                tee -a ${install_log} >&2
        fi
}

# Program name and args list
typeset -r PROG=${0##*/}
typeset -r ARGS=$*
typeset -r pid=$$
typeset -r RT_NAME=SUNW.nfs
typeset -r SC_BASEDIR=${SC_BASEDIR:-}
typeset -r SC_LOGDIR=${SC_BASEDIR}/var/cluster/logs/install
typeset install_log=${SC_LOGDIR}/${PROG}.log.${pid}
typeset -r tmperrs=/tmp/${PROG}.cmderr.${pid}

openlog || return 1

SCRGADM=/usr/cluster/bin/scrgadm
SCSWITCH=/usr/cluster/bin/scswitch

# *************************************************************
# nfs_upgrade script is called with two arguments.
# v - Version of the cluster software that needs to be upgraded
# d - Location of the preserved configuration files

# *************************************************************
# check whether the function is called with valid arguments.
	while getopts v:d: name
	do
		case $name in
		v)	version_info="$OPTARG";;
		d)	preserve_conf_dir="$OPTARG";;
                \?)	printf "%s:  $(gettext 'Internal error - bad call to nfs_upgrade ()') \n" ${PROG} >&2
			exit 2;;
		esac
	done

# Check whether the preserve_conf_dir exists
if [[ ! -d $preserve_conf_dir ]]; then
	 printf "%s:  $(gettext 'Internal error - Configuration directory "%s" is not found') \n" ${PROG} ${preserve_conf_dir} >&2
	exit 2
fi

dfstab_path=${preserve_conf_dir}/SUNWcluster/conf/hanfs
ccd_file=${preserve_conf_dir}/SUNWcluster/conf/ccd.database

# *************************************************************
# get_lhost_names() -
# This function retrieves the logicalhost names from ccd which
# have nfs.
# *************************************************************

function get_lhost_names {
	printf "$(gettext 'Retrieving the logical host names') ... \n" | logmsg
	typeset -i i=0

	if [[ ! -r $ccd_file ]]; then
		printf "$(gettext '%s:  Internal error- preserved configuration file "%s" is not accessible')\n" ${PROG} ${ccd_file} >&2
		exit 2
	fi

	cmd="egrep "^LOGHOST_DS:" $ccd_file"
	print "${cmd}\n" >>${install_log}
	${cmd} > ${tmperrs} 2>&1
	result=$?
	cat ${tmperrs} >>${install_log}

	if [[ $result -ne 0 ]]; then
		printf "$(gettext 'failed')\n\n" | logmsg
		printf "%s:  $(gettext 'Problem parsing configuration file'): %s\n" ${PROG} ${ccd_file} | logerr
		exit 1
	fi
		
	egrep "^LOGHOST_DS:" $ccd_file | while read lhost_row
	do

	        if [[ $(IFS=: ; set -- ${lhost_row}; print $#) -ne 3 ]]; then
			printf "$(gettext 'failed')\n\n" | logmsg
			printf "%s:  $(gettext 'Problem parsing configuration file'): %s\n" ${PROG} ${ccd_file} | logerr
			exit 1
        	else
			rname=$(IFS=: ; set -- ${lhost_row}; print $3)
			if [[ $rname == "nfs" ]]; then
				lname=$(IFS=: ; set -- ${lhost_row}; print $2)
				host_names[$i]=$lname
                        	((i=$i+1))
			fi     
		fi
	done

		number_of_hostnames=${#host_names[*]}
		if [[ $number_of_hostnames -eq 0 ]]; then
			printf "$(gettext 'failed')\n\n" | logmsg
			printf "%s:  $(gettext 'nfs data service is not configured on any logicalhost'): %s\n" ${PROG} ${ccd_file} | logerr
			exit 1
		fi

		printf "$(gettext 'Succeeded')\n\n" | logmsg

}

# *************************************************************
# setup_dfstab()
# This function copies all the 2.2 dftstab files in the 
# appropriate location.
# *************************************************************

function setup_dfstab {
	typeset pathprefix
	typeset dfstab_file
	typeset -i i=0	

	printf "$(gettext 'Migrating dfstabfile') ...\n" | logmsg

	for loghost in ${host_names[*]}
	do
		rg_name=${loghost}-lh	
		rs_name=nfs-$loghost

		# Retrieve the pathprefix property value for the RG

		cmd="scha_resourcegroup_get -O PATHPREFIX -G $rg_name"
		print "${cmd}\n\n" >>${install_log}
		pathprefix=`${cmd}`

		if [[ $? -ne 0 ]]; then
			printf "$(gettext 'failed')\n\n" | logmsg
                        printf "%s:  $(gettext 'Failed to retrieve Path_prefix for "%s" ') \n" ${PROG} ${rg_name} | logerr 
			exit 1
		fi

		if [[ -z "${pathprefix}" ]]; then
			printf "$(gettext 'failed')\n\n" | logmsg
			printf "%s:  $(gettext 'No pathprefix set for Resource Group: "%s" ') \n" ${PROG} ${rg_name} | logerr
			exit 1
		fi	

		# Verify whether the pathprefix directory exists
		if [[ ! -d ${pathprefix} ]]; then	
	 		printf "%s:  $(gettext 'Internal error - Pathprefix directory "%s" does not exist') \n" ${PROG} ${pathprefix} >&2
			exit 2
		fi	
	
		# Create the directory to keep the dfstab files
		mkdir -p ${pathprefix}/SUNW.nfs

		dfstab_file_old=${dfstab_path}/dfstab.$loghost

		# Verify whether the dfstab file exists for this
		# logical host
		if [[ ! -r ${dfstab_file_old} ]]; then
			printf "$(gettext 'dfstab file is not accessible for logical host "%s". Skipping this resource.')\n\n" ${loghost} | logmsg
			continue
		fi

        	dfstab_file_new=${pathprefix}/SUNW.nfs/dfstab.${rs_name}

		# Copy the dfstab files
		cmd="cp $dfstab_file_old $dfstab_file_new"
		print ${cmd} >>${install_log}
		${cmd} > ${tmperrs} 2>&1
                cat ${tmperrs} >>${install_log}

		# Store the rg_name and rs_name. 
		# These names are used later while creating resource
		config_info[i]=$rg_name:$rs_name
		((i=i+1))

        done

	printf "$(gettext 'Succeeded')\n\n" | logmsg
	
}

# *************************************************************
# configure_rs() 
# This function creates the nfs resource(s) and brings online.
# *************************************************************

function configure_rs {
	
	printf "$(gettext 'Configuring nfs resource(s)') ...\n " | logmsg	

	# Resource Type is already registered by Framework.

	# Configure the resource(s)
	for entry in ${config_info[*]}
	do
		rg_name=$(IFS=: ; set -- ${entry}; print $1)
		rs_name=$(IFS=: ; set -- ${entry}; print $2)

		# check whether the resource is already existing
		# This is needed for idempotency

		cmd="scha_resource_get -O TYPE -R $rs_name"	
		print "${cmd}\n" >>${install_log}
		${cmd} > ${tmperrs} 2>&1
		result=$?
		cat ${tmperrs} >>${install_log}
		
		if [[ $result -ne 0 ]]; then
		# Resource is not there, create it	
			cmd="${SCRGADM} -a -j $rs_name -t $RT_NAME -g $rg_name"
			print "${cmd}\n" >>${install_log}
			${cmd} > ${tmperrs} 2>&1
			result=$?
			cat ${tmperrs} >>${install_log}
			
			if [[ $result -ne 0 ]]; then
				printf "$(gettext 'failed')\n\n" | logmsg
                        	printf "%s:  $(gettext 'scrgadm failed to create the resource "%s". Verify whether the nfs package is installed on all nodes and make sure the configuration is correct') \n" ${PROG} ${rs_name} | logerr
                        	exit 1
			fi
		fi

		# Resource Group is already brought online by FrameWork.

		# Enable the resource
		cmd="${SCSWITCH} -e -j $rs_name"
		print "${cmd}\n\n" >>${install_log}
                ${cmd} >${tmperrs} 2>&1
		result=$?
                cat ${tmperrs} >>${install_log}

		if [[ $result -ne 0 ]]; then
			printf "$(gettext 'failed')\n\n" | logmsg
			printf "%s:  "
			    "$(gettext 'Failed to start the resource "%s".') \n" ${PROG} ${rs_name} | logerr
			exit 1
		fi

		# Enable the resource monitor
		cmd="${SCSWITCH} -e -M -j $rs_name"
		print "${cmd}\n" >>${install_log}
                ${cmd} >${tmperrs} 2>&1
		result=$?
                cat ${tmperrs} >>${install_log}

		if [[ $result -ne 0 ]]; then
			printf "$(gettext 'failed')\n\n" | logmsg
			printf "%s:  $(gettext 'Failed to start the fault monitor for resource "%s".') \n" ${PROG} ${rs_name} | logerr
			exit 1
		fi

	done
	printf "$(gettext 'Succeeded')\n\n" | logmsg
}

# Retrieve the logical host names which have nfs resource.
get_lhost_names

# Convert dfstab entries.
setup_dfstab

# Create and enable the resource(s)
configure_rs
