#!/bin/ksh
#
#pragma ident     "@(#)ccdreconfig.sh 1.13 01/08/02"
#Copyright (C) 1997 Sun Microsystems, Inc.
#

#
# ccdreconfig - Energizer Cluster Reconfiguration Programs for
#		CCD.
#
# Input:
#		All environment variables like "currnodes"/
#		"allnodes"/"localnodeid"/ and current "cmmstep".
#		(CURRSTEP)
#
# Action:	Run Reconfiguration Programs based on current
#		"cmmstepN"|"cmmabort"|"cmmstart"|"cmmreturn".
#
# Output:	Return 0 if success.
#		Return 1 if failure
#		Return 200 if reconfigurtion program result is to
#		be ignored.

#
# Put Local Variables here.
#
set -e
pre="SUNWcluster.reconf.ccd"


RECONF_SCRIPTS=${RECONF_SCRIPTS:-/opt/SUNWcluster/etc/reconf/scripts}
CLUSTERBIN=${CLUSTERBIN:-/opt/SUNWcluster/bin/}
CLUSTERVAR=${CLUSTERVAR:-/var/opt/SUNWcluster/}
CLUSTERETC=${CLUSTERETC:-/etc/opt/SUNWcluster/}
INCLUDE=.
${INCLUDE} ${RECONF_SCRIPTS}/reconf_ener.common

# CCD local variables.
CCDRESTARTING=${CLUSTERVAR}/ccd_is_restarted
CCDSHARECOPY="${CLUSTERETC}/conf/ccd.database.shared"

ccdstartnode_cmd() {

 if [  -d ${CLUSTERBIN}/ccdd -o ! -x ${CLUSTERBIN}/ccdd  ]; then
     log_info "${pre}.4000" \
		"${CLUSTERBIN}/ccdd:  CCD package is not installed."
     exit 1
 fi
	#
	# Clean up static query lock
	#
	/bin/rm -f ${CLUSTERVAR}/ccd/updlock


}

ccdstart_cmd() {
	#
	# Check if we have a two node cluster. In that case we
	# should verify that the shared CCD volume mount directory was
 	# created.

	if [ ${ccdssa} -eq 2 ]; then
		if [ ! -d ${CLUSTERETC}/conf/ccdssa ]; then
			/usr/bin/mkdir ${CLUSTERETC}/conf/ccdssa
		fi
	fi

	# start ccdd.  We can't do it before this point because
	# clustd has to determine the nodeid.
	if [ `/usr/bin/ps -e | /usr/bin/grep ccdd | \
                    /usr/bin/wc -l` -ne 0 ]; then
     		log_info "${pre}.4002" "${clustname} ccdd already running"
               	exit 1
	fi

	if [ ! -d ${CLUSTERVAR}/ccd ]; then
		/usr/bin/mkdir -p ${CLUSTERVAR}/ccd/
	fi

	${CLUSTERBIN}/ccdd -f ${ccdfile} >> ${CLUSTERVAR}/ccd/ccd.log 2>&1

	#
	#       setup the flag to indicate we are restarting the node
	#
	if [ ! -f ${CCDRESTARTING} ]; then
			touch ${CCDRESTARTING}
	fi

}

ccdabort_cmd() {
      #
      # Check if we need to umount the CCD shared volume.
      #
 
	devssa=`enccdmatch ccd.ccddevice.ssa`
	if ([ ${ccdssa} -eq 2 ] && [ ${devssa} != "none" ]) ; then
         # log_info "${pre}.1700" "${clustname} umount \
     	 #	CCD Shared Volume"

          #
          # check if the device is in fact mounted
          #
	  log_info "${pre}.1712" "Checking if shared CCD Volume already mounted"
          if [ `/usr/sbin/mount -v | grep ${CLUSTERETC}/conf/ccdssa \
      		| /bin/wc -l` -eq 1 ]; then
		
		log_info "${pre}.1713" "Running lockfs on ${CLUSTERETC}/conf/ccdssa"
                /usr/sbin/lockfs -h ${CLUSTERETC}/conf/ccdssa
		log_info "${pre}.1704" "Unmounting ${CLUSTERETC}/conf/ccdssa"
                /usr/sbin/umount ${CLUSTERETC}/conf/ccdssa
		log_info "${pre}.1704" "Unmounted ${CLUSTERETC}/conf/ccdssa"
          fi
	  #
	  # Do not check if sc_dg is imported : it can take too long.
	  # If not imported deport will fail, ignore it. If it is imported
	  # it will eventually get deported, before we import it again.
	  #
		/usr/sbin/vxdg deport sc_dg &
	fi

	# Just to be safe remove any shared copy of the ccd that
	# might still exist.
	/bin/rm -rf ${CLUSTERETC}/conf/${CCDSHARECOPY}
	/bin/rm -rf ${CLUSTERVAR}/ccd/ccdlocation

     log_info "${pre}.1701" "${clustname} aborting ccdd."
     ${CLUSTERBIN}/ccdctl stop $clustname `enccdmatch ccd.stop_timeout`
     log_info "${pre}.1702" "${clustname} aborting ccdd completed."
}

