Home | History | Annotate | Download | only in PostgreSQL
      1 #
      2 # CDDL HEADER START
      3 #
      4 # The contents of this file are subject to the terms of the
      5 # Common Development and Distribution License (the License).
      6 # You may not use this file except in compliance with the License.
      7 #
      8 # You can obtain a copy of the license at usr/src/CDDL.txt
      9 # or http://www.opensolaris.org/os/licensing.
     10 # See the License for the specific language governing permissions
     11 # and limitations under the License.
     12 #
     13 # When distributing Covered Code, include this CDDL HEADER in each
     14 # file and include the License file at usr/src/CDDL.txt.
     15 # If applicable, add the following below this CDDL HEADER, with the
     16 # fields enclosed by brackets [] replaced with your own identifying
     17 # information: Portions Copyright [yyyy] [name of copyright owner]
     18 #
     19 # CDDL HEADER END
     20 #
     21 
     22 #
     23 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24 # Use is subject to license terms.
     25 #
     26 
     27 # ident   "@(#)functions.ksh 1.13     08/05/15 SMI"
     28 
     29 PKG=SUNWscPostgreSQL
     30 METHOD=`basename $0`
     31 TASK_COMMAND=""
     32 
     33 ZONENAME=/usr/bin/zonename
     34 DIRNAME=/usr/bin/dirname
     35 
     36 SCLOGGER=/usr/cluster/lib/sc/scds_syslog
     37 PMFADM=/usr/cluster/bin/pmfadm
     38 GETENT=/usr/bin/getent
     39 AWK=/usr/bin/awk
     40 NAWK=/usr/bin/nawk
     41 CAT=/usr/bin/cat
     42 EGREP=/usr/bin/egrep
     43 GREP=/usr/bin/grep
     44 ENV=/usr/bin/env
     45 HEAD=/usr/bin/head
     46 PS=/usr/bin/ps
     47 PGREP=/usr/bin/pgrep
     48 KILL=/usr/bin/kill
     49 IPCS=/usr/bin/ipcs
     50 IPCRM=/usr/bin/ipcrm
     51 ECHO=/usr/bin/echo
     52 TR=/usr/bin/tr
     53 SU=/usr/bin/su
     54 RM=/usr/bin/rm
     55 ZLOGIN=/usr/sbin/zlogin
     56 TEST=/usr/bin/test
     57 PING=/usr/sbin/ping
     58 SED=/usr/bin/sed
     59 IFCONFIG=/usr/sbin/ifconfig
     60 SSH=/usr/bin/ssh
     61 SSH_AGENT=/usr/bin/ssh-agent
     62 PKILL=/usr/bin/pkill
     63 WC=/usr/bin/wc
     64 SLEEP=/usr/bin/sleep
     65 TOUCH=/usr/bin/touch
     66 CHOWN=/usr/bin/chown
     67 CP=/usr/bin/cp
     68 
     69 get_fmri_parameters ()
     70 {
     71 
     72 # extract the smf properties, you need to call your agent commands
     73 
     74         debug_message "Function: get_fmri_parameters - Begin "
     75         ${SET_DEBUG}
     76 
     77 # Resource name
     78 
     79 	RESOURCE=`/usr/bin/svcprop -p parameters/Resource ${SMF_FMRI}`
     80 
     81 # Resource Group
     82 
     83 	RESOURCEGROUP=`/usr/bin/svcprop -p parameters/Resource_group ${SMF_FMRI}`
     84 
     85 # Start Project
     86 
     87 	Project=:default
     88 	if /usr/bin/svcprop ${SMF_FMRI}|grep start/project >/dev/null
     89 	then
     90 		Project=`/usr/bin/svcprop -p start/project ${SMF_FMRI}`
     91 		if [ "${Project}" != ":default" ]
     92 		then
     93 			PROJ_OPT=" -P ${Project}"
     94 			ZONE_PROJECT=${Project}
     95 		fi
     96 	fi
     97 
     98 # Parameter file
     99 
    100 	PARFILE=`/usr/bin/svcprop -p parameters/Parameter_File ${SMF_FMRI}`
    101 
    102         debug_message "Function: get_fmri_parameters - End "
    103 }
    104 
    105 set_shell_specifics()
    106 {
    107 
    108 	# Set variables to construct sourcing and output redirection depending 
    109 	# on the login shell of the user
    110 
    111         debug_message "Function: set_shell_specifics - Begin"
    112         ${SET_DEBUG}
    113 
    114 	ENVSC=
    115 
    116         if /usr/bin/getent passwd ${USER} | /usr/bin/awk -F: '{print $7}' | /usr/bin/grep csh > /dev/null
    117         then
    118 
    119 		# C shell specifics
    120 
    121 		# sourcing
    122 
    123 		if [ -n "${ENVSCRIPT}" ]
    124 		then
    125 			ENVSC="source ${ENVSCRIPT};"
    126 		fi
    127 
    128 		# brackets for subshells
    129 
    130 		OPEN_BRACKET="("
    131 		CLOSE_BRACKET=")"
    132 
    133 		# redirection
    134 
    135 		OUTPUT_APP=">>& ${LOGFILE}"
    136 		OUTPUT=">& ${LOGFILE}"
    137 		CAT_OUTPUT="> /tmp/${RESOURCE}-${USER}-cat-out"
    138 		CAT_ERRPUT=">& /tmp/${RESOURCE}-${USER}-cat-err"
    139 		TBL_OUTPUT="> /tmp/${RESOURCE}-${USER}-tbl-out"
    140 		TBL_ERRPUT=">& /tmp/${RESOURCE}-${USER}-tbl-err"
    141         else
    142 
    143 		# Korn shell specifics
    144 
    145 		# sourcing
    146 
    147 		if [ -n "${ENVSCRIPT}" ]
    148 		then
    149 			ENVSC=". ${ENVSCRIPT};"
    150 		fi
    151 
    152 		# no subshell needed in a ksh 
    153 
    154 		OPEN_BRACKET=
    155 		CLOSE_BRACKET=
    156 
    157 		# redirection
    158 
    159 	        OUTPUT_APP=">> ${LOGFILE} 2>&1"
    160 	        OUTPUT="> ${LOGFILE} 2>&1"
    161 		CAT_OUTPUT="> /tmp/${RESOURCE}-${USER}-cat-out"
    162 		CAT_ERRPUT="2> /tmp/${RESOURCE}-${USER}-cat-err"
    163 		TBL_OUTPUT="> /tmp/${RESOURCE}-${USER}-tbl-out"
    164 		TBL_ERRPUT="2> /tmp/${RESOURCE}-${USER}-tbl-err"
    165         fi
    166 
    167 
    168         debug_message "Function: set_shell_specifics - End"
    169 }
    170 
    171 create_pfile()
    172 {
    173 
    174 	# Creation of the parameter file. This function is used at registration
    175 	# time only.
    176 
    177         debug_message "Function: create_pfile - Begin "
    178         ${SET_DEBUG}
    179 
    180 	if [ -z "${PFILE}" ]
    181 	then
    182 		${ECHO} "ERROR: set the variable parameter file"
    183 		return 1
    184 	fi
    185 	
    186 	# determine wether the parameter file needs to be created in a zone or not
    187 
    188 	zonecmd=
    189 
    190 	pfile_tmp="/tmp/pgspfile.${RS}"
    191 
    192 	# get the zonename of the resource group
    193 
    194 	target_zone=$(rgs_zonename) 
    195 	if [ -n "${target_zone}" ]
    196 	then
    197 		zonecmd="${ZLOGIN} ${target_zone}"
    198 	fi
    199 
    200 	# check the directory of the parameter file
    201 
    202 	pdir=`${zonecmd} ${DIRNAME} ${PFILE}`
    203 
    204 	# test for the existance of the parameter files directory either in the local or
    205 	# the global zone according to the zone entry in the nodelist
    206 
    207 	if ! ${zonecmd} ${TEST} -d ${pdir}
    208 	then
    209 		${ECHO} "ERROR: set the variable parameter file in an existing directory"
    210 		return 1
    211 	fi
    212 
    213 	# create the parameter file 
    214 
    215 	${ECHO} "Prepare the parameter file ${PFILE}"
    216 
    217 	${CAT} <<EOF > ${pfile_tmp}
    218 	
    219 #
    220 # Content for the parameter file
    221 #
    222 #            USER - The Solaris user, which owns the PostgreSQL database
    223 #          PGROOT - Contains the path to the PostgreSQL directory. Below this
    224 #                   directory the postgres binaries are located in the ./bin
    225 #                   directory.
    226 #          PGDATA - Contains the path to the databases of this specific PostgreSQL
    227 #                   instance. The pg_hba.conf needs to be here.
    228 #          PGPORT - Port where the postmaster process will be listening to.
    229 #          PGHOST - Hostname where the postmaster process is listening to, or a directory where the
    230 #                   Unix socket file is stored.
    231 #                   If set to a valid hostname, the PGHOST variable forces the probe to 
    232 #                   traverse the TCP/IP stack. If the PGHOST variable is empty or starts with a "/", 
    233 #                   the probe will use a socket. If the PGHOST variable starts with a "/", the entry must
    234 #                   be the directory which contains the socket file. 
    235 #       PGLOGFILE - Logfile where the log messages of the postmaster will be stored.
    236 # LD_LIBRARY_PATH - This path contains all the necessary libraries for this PostgreSQL
    237 #                   installation.
    238 #                   Optional
    239 #       ENVSCRIPT - Script to contain PostgreSQL specific runtime variables.
    240 #                   Optional
    241 #            SCDB - This specific PostgreSQL database will be monitored.
    242 #          SCUSER - PostgresSQL user to connect to the $SCDB database.
    243 #         SCTABLE - Table name in the $SCDB database. This table name will be manipulated
    244 #                   to check if PostgreSQL is alive. This table will be generated at database
    245 #                   preparation time.
    246 #          SCPASS - Password of the SCUSER. If no password is provided the authentication method 
    247 #                   for the SCDB database needs to be trusted for requests from the localhost.
    248 #                   Optional
    249 #        NOCONRET - Return code for connection errors. This return code has to follow the rules
    250 #                   for the generic data service. The value has to be between 1 and 100.
    251 #                   100/NOCONRET defines the number of consecutive probes to ignore for failed
    252 #                   connections. A restart or failover will occur, if the number is exeeded within
    253 #                   the retry interval.
    254 
    255 
    256 USER=${USER}
    257 PGROOT=${PGROOT}
    258 PGDATA=${PGDATA}
    259 PGPORT=${PGPORT}
    260 PGHOST=${PGHOST}
    261 PGLOGFILE=${PGLOGFILE}
    262 LD_LIBRARY_PATH=${LD_LIBRARY_PATH}
    263 ENVSCRIPT=${ENVSCRIPT}
    264 SCDB=${SCDB}
    265 SCUSER=${SCUSER}
    266 SCTABLE=${SCTABLE}
    267 SCPASS=${SCPASS}
    268 NOCONRET=${NOCONRET}
    269 
    270 # The following parameters need to be configured only if logfile shipping is configured to ship
    271 # the PosgreSQL WAL logs between a designated primary and a designated standby resource.
    272 # They need to be configured only on the primary.
    273 
    274 #        STDBY_RS  The resource name of the PostgreSQL standby resource.
    275 #        STDBY_RG  The resource group name of the PostgreSQL standby resource group.
    276 #      STDBY_USER  User which is the owner of the standby postgres database.
    277 #      STDBY_HOST  Resolvable name of the standby host or the standby zone, 
    278 #                  this name has to be reachable via ssh.
    279 #   STDBY_PARFILE  The standbys postgres parameter file to get the rest of the necessary parameters.
    280 #   STDBY_PING     The number of packets the primary uses to ping the standby host. If this variable is
    281 #                  empty, it will be set to 5 packets.
    282 #   ROLECHG_RS     The rolechangers resource name.
    283 #  SSH_PASSDIR     A directory where the ssh passphrase is stored in a the file <resourcename>-phrase.
    284 #                  This parameter is needed only if you configured WAL file shipping and secured your
    285 #                  ssh key with a passphrase.
    286 #                  Leave it undefined if the passprase is empty.
    287 #
    288 # If you configure the logfile shipping in a shared nothing topology, do not set the LH parameter.
    289 #
    290 # Configure the following paramters on the primary host.
    291 
    292 STDBY_RS=${STDBY_RS}
    293 STDBY_RG=${STDBY_RG}
    294 STDBY_USER=${STDBY_USER}
    295 STDBY_HOST=${STDBY_HOST}
    296 STDBY_PARFILE=${STDBY_PARFILE}
    297 STDBY_PING=${STDBY_PING}
    298 #
    299 # Configure the following paramter on the standby host.
    300 #
    301 ROLECHG_RS=${ROLECHG_RS}
    302 #
    303 # Configure the following parameter on both hosts.
    304 #
    305 SSH_PASSDIR=${SSH_PASSDIR}
    306 
    307 EOF
    308 	if [ $? -ne 0 ]
    309 	then
    310 		${ECHO} "ERROR: could not create the temporary parameter file ${pfile_tmp}"
    311 		return 1
    312 	fi
    313 
    314 	# create the parameter file either in the global or in the prepared target zone
    315 
    316 	if [ -n "${target_zone}" ]
    317 	then
    318 		${CAT} ${pfile_tmp} | ${zonecmd} ${CAT} - \>${PFILE} 
    319 		if [ $? -ne 0 ]
    320 		then
    321 			${ECHO} "ERROR: could not create the parameter file ${PFILE}"
    322 			return 1
    323 		fi
    324 	else
    325 		${CAT} ${pfile_tmp} > ${PFILE}
    326 		if [ $? -ne 0 ]
    327 		then
    328 			${ECHO} "ERROR: could not create the parameter file ${PFILE}"
    329 			return 1
    330 		fi
    331 	fi
    332 		
    333         debug_message "Function: create_pfile - End "
    334 	return 0
    335 }
    336 
    337 validate_options()
    338 {
    339         debug_message "Function: validate_options - Begin"
    340 	${SET_DEBUG}
    341 
    342         #
    343         # Ensure all mandatory options are set
    344         #
    345 
    346         for i in RESOURCE RESOURCEGROUP PARFILE
    347         do
    348                 case ${i} in
    349                         RESOURCE)
    350                         if [ -z "${RESOURCE}" ]; then
    351                                 # SCMSGS
    352                                 # @explanation
    353                                 # The start, stop or probe command requires an
    354                                 # option which is not set.
    355                                 # @user_action
    356                                 # Fix the start, stop or probe command in the
    357                                 # SUNW.gds resource.
    358                                 scds_syslog -p daemon.err -t $(syslog_tag) -m \
    359                                 	"Function: validate_options: %s Option %s not set" \
    360                                 	"${METHOD}" "-R"
    361                                 return 1
    362                         fi;;
    363 
    364                         RESOURCEGROUP)
    365                         if [ -z "${RESOURCEGROUP}" ]; then
    366                                 scds_syslog -p daemon.err -t $(syslog_tag) -m \
    367 	                                "Function: validate_options: %s Option %s not set" \
    368                                 	"${METHOD}" "-G"
    369                                 return 1
    370                         fi;;
    371 
    372                         PARFILE)
    373                         if [ -z "${PARFILE}" ]; then
    374                                 scds_syslog -p daemon.err -t $(syslog_tag) -m \
    375 	                                "Function: validate_options: %s Option %s not set" \
    376                                 	"${METHOD}" "-P"
    377                                 return 1
    378                         fi;;
    379                 esac
    380         done
    381 
    382 	debug_message "Function: validate_options - End"
    383 }
    384 
    385 validate()
    386 {
    387 	#
    388 	# Validate
    389 	#
    390 	
    391         debug_message "Function: validate - Begin"
    392 	${SET_DEBUG}
    393 
    394 	rc_validate=0
    395 
    396 	if ! val_parfile ${PARFILE} "USER PGROOT PGDATA PGPORT PGLOGFILE SCDB SCUSER SCTABLE NOCONRET"
    397 	then
    398 		debug_message "Function: validate - End"
    399 		rc_validate=1
    400 		return ${rc_validate}
    401 	fi
    402 
    403 	. ${PARFILE}
    404 
    405 	for i in `${CAT} ${PARFILE} |grep -v "^#"|grep -v "^ "|nawk -F= '{print $1}'`
    406 	do
    407 		case $i in
    408 			USER)
    409 
    410 			# Test the PostgresSQL OS user
    411 
    412                         if [ -z "${USER}" ]; then
    413 				# SCMSGS
    414 				# @explanation
    415 				# A mandatory variable is unset in the
    416 				# parameter file.
    417 				# @user_action
    418 				# Fix the parameter file and provide a value
    419 				# for the variable in the parameter file
    420 				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    421 					"Function: validate: The %s variable is not set, but it is required" \
    422 					"USER"
    423 				rc_validate=1
    424 			else
    425 				id ${USER} >/dev/null 2>&1
    426 				if [ $? -ne 0 ]; then
    427    					# SCMSGS
    428    					# @explanation
    429    					# The user mentioned in the parameter
    430    					# file is not defined in the OS.
    431    					# @user_action
    432    					# Fix the parameter file and provide
    433    					# an existing user for the variable
    434    					# USER.
    435    					scds_syslog -p daemon.err -t $(syslog_tag) -m \
    436 						"Function: validate: User %s does not exist, an existing user is required" \
    437 						"${USER}"
    438 					rc_validate=1
    439 				else 
    440 					debug_message "Function: validate - USER OK"	
    441                         	fi
    442                         fi;;
    443 
    444 			PGROOT)
    445 
    446 			# Test the PG Root variable
    447 	                      
    448                         if [ -z "${PGROOT}" ]; then
    449    				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    450                                 	"Function: validate: The %s variable is not set, but it is required" \
    451 					"PGROOT"
    452 				rc_validate=1
    453 			else
    454 	                        if [ ! -d ${PGROOT} ]; then
    455 	   				# SCMSGS
    456 	   				# @explanation
    457 	   				# The directory mentioned in the
    458 	   				# parameter file for the PGROOT or
    459 	   				# PGDATA variable does not exist.
    460 	   				# @user_action
    461 	   				# Fix the parameter file and provide
    462 	   				# an existing directoy for the
    463 	   				# variable PGROOT or PGDATA.
    464 	   				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    465 	                                	"Function: validate: Directory %s does not exist, an existing directory is required" \
    466 						"${PGROOT}"
    467 					rc_validate=1
    468 	                        fi
    469 
    470 				# test if it is a postgres installation
    471 
    472 				if [ ! -f ${PGROOT}/bin/pg_ctl ]
    473 				then
    474 	   				# SCMSGS
    475 	   				# @explanation
    476 	   				# The directory mentioned in the
    477 	   				# PGROOT variable does not contain the
    478 	   				# PostgreSQL binaries in its bin
    479 	   				# directory.
    480 	   				# @user_action
    481 	   				# Provide the directory which does
    482 	   				# contain at least the PostgreSQL
    483 	   				# binaries in the path ./bin.
    484 	   				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    485 	                                	"Function: validate: Directory %s does not contain the PostgreSQL binaries" \
    486 						"${PGROOT}"
    487 					rc_validate=1
    488 				else 
    489 					debug_message "Function: validate - PGROOT OK"	
    490 	                        fi
    491                         fi;;
    492 
    493 			PGDATA)
    494 
    495 			# Test the PG Data variable
    496 	                      
    497                         if [ -z "${PGDATA}" ]; then
    498    				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    499                                 	"Function: validate: The %s variable is not set, but it is required" \
    500 					"PGDATA"
    501 				rc_validate=1
    502 			else
    503 	                        if [ ! -d ${PGDATA} ]; then
    504 	   				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    505 	                                	"Function: validate: Directory %s does not exist, an existing directory is required" \
    506 						"${PGDATA}"
    507 					rc_validate=1
    508 	                        fi
    509 
    510 				# test if it is a postgres database cluster
    511 
    512 				if [ ! -f ${PGDATA}/postgresql.conf ]
    513 				then
    514 	   				# SCMSGS
    515 	   				# @explanation
    516 	   				# A directory is specified in the
    517 	   				# PGDATA variable which does not
    518 	   				# contain a postgresql.conf file.
    519 	   				# @user_action
    520 	   				# Specify a directory in the PGDATA
    521 	   				# variable in the parmeter file, which
    522 	   				# contains the postgresql.conf file.
    523 	   				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    524 	                                	"Function: validate: Directory %s does not contain the PostgreSQL configuration files" \
    525 						"${PGDATA}"
    526 					rc_validate=1
    527 				else 
    528 					debug_message "Function: validate - PGDATA OK"	
    529 	                        fi
    530                         fi;;
    531 
    532 			PGPORT) 
    533 
    534 			# Test the PG Port variable
    535 	                      
    536                         if [ -z "${PGPORT}" ]; then
    537    				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    538                                 	"Function: validate: The %s variable is not set, but it is required" \
    539 					"PGPORT"
    540 				rc_validate=1
    541 			else
    542 
    543 				# test if the port is numeric
    544 
    545 	                        if  ! let x=${PGPORT} >/dev/null 2>&1
    546 				then
    547 	   				# SCMSGS
    548 	   				# @explanation
    549 	   				# In the parameter file, there is a
    550 	   				# non numeric character in the value
    551 	   				# for the PGPORT variable.
    552 	   				# @user_action
    553 	   				# Fix the PGPORT variable in the
    554 	   				# parameter file.
    555 	   				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    556 	                                	"Function: validate: Port %s is not numeric" \
    557 						"${PGPORT}"
    558 					rc_validate=1
    559 				else 
    560 					debug_message "Function: validate - PGPORT OK"	
    561 	                        fi
    562                         fi;;
    563 
    564 			PGHOST)
    565 
    566 			# test the PGHOST variable ony if it is defined
    567 
    568 			if [ -n "${PGHOST}" ]
    569 			then
    570 
    571 				# strip of leading spaces
    572 
    573 				PGHOST=`print ${PGHOST}|${SED} 's/^ *//'`
    574 
    575 				if ${ECHO} ${PGHOST} | ${GREP} "^/" >/dev/null 2>&1
    576 				then
    577 			
    578 					if [ ! -d "${PGHOST}" ]
    579 					then
    580 						
    581 						# SCMSGS
    582 						# @explanation
    583 						# The directory specified in the PGHOST variable does not
    584 						# exist.
    585 						# @user_action
    586 						# Create the directory. None if it was a lost mount.
    587 						scds_syslog -p daemon.err -t $(syslog_tag) -m \
    588 							"Function: validate - Directory for the socket file %s does not exist" \
    589 							"${PGHOST}"
    590 						rc_validate=1
    591 			
    592 					else
    593 						debug_message "Function: validate - PGHOST OK"	
    594 					fi
    595 				
    596 				else
    597 					if ! ${GETENT} hosts ${PGHOST} >/dev/null 2>&1
    598 					then
    599 						
    600 						# SCMSGS
    601 						# @explanation
    602 						# The host specified in the PGHOST variable is not
    603 						# resolvable.
    604 						# @user_action
    605 						# Create the the host entry in /etc/hosts.
    606 						scds_syslog -p daemon.err -t $(syslog_tag) -m \
    607 							"Function: validate - The host %s is not resolvable" \
    608 							"${PGHOST}"
    609 						rc_validate=1
    610 						
    611 					else
    612 						debug_message "Function: validate - PGHOST resolvable"	
    613 					fi
    614 
    615 					# Validate if the address of the PGHOST variable is configured UP
    616 					# on a adapter of the host. This validation works in
    617 					# global zones, local zones and in failover zones.
    618 					# This method was preferred over checking the dependency tree,
    619 					# because it works in failover zones, even if there is no logical
    620 					# host configured. 
    621 
    622 					# Set the laguage to C to avoid localisation problems with ifconfig
    623 
    624 					LANG=C
    625 
    626 					addr=`${GETENT} hosts ${PGHOST}| ${AWK} '{print $1}'`
    627 
    628 					# Check if the address is configured up on the node
    629 	
    630 					adapter_success=1
    631 					for i in `${IFCONFIG} -a |${GREP} UP|${AWK} '{print $1}' |${EGREP} -v "zone|inet"|${GREP} ":$"|${SED} s/:$//`
    632 					do
    633 
    634 						${IFCONFIG} ${i}|${GREP} ${addr} >/dev/null 2>&1
    635 						if [ ${?} -eq 0 ]
    636 						then
    637 							adapter_success=0
    638 						fi
    639 
    640 					done
    641 
    642 					if [ ${adapter_success} -ne 0 ]
    643 					then
    644 						
    645 						# SCMSGS
    646 						# @explanation
    647 						# The host specified in the PGHOST variable is not
    648 						# configured up on the hosts adapters.
    649 						# @user_action
    650 						# Fix either the network configuration or the PGHOST variable
    651 						scds_syslog -p daemon.err -t $(syslog_tag) -m \
    652 							"Function: validate - The host %s is not configured UP on the hosts adapters" \
    653 							"${PGHOST}"
    654 						rc_validate=1
    655 					else
    656 						debug_message "Function: validate - PGHOST is configured on the nodes adapters"	
    657 					fi
    658 				fi
    659 			fi;;
    660 
    661 			PGLOGFILE)
    662 
    663 			# Test the Logfile variable
    664 	                      
    665                         if [ -z "${PGLOGFILE}" ]; then
    666    				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    667                                 	"Function: validate: The %s variable is not set, but it is required" \
    668 					"PGLOGFILE"
    669 				rc_validate=1
    670 			else
    671 
    672 				# test if the directory for Logfile exists
    673 
    674 				Logdir=`/usr/bin/dirname ${PGLOGFILE}`
    675 	                        if [ ! -d ${Logdir} ]; then
    676 	   				# SCMSGS
    677 	   				# @explanation
    678 	   				# The path to the filename variable
    679 	   				# PGLOGFILE does not exist.
    680 	   				# @user_action
    681 	   				# Qualify the filename of the parameter
    682 	   				# files PGLOGFILE variable in an
    683 	   				# existing directory.
    684 	   				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    685 	                                	"Function: validate: Directory for logfile %s does not exist, an existing directory is required" \
    686 						"${PGLOGFILE}"
    687 					rc_validate=1
    688 				else 
    689 					debug_message "Function: validate - PGLOGFILE OK"	
    690 	                        fi
    691                         fi;;
    692 
    693 			LD_LIBRARY_PATH)
    694 
    695 			# test LD_LIBRARY_PATH if it is set
    696 
    697 			if [ -n "${LD_LIBRARY_PATH}" ]
    698 			then
    699 				export LD_LIBRARY_PATH
    700 				if ! ${PGROOT}/bin/psql --help >/dev/null 2>&1
    701 				then
    702 	   				# SCMSGS
    703 	   				# @explanation
    704 	   				# The LD_LIBRARY_PATH is not valid to
    705 	   				# call the postgres binary.
    706 	   				# @user_action
    707 	   				# Qualify the LD_LIBRARY_PATH in the
    708 	   				# parameter file until it is
    709 	   				# sufficient for the psql binary.
    710 	   				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    711 	                                	"Function: validate: The LD_LIBRARY_PATH %s is not valid for this PostgreSQL installation" \
    712 						"${LD_LIBRARY_PATH}"
    713 					rc_validate=1
    714 				else 
    715 					debug_message "Function: validate - LD_LIBRARY_PATH OK"	
    716 				fi
    717 			fi;;
    718 
    719 			ENVSCRIPT) 
    720 
    721 			# test if the environment script is a syntactically valid script
    722 			# In the smf context it needs to be a ksh script.
    723 			# In the GDS context the script type ksh/csh is dependent from the login shell of the user.
    724 
    725 			if [ -n "${ENVSCRIPT}" ]
    726 			then
    727 				if [ -f ${ENVSCRIPT} ]
    728 				then
    729 					if ${GETENT} passwd ${USER} | ${AWK} -F: '{print $7}' | ${GREP} "csh" > /dev/null  && [ -z "${SMF_FMRI}" ]
    730 					then
    731 						if ! /usr/bin/csh -n ${ENVSCRIPT} > /dev/null 2>&1
    732 						then
    733 			   				# SCMSGS
    734 			   				# @explanation
    735 			   				# The environment
    736 			   				# script specified in
    737 			   				# the parameter file
    738 			   				# needs to be a valid
    739 			   				# c shell script,
    740 			   				# because the login
    741 			   				# shell of the
    742 			   				# PostgreSQL user is c
    743 			   				# shell compliant.
    744 			   				# @user_action
    745 			   				# Fix the environment
    746 			   				# script until it
    747 			   				# passes csh -n
    748 			   				# scriptname.
    749 			   				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    750 			                                "Function: validate: The Environment script %s is not a valid c shell script" \
    751 							"${ENVSCRIPT}"
    752 							rc_validate=1
    753 						else 
    754 							debug_message "Function: validate - ENVSCRIPT OK"	
    755 						fi
    756 					else
    757 						if ! /usr/bin/ksh -n ${ENVSCRIPT} >/dev/null 2>&1
    758 						then
    759 		   					# SCMSGS
    760 		   					# @explanation
    761 		   					# The environment
    762 		   					# script specified in
    763 		   					# the parameter file
    764 		   					# needs to be a valid
    765 		   					# korn shell script,
    766 		   					# because the login
    767 		   					# shell of the
    768 		   					# PostgreSQL user is
    769 		   					# korn shell
    770 		   					# compliant.
    771 		   					# @user_action
    772 		   					# Fix the environment
    773 		   					# script until it
    774 		   					# passes ksh -n
    775 		   					# scriptname.
    776 		   					scds_syslog -p daemon.err -t $(syslog_tag) -m \
    777 		               	 	                	"Function: validate: The Environment script %s is not a valid korn shell script" \
    778 								"${ENVSCRIPT}"
    779 							rc_validate=1
    780 						else 
    781 							debug_message "Function: validate - ENVSCRIPT OK"	
    782 						fi
    783 					fi
    784 				else
    785 			   		# SCMSGS
    786 			   		# @explanation
    787 			   		# The filename specified in the
    788 			   		# parameter files ENVSCRIPT variable
    789 			   		# does not exist.
    790 			   		# @user_action
    791 			   		# Fix the parameter file and specify a
    792 			   		# valid Environment script.
    793 			   		scds_syslog -p daemon.err -t $(syslog_tag) -m \
    794 			                	"Function: validate: The Environment script %s does not exist" \
    795 						"${ENVSCRIPT}"
    796 					rc_validate=1
    797 			
    798 				fi
    799 			fi;;
    800 
    801 			SCDB) 
    802 
    803 			# Test if the test database variable is defined
    804 	                      
    805                         if [ -z "${SCDB}" ]; then
    806    				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    807                                 	"Function: validate: The %s variable is not set, but it is required" \
    808 					"SCDB"
    809 				rc_validate=1
    810 			else 
    811 				debug_message "Function: validate - SCDB OK"	
    812 			fi;;
    813 
    814 			SCUSER)
    815 
    816 			# Test if the database user variable is defined
    817 	                      
    818                         if [ -z "${SCUSER}" ]; then
    819    				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    820                                 	"Function: validate: The %s variable is not set, but it is required" \
    821 					"SCUSER"
    822 				rc_validate=1
    823 			else 
    824 				debug_message "Function: validate - SCUSER OK"	
    825 			fi;;
    826 
    827 			SCTABLE)
    828 
    829 			# Test if the database table variable is defined
    830 	                      
    831                         if [ -z "${SCTABLE}" ]; then
    832    				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    833                                 	"Function: validate: The %s variable is not set, but it is required" \
    834 					"SCTABLE"
    835 				rc_validate=1
    836 			else 
    837 				debug_message "Function: validate - SCTABLE OK"	
    838 			fi;;
    839 
    840 			NOCONRET)
    841 
    842 			# Test the No Connection return code  variable
    843 	                      
    844                         if [ -z "${NOCONRET}" ]; then
    845    				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    846                                 	"Function: validate: The %s variable is not set, but it is required" \
    847 					"NOCONRET"
    848 				rc_validate=1
    849 			else
    850 
    851 				# test if the NOCONRET is numeric
    852 
    853 	                        if  ! let x=${NOCONRET} >/dev/null 2>&1
    854 				then
    855 	   				# SCMSGS
    856 	   				# @explanation
    857 	   				# The value for the NOCONRET variable
    858 	   				# contains a non numeric character.
    859 	   				# @user_action
    860 	   				# Fix the NOCONRET variable in the
    861 	   				# parameter file.
    862 	   				scds_syslog -p daemon.err -t $(syslog_tag) -m \
    863 	                                	"Function: validate: Return code for failed connections %s is not numeric" \
    864 						"${NOCONRET}"
    865 					rc_validate=1
    866 				else 
    867 					if [ ${NOCONRET} -gt 100 ]; then
    868 	   					# SCMSGS
    869 	   					# @explanation
    870 	   					# The value of the NOCONRET
    871 	   					# variable in the parameter
    872 	   					# file exeeds 100.
    873 	   					# @user_action
    874 	   					# Fix the parameter file with
    875 	   					# a value below 100.
    876 	   					scds_syslog -p daemon.err -t $(syslog_tag) -m \
    877 	                                		"Function: validate: Return code for failed connections %s is greater 100" \
    878 							"${NOCONRET}"
    879 						rc_validate=1
    880 					else
    881 						debug_message "Function: validate - NOCONRET OK"	
    882 					fi
    883 	                        fi
    884                         fi;;
    885 
    886 			STDBY_HOST) 
    887 
    888 			# Test the standby host variable and the neccessary other variables if the standby 
    889 			# host variable is not set.
    890 	                      
    891 			if [ -n "${STDBY_HOST}" ]; then
    892 				if ! ${GETENT} hosts ${STDBY_HOST} >/dev/null 2>&1
    893 				then
    894 			
    895 					# SCMSGS
    896 					# @explanation
    897 					# The host specified in the STDBY_HOST variable is not
    898 					# resolvable.
    899 					# @user_action
    900 					# Add the host to one of your configured name services, 
    901 					# so it can get listed with getent.
    902 					scds_syslog -p daemon.err -t $(syslog_tag) -m \
    903 						"Function: validate - The standby host %s is not resolvable" \
    904 						"${STDBY_HOST}"
    905 					rc_validate=1
    906 						
    907 				else
    908 					debug_message "Function: validate - STDBY_HOST resolvable"	
    909 				fi
    910 
    911 				# Test if all the other standby related variables are set.
    912 				# There will be no other validation, because it may be that the necessary
    913 				# resources are not up right now, and then the validation will fail without 
    914 				# a valid reason which is related to the parameter configuration.
    915 
    916 				if [ -z "${STDBY_RS}" ]
    917 				then
    918    					scds_syslog -p daemon.err -t $(syslog_tag) -m \
    919 						"Function: validate: The %s variable is not set, but it is required" \
    920 						"STDBY_RS"
    921 					rc_validate=1
    922 				else
    923 					debug_message "Function: validate - STDBY_RS OK"
    924 				fi
    925 
    926 				if [ -z "${STDBY_RG}" ]
    927 				then
    928    					scds_syslog -p daemon.err -t $(syslog_tag) -m \
    929 						"Function: validate: The %s variable is not set, but it is required" \
    930 						"STDBY_RG"
    931 					rc_validate=1
    932 				else
    933 					debug_message "Function: validate - STDBY_RG OK"
    934 				fi
    935 
    936 				if [ -z "${STDBY_USER}" ]
    937 				then
    938    					scds_syslog -p daemon.err -t $(syslog_tag) -m \
    939 						"Function: validate: The %s variable is not set, but it is required" \
    940 						"STDBY_USER"
    941 					rc_validate=1
    942 				else
    943 					debug_message "Function: validate - STDBY_USER OK"
    944 				fi
    945 
    946 				if [ -z "${STDBY_PARFILE}" ]
    947 				then
    948    					scds_syslog -p daemon.err -t $(syslog_tag) -m \
    949 						"Function: validate: The %s variable is not set, but it is required" \
    950 						"STDBY_PARFILE"
    951 					rc_validate=1
    952 				else
    953 					debug_message "Function: validate - STDBY_PARFILE OK"
    954 				fi
    955 
    956 				if [ -n "${STDBY_PING}" ]
    957 				then
    958 	                        	if  ! let x=${STDBY_PING} >/dev/null 2>&1
    959 					then
    960 						# SCMSGS
    961 						# @explanation
    962 						# In the parameter file, there is a
    963 						# non numeric character in the value
    964 						# for the STDBY_PING variable.
    965 						# @user_action
    966 						# Fix the STDBY_PING variable in the
    967 						# parameter file.
    968 
    969    						scds_syslog -p daemon.err -t $(syslog_tag) -m \
    970 							"Function: validate: The STDBY_PING value of %s is not numeric" \
    971 							"${STDBY_PING}"
    972 						rc_validate=1
    973 					else
    974 						debug_message "Function: validate - STDBY_PING OK"
    975 					fi
    976 				else
    977 					# set a default of 5 packets
    978 					STDBY_PING=5
    979 					debug_message "Function: validate - STDBY_PING OK, it was set to 5 packets"
    980 				fi
    981 
    982 			fi;;
    983 		esac
    984 	done
    985 
    986 	debug_message "Function: validate - End"
    987 	return ${rc_validate}
    988 }
    989 
    990 validate_probe()
    991 {
    992 	# Validate ony for non existant files or lost directories
    993 
    994         debug_message "Function: validate_probe - Begin"
    995 	${SET_DEBUG}
    996 	
    997 	rc_val_probe=0
    998 	
    999 	# If the parameter file does not pass the short validation, try a failover
   1000 	# A failover is the appropriate action, because the directory existed
   1001 	# at startup of the resource.
   1002 
   1003 	if ! val_parfile ${PARFILE}
   1004 	then
   1005 
   1006 
   1007                 # SCMSGS
   1008                	# @explanation
   1009                	# The file specified in the PARFILE variable does not
   1010 		# exist any more.
   1011                	# @user_action
   1012                	# Create the directory and restore the parameter file. None if it was a lost mount.
   1013                	scds_syslog -p daemon.err -t $(syslog_tag) -m \
   1014                		"Function: validate_probe - Directory for the parameter file %s does not exist any more, a faiover will occur" \
   1015               		"${PARFILE}"
   1016 
   1017 		rc_val_probe=201
   1018 	fi
   1019 
   1020 	# source the parameter file
   1021 
   1022 	. ${PARFILE}
   1023 
   1024 	# Check the PGHOST variable.
   1025 	# If the PGHOST variable starts with a / then it should be a directory which contains the socket file.
   1026 	# If this directory is not available, a failover will be initiated.
   1027 	# If it does not contain a / then it has to be a hostname or an address, in this case the hostname 
   1028 	# has to respond to ping. 
   1029 
   1030 	if [ -n "${PGHOST}" ]
   1031 	then
   1032 
   1033 		# strip of leading spaces
   1034 
   1035 		PGHOST=`print ${PGHOST}|${SED} 's/^ *//'`
   1036 
   1037 		if ${ECHO} ${PGHOST} | ${GREP} "^/" >/dev/null 2>&1
   1038 		then
   1039 	
   1040 			if [ ! -d "${PGHOST}" ]
   1041 			then
   1042 				
   1043 	                	# SCMSGS
   1044 	                	# @explanation
   1045 	                	# The directory specified in the PGHOST variable does not
   1046 				# exist any more.
   1047 	                	# @user_action
   1048 	                	# Create the directory. None if it was a lost mount.
   1049 	                	scds_syslog -p daemon.err -t $(syslog_tag) -m \
   1050 	                  		"Function: validate_probe - Directory for the socket file %s does not exist any more, a faiover will occur" \
   1051 	                  		"${PGHOST}"
   1052 				rc_val_probe=201
   1053 			else
   1054 				debug_message "Function: validate_probe - the directory in PGHOST exists"
   1055 			fi
   1056 		
   1057 		else
   1058 
   1059 			# If an address is specified, test it with ping. Initiate a failover if the address 
   1060 			# is unavailable.	
   1061 			# This needs to be done, because an unpingable address will cause the psql commands to hang
   1062 			# The test will detect accidentally unconfigured interfaces, just a failover or restart of 
   1063 			# the resource group can cure this problem.
   1064 
   1065 			# This ping test is here to prevent a predictable timeout, it is needed as long as 
   1066 			# SUNW.LogicalHost does not probe the ipaddresses. As soon as this changes the
   1067 			# ping test should be removed.
   1068 
   1069 			if ! ${PING} ${PGHOST} 1 >/dev/null 2>&1
   1070 			then
   1071 				# SCMSGS
   1072 				# @explanation
   1073 				# The address specified in the PGHOST variable
   1074 				# is unavailable.
   1075 				# @user_action
   1076 				# None, a failover will occur
   1077 				scds_syslog -p daemon.err -t $(syslog_tag) -m \
   1078  	            			"check_pgs: The host %s is not accessible, a failover will occur" \
   1079 	      	       			"${PGHOST}"
   1080 	
   1081 				rc_val_probe=201
   1082 			else
   1083 				debug_message "Function: validate_probe - the host in PGHOST is pingable"
   1084 			fi
   1085 		fi
   1086 	fi
   1087 
   1088         debug_message "Function: validate_probe - End"
   1089 	return $rc_val_probe
   1090 }
   1091 
   1092 val_parfile()
   1093 {
   1094 	# Common valdation for parameter file
   1095 	#
   1096 	# If the parameter is in $2, there will be an intensive validation.
   1097 	# If $2 is empty, the validation will just check for the existance of the file.
   1098 	
   1099         debug_message "Function: val_parfile - Begin"
   1100 	${SET_DEBUG}
   1101 
   1102 	rc_val_parfile=0
   1103 
   1104         # Validate that parameter file exists
   1105 
   1106 	PARFILE=${1}
   1107         PARLIST=${2}
   1108 
   1109         if [ ! -f "${PARFILE}" ]; then
   1110                 # SCMSGS
   1111                 # @explanation
   1112                 # The parameter file does not exist in the parameter file
   1113                 # directory.
   1114                 # @user_action
   1115                 # Restore the parameter file or re-register the resource.
   1116                 scds_syslog -p daemon.err -t $(syslog_tag) -m \
   1117                   "Function: val_parfile - File %s does not exist" \
   1118                   "${PARFILE}"
   1119                 rc_val_parfile=1
   1120 	else
   1121 		debug_message "Function: val_parfile - ${PARFILE} exists"	
   1122  	fi
   1123 
   1124 	# Test the semantics only, if the parameter list is specified.
   1125 	# This should not be done when called from validate_probe.
   1126 
   1127 	if [ -n "${2}" ]
   1128 	then
   1129 	
   1130 		# Test if the parameter file is a valid ksh script</