#! /bin/ksh
#
#
# Copyright (c) 1998-2000 by Sun Microsystems, Inc.
# All rights reserved.
#
#ident  "@(#)nfs_upgrade.ksh 1.5     00/08/16 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

# ***************************************************************
#
# scrgadm(1M) exit codes used by upgrade
#
#       The following exit codes must always be synchronized with the
#       scha_err_t codes defined in scha_err.h!
#
# ***************************************************************

integer -r SCHA_ERR_NOERR=0             # no error was found
integer -r SCHA_ERR_EXIST=13            # R/RG/RT already exists; can't add
integer -r SCHA_ERR_RSRC=14             # invalid resource
integer -r SCHA_ERR_ACCESS=4            # permission denied

# *************************************************************
# 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}

openlog || return 1

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

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

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

	egrep "^LOGHOST_DS:" $ccd_file | read lhost_row
        if (( $(IFS=: ; set -- ${lhost_row}; print $#) != 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
		printf "$(gettext 'Succeeded')\n\n" | logmsg

}

# *************************************************************
# register_type()
# This functions register the nfs resource type.
# *************************************************************

function register_type {
	printf "$(gettext 'Registering the nfs resource type') ...\n " | logmsg
	cmd="$SCRGADM -a -t $RT_NAME"
	print "${cmd}" >>${install_log}
	${cmd} > ${tmperrs} 2>&1
	result=$?
	if [[ $result != $SCHA_ERR_NOERR && $result != $SCHA_ERR_EXIST ]]; then
		printf "$(gettext 'failed')\n\n" | logmsg		
		printf "%s:  $(gettext 'Cannot create the nfs resource type') \n" ${PROG} | logerr
		exit 1
	fi
	printf "$(gettext 'Succeeded')\n\n" | logmsg
}

# *************************************************************
# setup_dfstab()
# This function moves the dftstab file(s) in the proper location
# *************************************************************

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

	printf "$(gettext 'Migrating dfstabfile') ...\n" | logmsg
	for entry in ${host_names}
	do
		rg_name=${entry}-lh	
		rs_name=nfs-$entry
		config_info[i]=$rg_name:$rs_name
		((i=i+1))
		cmd="scha_resourcegroup_get -O PATHPREFIX -G $rg_name"
		print "${cmd}\n\n" >>${install_log}
                ${cmd} > ${tmperrs} 2>&1
		pathprefix=`${cmd}`
		if [[ $? != ${SCHA_ERR_NOERR} ]]; then
			printf "$(gettext 'failed')\n\n" | logmsg
                        printf "%s:  $(gettext 'Unable 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	

		mkdir -p ${pathprefix}/SUNW.nfs
        	dfstab_file=${pathprefix}/SUNW.nfs/dfstab.${rs_name}
		cmd="cp ${dfstab_path}/dfstab.* $dfstab_file"
		print ${cmd} >>${install_log}
		${cmd} >/dev/null 2>&1
        done
	printf "$(gettext 'Succeeded')\n\n" | logmsg
	
}

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

function create_rs {
	
	printf "$(gettext 'Configuring nfs resource(s)') ...\n " | logmsg	
	for entry in ${config_info}
	do
		rg_name=$(IFS=: ; set -- ${entry}; print $1)
		rs_name=$(IFS=: ; set -- ${entry}; print $2)
		cmd="${SCRGADM} -a -j $rs_name -t $RT_NAME -g $rg_name"
		print "${cmd}\n" >>${install_log}
		msg=`$cmd  2>&1`
                #${cmd} > ${tmperrs} 2>&1
		result=$?

		# if the resource exists scrgadm returns 3 
		# however it returns 3 for other conditions as well
		# therefore we have to parse the error string to
		# see if indeed the error is that the resource exists
		if [[ $result == 3 ]]; then
			target_word=`echo $msg | nawk -F\; '{print $1}' | nawk -F\: '{print $2}'`
			# Do NOT remove the preceding space.
			target_match=" resource exists"
fi

		if (( $result == $SCHA_ERR_ACCESS )); then
			printf "$(gettext 'failed')\n\n" | logmsg
			printf "%s:  $(gettext 'nfs package need to be installed on all the nodes.') \n" ${PROG} | logerr
                        exit 1


		# if there is an error and it is not SCHA_ERR_RSRC nor is 
		# that a resource exists, then we exit 1
		elif [[ $result != $SCHA_ERR_NOERR && $result != $SCHA_ERR_RSRC && "$target_word" != "$target_match"  ]]; then
			 printf "$(gettext 'failed')\n\n" | logmsg
			printf "%s:  $(gettext 'scrgadm failed to create the resource "%s".') \n" ${PROG} ${rs_name} | logerr
			exit 1
		fi	
		
		cmd="${SCSWITCH} -e -j $rs_name"
		print "${cmd}\n\n" >>${install_log}
                ${cmd} >${tmperrs} 2>&1

		if [[ $? != 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

		cmd="${SCSWITCH} -e -M -j $rs_name"
		print "${cmd}\n\n" >>${install_log}
                ${cmd} >${tmperrs} 2>&1
		if [[ $? != 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
}

typeset -ft $(typeset +f) 
# Retrieve the logical host names which have nfs resource.
get_lhost_names

# Register nfs resource type.
register_type

# Convert dfstab entries.
setup_dfstab

# Create resource(s)
create_rs
