#!/bin/sh # # # oralsnr # # Description: Manages an Oracle Listener as a High-Availability # resource # # # Author: Dejan Muhamedagic # Support: users@clusterlabs.org # License: GNU General Public License (GPL) # Copyright: (C) 2006 International Business Machines, Inc. # # This code inspired by the DB2 resource script # written by Alan Robertson # # An example usage in /etc/ha.d/haresources: # node1 10.0.0.170 oralsnr::sid::home::user::listener # # See oralsnr_usage() function below for more details... # # OCF instance parameters: # OCF_RESKEY_sid (mandatory; for the monitor op) # OCF_RESKEY_home (optional; else read it from /etc/oratab) # OCF_RESKEY_user (optional; user to run the listener) # OCF_RESKEY_listener (optional; defaults to LISTENER) # # Initialization: : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs . ${OCF_FUNCTIONS_DIR}/ora-common.sh # Parameter defaults OCF_RESKEY_sid_default="" OCF_RESKEY_home_default="" OCF_RESKEY_user_default="" OCF_RESKEY_listener_default="LISTENER" : ${OCF_RESKEY_sid=${OCF_RESKEY_sid_default}} : ${OCF_RESKEY_home=${OCF_RESKEY_home_default}} : ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} : ${OCF_RESKEY_listener=${OCF_RESKEY_listener_default}} ####################################################################### SH=/bin/sh oralsnr_usage() { methods=`oralsnr_methods` methods=`echo $methods | tr ' ' '|'` cat <<-! usage: $0 ($methods) $0 manages an Oracle Database instance as an HA resource. The 'start' operation starts the database. The 'stop' operation stops the database. The 'status' operation reports whether the database is running The 'monitor' operation reports whether the database seems to be working The 'validate-all' operation reports whether the parameters are valid The 'methods' operation reports on the methods $0 supports ! } oralsnr_meta_data() { cat < 1.0 Resource script for Oracle Listener. It manages an Oracle Listener instance as an HA resource. Manages an Oracle TNS listener The Oracle SID (aka ORACLE_SID). Necessary for the monitor op, i.e. to do tnsping SID. sid The Oracle home directory (aka ORACLE_HOME). If not specified, then the SID should be listed in /etc/oratab. home Run the listener as this user. user Listener instance to be started (as defined in listener.ora). Defaults to LISTENER. listener Full path to the directory that contains the Oracle listener tnsnames.ora configuration file. The shell variable TNS_ADMIN is set to the value provided. Full path to the directory containing tnsnames.ora END } # # methods: What methods/operations do we support? # oralsnr_methods() { cat <<-! start stop status monitor validate-all methods meta-data usage ! } # # Run commands as the Oracle owner... # runasdba() { if [ "$US" = "$ORACLE_OWNER" ]; then $SH else ( echo ". $ORA_ENVF" cat ) | su -s $SH - $ORACLE_OWNER fi } # # oralsnr_start: Start the Oracle listener instance # oralsnr_start() { if is_proc_running && test_tnsping; then : nothing to be done, we can leave right now ocf_log info "Listener $listener already running" return $OCF_SUCCESS fi output=`echo lsnrctl start $listener | runasdba` if test_tnsping; then : cool, we are up and running ocf_log info "Listener $listener running: $output" return $OCF_SUCCESS else ocf_exit_reason "Listener $listener appears to have started, but is not running properly: $output" ocf_log err "Probable Oracle configuration error" return $OCF_ERR_GENERIC fi } # # oralsnr_stop: Stop the Oracle instance # oralsnr_stop() { if is_proc_running; then output=`echo lsnrctl stop $listener | runasdba` else ocf_log info "Listener $listener already stopped" return $OCF_SUCCESS fi ocf_stop_processes TERM $PROCS_CLEANUP_TIME `proc_pids` # kill the procs if they hanged if is_proc_running; then ocf_exit_reason "Listener $listener not stopped: $output" return $OCF_ERR_GENERIC else ocf_log info "Listener $listener stopped: $output" return $OCF_SUCCESS fi } # # is_proc_running: is the listener running? # is_proc_running() { show_procs | grep "." > /dev/null } # the following two should be run only if the process is running test_listener() { local output output=`lsnrctl status $listener` if echo "$output" | tail -1 | grep -qs 'completed successfully' then return $OCF_SUCCESS else ocf_exit_reason "$listener status failed: $output" return $OCF_ERR_GENERIC fi } # and does it work? test_tnsping() { local output output=`tnsping $ORACLE_SID` if echo "$output" | tail -1 | grep -qs '^OK'; then return $OCF_SUCCESS else ocf_exit_reason "tnsping $ORACLE_SID failed: $output" return $OCF_ERR_GENERIC fi } # # oralsnr_monitor: Can we connect to the listener? # oralsnr_monitor() { if is_proc_running; then test_listener && test_tnsping else return $OCF_NOT_RUNNING fi } oralsnr_status() { if is_proc_running then echo Listener $listener is running exit $OCF_SUCCESS else echo Listener $listener is stopped exit $OCF_NOT_RUNNING fi } oralsnr_getconfig() { ora_common_getconfig "$OCF_RESKEY_sid" "$OCF_RESKEY_home" "$OCF_RESKEY_user" "$OCF_RESKEY_tns_admin" listener=${OCF_RESKEY_listener} } oralsnr_validate_all() { ora_common_validate_all } # used in ora-common.sh show_procs() { ps -U "$ORACLE_OWNER" -o pid,user,args | grep '[t]nslsnr' | grep -i -w "$listener" } proc_pids() { show_procs | awk '{print $1}'; } PROCS_CLEANUP_TIME="10" OCF_REQUIRED_PARAMS="sid" OCF_REQUIRED_BINARIES="lsnrctl tnsping" ocf_rarun $* # # vim:tabstop=4:shiftwidth=4:textwidth=0:wrapmargin=0