# # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the License). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/CDDL.txt # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/CDDL.txt. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets [] replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" # PKG=SUNWscids LOGFILE=/var/tmp/${RESOURCE}_logfile TASK_COMMAND="" RESOURCE_PROJECT_NAME="" SCLOGGER=/usr/cluster/lib/sc/scds_syslog LOGGER=/usr/bin/logger syslog_tag() { ${SET_DEBUG} print "SC[${PKG:-??}.${COMPONENT:-??}.${METHOD:-??}]:${RESOURCEGROUP:-??}:${RESOURCE:-??}" } scds_syslog() { if [ -f "${SCLOGGER}" ] then ${SCLOGGER} "$@" & else while getopts 'p:t:m' opt do case "${opt}" in t) TAG=${OPTARG};; p) PRI=${OPTARG};; esac done shift $((${OPTIND} - 1)) LOG_STRING=`/usr/bin/printf "$@"` ${LOGGER} -p ${PRI} -t ${TAG} ${LOG_STRING} fi } debug_message() { if [ "${DEBUG}" = "${RESOURCE}" -o "${DEBUG}" = "ALL" ] then SET_DEBUG="set -x" DEBUG_TEXT=${1} scds_syslog -p daemon.debug -t $(syslog_tag) -m \ "%s" "${DEBUG_TEXT}" else SET_DEBUG= fi } log_message() { debug_message "Function: log_message - Begin" {SET_DEBUG} if [ -s "${LOGFILE}" ] then PRIORITY=$1 HEADER=$2 strings ${LOGFILE} > ${LOGFILE}.copy while read MSG_TXT do scds_syslog -p daemon.${PRIORITY} -t $(syslog_tag) -m \ "%s - %s" \ "${HEADER}" "${MSG_TXT}" done < ${LOGFILE}.copy cat /dev/null > ${LOGFILE} fi debug_message "Function: log_message - End" } set_redirection() { debug_message "Function: set_redirection - Begin" ${SET_DEBUG} if /usr/bin/getent passwd ${USERID} | /usr/bin/awk -F: '{print $7}' | /usr/bin/grep csh > /dev/null then OUTPUT=">& ${LOGFILE}" else OUTPUT="> ${LOGFILE} 2>&1" fi debug_message "Function: set_redirection - End" } validate() { debug_message "Function: validate - Begin" ${SET_DEBUG} rc=0 # Note that group/user informix is an IDS requirement. Refer to # http://publib.boulder.ibm.com/infocenter/idshelp/v111/index.jsp?topic # and in particular Installing IDS. if /usr/bin/getent passwd informix > /dev/null then debug_message "Validate - User informix exists" else # SCMSGS # @explanation # The userid informix does not exist. # @user_action # You must create the userid informix. scds_syslog -p daemon.error -t $(syslog_tag) -m \ "Validate - User informix does not exist" rc=1 fi if /usr/bin/getent group informix > /dev/null then debug_message "Validate - Group informix exists" else # SCMSGS # @explanation # The group informix does not exist. # @user_action # You must create the group informix. scds_syslog -p daemon.error -t $(syslog_tag) -m \ "Validate - Group informix does not exist" rc=1 fi if [ "${USERID}" = "informix" ] then debug_message "Validate - Userid is informix" else pgroup=`/usr/bin/getent passwd ${USERID} | /usr/bin/awk -F: '{print $4}'` if [ -n "${pgroup}" ] then if /usr/bin/getent group ${pgroup} | /usr/bin/awk -F: '{ if ($1 == "informix") print $3}' | \ /usr/bin/grep "^${pgroup}$" > /dev/null then debug_message "Validate - Primary group for userid ${USERID} is informix" else if /usr/bin/getent group informix | /usr/bin/awk -F: '{print $4}' | \ /usr/bin/grep ${USERID} > /dev/null then debug_message "Validate - Secondary group for userid ${USERID} is informix" else # SCMSGS # @explanation # The user is not a member of the group informix. # @user_action # Ensure the user is a member of the group informix. scds_syslog -p daemon.error -t $(syslog_tag) -m \ "Validate - Userid %s is not a member of group informix" \ "${USERID}" rc=1 fi fi else # SCMSGS # @explanation # The user is not a valid userid. # @user_action # Ensure the user name is correct. scds_syslog -p daemon.error -t $(syslog_tag) -m \ "Validate - User %s is not a valid userid" \ "${USERID}" rc=1 fi fi if [ -d "${INFORMIXDIR}" ] then debug_message "Validate - ${INFORMIXDIR} exists" if [ -x "${INFORMIXDIR}/bin/oninit" ] then debug_message "Validate - ${INFORMIXDIR}/bin/oninit exists and is executable" else # SCMSGS # @explanation # oninit was not found in ${INFORMIXDIR}/bin. # @user_action # Ensure that ${INFORMIXDIR} is the directory path # where the Informix files are installed. scds_syslog -p daemon.error -t $(syslog_tag) -m \ "Validate - %s/bin/oninit does not exist" \ "${INFORMIXDIR}" rc=1 fi else # SCMSGS # @explanation # ${INFORMIXDIR} does not exist or is not a directory. # @user_action # Ensure that ${INFORMIXDIR} is the directory path # where the Informix files are installed. scds_syslog -p daemon.error -t $(syslog_tag) -m \ "Validate - %s does not exist or is not a directory" \ "${INFORMIXDIR}" rc=1 fi # Here, we check that the ${ONCONFIG} file contains # the ROOTNAME variable, below is snipped sample # ${ONCONFIG} file containing ROOTNAME. # # ROOTNAME rootdbs # Root dbspace name if [ -f "${INFORMIXDIR}/etc/${ONCONFIG}" ] then debug_message "Validate - ${INFORMIXDIR}/etc/${ONCONFIG} exists" if /usr/xpg4/bin/grep -qw ROOTNAME ${INFORMIXDIR}/etc/${ONCONFIG} then debug_message "Validate - ROOTNAME found in ${INFORMIXDIR}/etc/${ONCONFIG}" else # SCMSGS # @explanation # ${INFORMIXDIR}/bin/${ONCONFIG} is not a valid onconfig file. # @user_action # Ensure that ${INFORMIXDIR}/etc/${ONCONFIG} is a valid onconfig file. scds_syslog -p daemon.error -t $(syslog_tag) -m \ "Validate - %s/bin/%s is not a valid onconfig file" \ "${INFORMIXDIR}" "${ONCONFIG}" rc=1 fi # Here, we check that the ${ONCONFIG} file contains # the ${INFORMIXSERVER} name, below is snipped sample # ${ONCONFIG} file containing ${INFORMIXSERVER}. # # DBSERVERNAME demo_on # # Note that ${INFORMIXSERVER} is represented by "demo_on". if /usr/xpg4/bin/grep -qw ${INFORMIXSERVER} ${INFORMIXDIR}/etc/${ONCONFIG} then debug_message "Validate - ${INFORMIXSERVER} found in ${INFORMIXDIR}/etc/${ONCONFIG}" else # SCMSGS # @explanation # ${INFORMIXDIR}/etc/${ONCONFIG} does not contain ${INFORMIXSERVER}. # @user_action # Ensure that ${INFORMIXDIR}/etc/${ONCONFIG} contains ${INFORMIXSERVER}. scds_syslog -p daemon.error -t $(syslog_tag) -m \ "Validate - %s/etc/%s does not contain %s" \ "${INFORMIXDIR}" "${ONCONFIG}" "${INFORMIXSERVER}" rc=1 fi else # SCMSGS # @explanation # ${INFORMIXDIR}/etc/${ONCONFIG} does not exist. # @user_action # Ensure that ${INFORMIXDIR}/etc/${ONCONFIG} exists. scds_syslog -p daemon.error -t $(syslog_tag) -m \ "Validate - %s/etc/%s does not exist" \ "${INFORMIXDIR}" "${ONCONFIG}" rc=1 fi # Here, we check that the ${INFORMIXSQLHOSTS} file contains # the ${INFORMIXSERVER} name, below is snipped sample # ${INFORMIXSQLHOSTS} file containing ${INFORMIXSERVER}. # # demo_on ontlitcp lzmutt1a 9088 # # Note that ${INFORMIXSERVER} is represented by "demo_on". if [ -f "${INFORMIXSQLHOSTS}" ] then debug_message "Validate - ${INFORMIXSQLHOSTS} exists" if /usr/xpg4/bin/grep -qw ${INFORMIXSERVER} ${INFORMIXSQLHOSTS} then debug_message "Validate - ${INFORMIXSERVER} found in ${INFORMIXSQLHOSTS}" else # SCMSGS # @explanation # ${INFORMIXSQLHOSTS} does not contain ${INFORMIXSERVER}. # @user_action # Ensure that ${INFORMIXSQLHOSTS} is contains ${INFORMIXSERVER}. scds_syslog -p daemon.error -t $(syslog_tag) -m \ "Validate - %s does not contain %s" \ "${INFORMIXSQLHOSTS}" "${INFORMIXSERVER}" rc=1 fi else # SCMSGS # @explanation # ${INFORMIXSQLHOSTS does not exist. # @user_action # Ensure that ${INFORMIXSQLHOSTS} exists. scds_syslog -p daemon.error -t $(syslog_tag) -m \ "Validate - %s does not exist" \ "${INFORMIXSQLHOSTS}" rc=1 fi if [ "${rc}" -eq 0 ] then # SCMSGS # @explanation # The Informix Server validation was successful. # @user_action # None required, informational message. scds_syslog -p daemon.info -t $(syslog_tag) -m \ "Validate - Informix Server (%s) validation was successful" \ "${INFORMIXSERVER}" fi debug_message "Function: validate - End" return ${rc} } start_ids() { debug_message "Function: start_ids - Begin" ${SET_DEBUG} /usr/bin/rm ${LOGFILE} > /dev/null if [ "${CALLER}" = "GDS" ] then get_state check_ids debug rc=$? # Check_ids will return 0 if # - The Informix Server is running # - No blocked on "MEDIA FAILURE" or "HANG_SYSTEM" exists if [ "${rc}" -eq 0 ] then # Turn off PMF restart if ${INFORMIXSERVER} has been manually started /usr/bin/sleep ${START_TIMEOUT} & /usr/cluster/bin/pmfadm -s ${RESOURCEGROUP},${RESOURCE},0.svc # SCMSGS # @explanation # The specified Informix Server has been manually started. # @user_action # None required. Informational message. scds_syslog -p daemon.notice -t $(syslog_tag) -m \ "start_ids - Informix Server (%s) was manually started" \ "${INFORMIXSERVER}" return 0 fi /usr/bin/su ${USERID} -c "${TASK_COMMAND} env INFORMIXDIR=${INFORMIXDIR} INFORMIXSERVER=${INFORMIXSERVER} INFORMIXSQLHOSTS=${INFORMIXSQLHOSTS} ONCONFIG=${ONCONFIG} ${INFORMIXDIR}/bin/oninit -y ${OUTPUT} &" > /dev/null else env INFORMIXDIR=${INFORMIXDIR} INFORMIXSERVER=${INFORMIXSERVER} INFORMIXSQLHOSTS=${INFORMIXSQLHOSTS} ONCONFIG=${ONCONFIG} ${INFORMIXDIR}/bin/oninit -y > ${LOGFILE} 2>&1 & fi rc=$? if [ "${rc}" -eq 0 ] then # SCMSGS # @explanation # The specified Informix Server was started successfully. # @user_action # None required. Informational message. scds_syslog -p daemon.info -t $(syslog_tag) -m \ "start_ids - Informix Server (%s) started rc(%s)" \ "${INFORMIXSERVER}" "${rc}" # At present there is no equivalent "wait_for_online" within SMF # therefore we'll perform our own. if [ "${CALLER}" = "SMF" ] then smf_wait_for_online rc=? fi else # SCMSGS # @explanation # The specified Informix Server failed to start. # @user_action # Check the syslog for further messages. If possible the # Solaris Cluster will attempt to restart the Informix # Server. scds_syslog -p daemon.error -t $(syslog_tag) -m \ "start_ids - Informix Server (%s) failed to start rc(%s)" \ "${INFORMIXSERVER}" "${rc}" log_message error "start_ids rc(${rc})" fi debug_message "Function: start_ids - End" return ${rc} } check_start() { debug_message "Function: check_start - Begin" ${SET_DEBUG} if [ "${CALLER}" = "GDS" ] then if [ -x /sbin/zonename ] then /usr/bin/pgrep -z ${ZONENAME} -f "$1 .*-R ${RESOURCE} " >/dev/null 2>&1 else /usr/bin/pgrep -u root -f "$1 .*-R ${RESOURCE} " >/dev/null 2>&1 fi else /usr/bin/pgrep -u ${USERID} -f "$1 ${RESOURCE} " >/dev/null 2>&1 fi rc=$? debug_message "Function: check_start - End" return ${rc} } get_state() { debug_message "Function: get_state - Begin" ${SET_DEBUG} # The Informix Dynamic Server has an operating mode which can be obtained # by using the "onstat -" utility that prints the output header of the # onstat utility. The format of the output header is as follows, # # Version--Mode (Type)--(Checkpnt)--Up Uptime--Sh_mem Kbytes # # "Version" will contain the product name and version number. # "Mode" will contain the currrent operating mode. # # In addition to the operating mode, the database maybe blocked from # performing any work. If the database is blocked, the blocked reason # is also displayed in the onstat output header. # # Of interest to us is "Version", "Mode" and any blocked reason. # # Under normal operation the product name within "Version" will contain # "IBM Informix Dynamic Server", after which "Mode" will reflect an # appropriate operating mode. Blocked states only appear once a "Mode" # is reached. # # The following shows two sample "onstat -" outputs, # Before IDS is started. # # shared memory not initialized for INFORMIXSERVER 'demo_on' # # After IDS is started. # # IBM Informix Dynamic Server Version 11.10.FC1 -- On-Line -- Up 01:47:59 -- 29696 Kbytes if [ "${CALLER}" = "GDS" ] then onstat_header=`/usr/bin/su ${USERID} -c "${TASK_COMMAND} env INFORMIXDIR=${INFORMIXDIR} INFORMIXSERVER=${INFORMIXSERVER} INFORMIXSQLHOSTS=${INFORMIXSQLHOSTS} ONCONFIG=${ONCONFIG} ${INFORMIXDIR}/bin/onstat - | /usr/bin/grep ."` else onstat_header=`env INFORMIXDIR=${INFORMIXDIR} INFORMIXSERVER=${INFORMIXSERVER} INFORMIXSQLHOSTS=${INFORMIXSQLHOSTS} ONCONFIG=${ONCONFIG} ${INFORMIXDIR}/bin/onstat - | /usr/bin/grep .` fi if echo ${onstat_header} | /usr/xpg4/bin/grep -q "Informix Dynamic Server" then onstat_mode=`echo ${onstat_header} | /usr/bin/sed -e 's/ -- Up.*$//' -e 's/^.*-- //'` if echo ${onstat_header} | /usr/xpg4/bin/grep -q "Blocked:" then onstat_blocked=`echo ${onstat_header} | /usr/bin/sed -e 's/^.*Blocked://'` else onstat_blocked="" fi fi debug_message "Function: get_state - End" } check_ids() { debug_message "Function: check_ids - Begin" ${SET_DEBUG} LEVEL=error [ "$1" = "debug" ] && LEVEL=debug # Check if IDS is starting up. if echo ${onstat_header} | /usr/xpg4/bin/grep -q "Changing data structure" then # SCMSGS # @explanation # The Informix Server database is starting up. # @user_action # None required. Solaris Cluster will restart the Informix Server # so that it is managed by Solaris Cluster. scds_syslog -p daemon.${LEVEL} -t $(syslog_tag) -m \ "check_ids - Database Instance %s is restarting" \ "${INFORMIXSERVER}" return 100 fi # Check if IDS is down. if echo ${onstat_header} | /usr/xpg4/bin/grep -q -E "shared memory not initialized|WARNING: IBM Informix Dynamic Server is no longer running" then # SCMSGS # @explanation # The Informix Server database is down. # @user_action # None required. Solaris Cluster will restart the Informix Server. scds_syslog -p daemon.${LEVEL} -t $(syslog_tag) -m \ "check_ids - Database Instance %s is down" \ "${INFORMIXSERVER}" return 100 fi # Check for any blocked states. # Regardless of the onstat_mode, if a blocked state of "MEDIA FAILURE" or # "HANG_SYSTEM" exists we will register a complete failure and indicate # that the DBA needs to be involved. if [ -n "${onstat_blocked}" ] then if echo "${onstat_blocked}" | /usr/xpg4/bin/grep -q -E "MEDIA_FAILURE|HANG_SYSTEM" then # SCMSGS # @explanation # The Informix Dynamic Server database has failed. # @user_action # Check the system log for error messages and contact your DBA. # Solaris Cluster will restart the Informix Server. scds_syslog -p daemon.${LEVEL} -t $(syslog_tag) -m \ "check_ids - Database Instance %s has failed mode(%s) blocked(%s), contact your DBA" \ "${INFORMIXSERVER}" "${onstat_mode}" "${onstat_blocked}" return 100 fi fi case "${onstat_mode}" in # Maintenance & Startup modes "Quiescent"|"Administration"|"Single User"|"Initialization"|"Fast Recovery"|"Recovery") rc=100 ;; # The following IDS server modes are acceptable normal operation modes. "On-Line"|"Read-only") # Normal operation modes rc=0 ;; # Any other IDS server modes are treated as a complete failure. *) # Unknown modes rc=100 ;; esac debug_message "check_ids - ${onstat_header}" if [ "${CALLER}" = "GDS" -a "${LEVEL}" != "debug" ] then # While we tolerate some blocked states we will output a status message # to Solaris Cluster if one is found. Nevertheless the resource remains online. saved_rc=${rc} # Check if GDS is still starting the resource. If GDS start has finished we'll set # the Solaris Cluster resource status with the appropriate Mode and any Blocked state. if ! check_start gds_svc_start then MESSAGE= [ -n "${onstat_mode}" ] && MESSAGE="Mode:${onstat_mode}" [ -n "${onstat_blocked}" ] && MESSAGE="${MESSAGE} Blocked:${onstat_blocked}" /usr/cluster/bin/scha_resource_setstatus -R ${RESOURCE} -G ${RESOURCEGROUP} -s OK -m "${MESSAGE}" fi rc=${saved_rc} fi debug_message "Function: check_ids - End" return ${rc} } stop_ids() { debug_message "Function: stop_ids - Begin" ${SET_DEBUG} MAX_STOP_TIMEOUT=`/usr/bin/expr ${STOP_TIMEOUT} \* 70 \/ 100` SECONDS=0 if [ "${CALLER}" = "GDS" ] then /usr/bin/su ${USERID} -c "${TASK_COMMAND} env INFORMIXDIR=${INFORMIXDIR} INFORMIXSERVER=${INFORMIXSERVER} INFORMIXSQLHOSTS=${INFORMIXSQLHOSTS} ONCONFIG=${ONCONFIG} ${INFORMIXDIR}/bin/onmode -uky ${OUTPUT} &" > /dev/null else env INFORMIXDIR=${INFORMIXDIR} INFORMIXSERVER=${INFORMIXSERVER} INFORMIXSQLHOSTS=${INFORMIXSQLHOSTS} ONCONFIG=${ONCONFIG} ${INFORMIXDIR}/bin/onmode -uky > ${LOGFILE} 2>&1 & fi while [ "${SECONDS}" -lt "${MAX_STOP_TIMEOUT}" ] do get_state if echo ${onstat_header} | /usr/xpg4/bin/grep -q "shared memory not initialized" then SECONDS=${MAX_STOP_TIMEOUT} else sleep 5 fi done # Note that the shutdown will be run in the background. As such the contents # of ${LOGFILE} is not of interest so we will clear that file. cat /dev/null > ${LOGFILE} get_state if ! echo ${onstat_header} | /usr/xpg4/bin/grep -q "shared memory not initialized" then /usr/cluster/bin/pmfadm -s ${RESOURCEGROUP},${RESOURCE},0.svc KILL 2> /dev/null fi debug_message "Function: stop_ids - End" return 0 } smf_wait_for_online() { debug_message "Function: smf_wait_for_online - Begin" ${SET_DEBUG} MAX_START_TIMEOUT=`/usr/bin/expr ${START_TIMEOUT} \* 95 \/ 100` SECONDS=0 while [ "${SECONDS}" -lt "${MAX_START_TIMEOUT}" ] do get_state check_ids rc=$? # Check_ids will return 0 if # - The Informix Server is running # - No blocked on "MEDIA FAILURE" or "HANG_SYSTEM" exists if [ "${rc}" -eq 0 ] then SECONDS=${MAX_START_TIMEOUT} else sleep 5 fi done debug_message "Function: smf_wait_for_online - End" return ${rc} } cleanup_ipc() { debug_message "Function: cleanup_ipc - Begin" ${SET_DEBUG} # Cleanup any IPC shared memory segments however only if # # - The shared memory segment(s) are owned by # OWNER=root and GROUP=informix # - The shared memory has no attached processes # - The CPID and LPID processes are not running flag= if [ "${DEBUG}" = "${RESOURCE}" -o "${DEBUG}" = "ALL" ] then debug_message "IPC Status BEFORE removal of non-attached segments created by group informix" /usr/bin/ipcs -mcopbZ | /usr/bin/grep " ${ZONENAME}$" > ${LOGFILE} log_message debug ipcs fi /usr/bin/ipcs -mcopbZ | /usr/bin/grep " ${ZONENAME}$" | /usr/bin/awk ' \ {if (NF == 13 && $5 == "root" && $6 == "informix" && $9 == 0 ) print $2,$11,$12; else \ if (NF == 12 && $4 == "root" && $5 == "informix" && $8 == 0 ) print $1,$10,$11 }' | \ while read SHMID CPID LPID do if /usr/bin/ps -p ${LPID} -o zone | /usr/bin/grep " ${ZONENAME}$" > /dev/null then debug_message "Informix SHMID: ${SHMID} - LPID ${LPID} is running" else if /usr/bin/ps -p ${CPID} -o zone | /usr/bin/grep " ${ZONENAME}$" > /dev/null then debug_message "Informix SHMID: ${SHMID} - CPID ${CPID} is running" else SHMID=`/usr/bin/echo ${SHMID} | /usr/xpg4/bin/tr 'm' ' '` # As the initial ipcs -mcopbZ is only a snapshot in time, Informix # may have already cleaned up. Therefore the following attempt to remove a # shared memory segment may fail with "not found". To prevent misleading # console messages stdout/stderr is redirected to ${LOGFILE}. /usr/bin/ipcrm -z ${ZONENAME} -m ${SHMID} > ${LOGFILE} debug_message "Informix SHMID: ${SHMID} - removed" flag=deleted fi fi done if [ -n "${flag}" ] then # SCMSGS # @explanation # All the Informix shared memory segments that were not being # used have been removed. # @user_action # None required. Informational message. scds_syslog -p daemon.notice -t $(syslog_tag) -m \ "All Informix non-attached IPC shared memory segments removed" fi debug_message "IPC Status AFTER removal of non-attached segments created by group informix" if [ "${DEBUG}" = "${RESOURCE}" -o "${DEBUG}" = "ALL" ] then /usr/bin/ipcs -mcopbZ | /usr/bin/grep " ${ZONENAME}$" > ${LOGFILE} log_message debug ipcs fi debug_message "Function: cleanup_ipc - End" return 0 }