ccdstep3_cmd() {

     #       CCD: step 3
     #

     log_info "${pre}.1703" "${clustname} starting ccdd."

 
     #
     # Check if we need to mount the CCD shared volume.
     # We need to mount it when we have a 2-node cluster.
     # The master is the only node mounting the shared CCD.
     #

     #
     # Extract the CCD shared-volume info
     #
     log_info "${pre}.1714" "Extracting ccd volume info"
     devssa=`enccdmatch ccd.ccddevice.ssa`
     log_info "${pre}.1714" "CCD volume info : ${devssa}"

     if ([ ${ccdssa} -eq 2 ] && [ ${devssa} != "none" ]) ; then
	#
        # check if the device is already mounted
        #
	log_info "${pre}.1712" "Checking if shared CCD volume already mounted"
        if [ `/usr/sbin/mount -v | grep ${CLUSTERETC}/conf/ccdssa \
        		| /bin/wc -l` -eq 1 ]; then

	      log_info "${pre}.1713" "Running lockfs on ${CLUSTERETC}/conf/ccdssa"
              /usr/sbin/lockfs -h ${CLUSTERETC}/conf/ccdssa
	      log_info "${pre}.1704" "Unmounting ${CLUSTERETC}/conf/ccdssa"
              /usr/sbin/umount ${CLUSTERETC}/conf/ccdssa
	      log_info "${pre}.1704" "Unmounted ${CLUSTERETC}/conf/ccdssa"
        fi

        # 
        # Check the number of nodes alives to decide which
        # node will mount the shared CCD volume as RWRITE.
        #
        nalive=`echo ${currnodes} | /bin/wc -w`

	ccddevpath=/dev/vx/dsk/sc_dg/ccdvol

	#
	# In 2-node case node 0 (master) will mount RW
	# only when two nodes are alive. When a single node
	# is alive it mount RW.
	#
	if ([ ${nalive} -eq 2 ] && [ ${localnodeid} -eq 0 ]) ||
			[ ${nalive} -eq 1 ] ; then

		#
		# import sc_dg disk group
		#
		log_info "${pre}.1710" "Importing sc_dg diskgroup"
		/usr/sbin/vxdg -Ctf import sc_dg
		log_info "${pre}.1711" "Running vxrecover on sc_dg diskgroup"
		/usr/sbin/vxrecover -g sc_dg -sb

		#
		# fsck the filesystem first
		#
		log_info "${pre}.1708" "Running fsck on ${ccddevpath}"
		/usr/sbin/fsck -F ufs -y  ${ccddevpath}

                log_info "${pre}.1704" \
		 "${clustname}  Mount CCD Shared Volume (${ccddevpath}) RW"

                 /usr/sbin/mount -F ufs  ${ccddevpath} \
                              ${CLUSTERETC}/conf/ccdssa

		log_info "${pre}.1704" "CCD Volume mounted"

		#
		#  CCD Volume mounted, so remove
		#  previous sync files
		#
		/usr/bin/rm -rf \
		${CLUSTERETC}/conf/ccdssa/ccd.database.ssa.sync_* > /dev/null

		if (( $nalive == 1 )); then
			# store the current valid ccd file
			#
			echo `enccdmatch ccd.ccdfilename.ssa` > \
				${CLUSTERVAR}/ccd/ccdlocation

			# remove any share copy that might exist since it no
			# longer is valid
			/usr/bin/rm -rf ${CLUSTERETC}/conf/${CCDSHARECOPY}
		else
			echo `enccdmatch ccd.ccdfilename` > \
				${CLUSTERVAR}/ccd/ccdlocation
		fi
	else
		# the second node in a two node cluster with a
		# shared ccd, we need to set the ccdlocation.
		echo `enccdmatch ccd.ccdfilename` > ${CLUSTERVAR}/ccd/ccdlocation
        fi
     else
	# we are in two node mode, the valid ccd is the local one.
	#
	echo `enccdmatch ccd.ccdfilename` > ${CLUSTERVAR}/ccd/ccdlocation
     fi

     ${CLUSTERBIN}/ccdctl start $clustname `enccdmatch ccd.start_timeout`

     log_info "${pre}.1705" "${clustname} starting ccdd completed."

}

ccdstep4_cmd() {
        #       CCD: step1 transition
        #
        if [ -f ${CCDRESTARTING} ]; then
              CCD_up=0
        else
              CCD_up=1
        fi

        log_info "${pre}.1706" "CCD Step 4 transition CCD_up=${CCD_up}"
        ${CLUSTERBIN}/ccdctl step1 $clustname \
                        `enccdmatch ccd.step1_timeout` ${CCD_up} ${CLSTARTUP}
        log_info "${pre}.1707" "CCD Step 4 transition completed."
}

ccdreturn_cmd() {
	log_info "${pre}.1708" "${clustname} returning ccdd."

	${CLUSTERBIN}/ccdctl return $clustname \
       			`enccdmatch ccd.return_timeout`

	devssa=`enccdmatch ccd.ccddevice.ssa`
	if ([ ${ccdssa} -eq 2 ] && [ ${devssa} != "none" ]) ; then
	    if [ `/usr/sbin/mount -v | grep ${CLUSTERETC}/conf/ccdssa \
       				| /bin/wc -l` -eq 1 ]; then
#
# Workaround to avoid an issue with a split brain condition and the
# shared ccd. The problem is that if we enter abort from steps 1-3
# and the system is configured with a shared ccd, that filesystem
# is not mounted yet. Just to have a backup of the most current
# shared ccd, make a copy here. We may never use it but just
# in case ccdadm -w can return this under certain conditions (see
# ccdctl.c).
		sharedccd=$(enccdmatch ccd.ccdfilename.ssa)
		if [[ -f ${sharedccd} ]]; then
			/bin/cp ${sharedccd} \
				${CLUSTERETC}/conf/ccd.database.shared
			echo ${CCDSHARECOPY} > ${CLUSTERVAR}/ccd/ccdlocation
		fi
		log_info "${pre}.1702" "Running lockfs on ${CLUSTERETC}/conf/ccdssa"
		/usr/sbin/lockfs -h ${CLUSTERETC}/conf/ccdssa
		log_info "${pre}.1704" "Unmounting ${CLUSTERETC}/conf/ccdssa"
		/usr/sbin/umount ${CLUSTERETC}/conf/ccdssa
		log_info "${pre}.1704" "Unmounted ${CLUSTERETC}/conf/ccdssa"
	    fi
	# Do not check if sc_dg is imported : it can take too long.
	# If not imported deport will fail, ignore it. If it is imported
	# it will eventually get deported, before we import it again.
	#
		log_info "${pre}.1710" "Deporting sc_dg diskgroup"
		/usr/sbin/vxdg deport sc_dg &
	else
		echo `enccdmatch ccd.ccdfilename` > ${CLUSTERVAR}/ccd/ccdlocation
	fi

	log_info "${pre}.1709" "${clustname} returning ccdd completed."
}



########################################################
#   Main Program                                       #
########################################################
if [ "${CURRSTEP}" != "startnode" ]; then
	#
	# can call enccdmatch only after
	# ensuring that the static query lock file
	# is cleaned up.
	#
	ccdssa=`enccdmatch ccd.nservers`
fi

case ${CURRSTEP} in
	startnode)
		ccdstartnode_cmd;;
        cmmstart)
		ccdstart_cmd ;;

        cmmabort)
		ccdabort_cmd ;;

        cmmreturn)
		ccdreturn_cmd;;

	cmmstep3)
		ccdstep3_cmd ;;

	cmmstep4)
		ccdstep4_cmd ;;

	cmmstep9)
		#
        	#       Netdisk
        	#
        	# CCD: setflag to indicate that the transition completed
        	#
        	if [ -f ${CCDRESTARTING} ]; then
              		/usr/bin/rm -rf ${CCDRESTARTING}
        	fi
		;;
	*) 
		;;
esac		

exit 0


##############################################################
# End of CCD reconf Programs				     #
##############################################################






