diff options
Diffstat (limited to '')
-rwxr-xr-x | heartbeat/oralsnr | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/heartbeat/oralsnr b/heartbeat/oralsnr new file mode 100755 index 0000000..dd0df1c --- /dev/null +++ b/heartbeat/oralsnr @@ -0,0 +1,293 @@ +#!/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 <<END +<?xml version="1.0"?> +<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> +<resource-agent name="oralsnr" version="1.0"> +<version>1.0</version> + +<longdesc lang="en"> +Resource script for Oracle Listener. It manages an +Oracle Listener instance as an HA resource. +</longdesc> +<shortdesc lang="en">Manages an Oracle TNS listener</shortdesc> + +<parameters> + +<parameter name="sid" unique="1" required="1"> +<longdesc lang="en"> +The Oracle SID (aka ORACLE_SID). Necessary for the monitor op, +i.e. to do tnsping SID. +</longdesc> +<shortdesc lang="en">sid</shortdesc> +<content type="string" default="${OCF_RESKEY_sid_default}" /> +</parameter> + +<parameter name="home" unique="0"> +<longdesc lang="en"> +The Oracle home directory (aka ORACLE_HOME). +If not specified, then the SID should be listed in /etc/oratab. +</longdesc> +<shortdesc lang="en">home</shortdesc> +<content type="string" default="${OCF_RESKEY_home_default}" /> +</parameter> + +<parameter name="user" unique="0"> +<longdesc lang="en"> +Run the listener as this user. +</longdesc> +<shortdesc lang="en">user</shortdesc> +<content type="string" default="${OCF_RESKEY_user_default}" /> +</parameter> + +<parameter name="listener" unique="1"> +<longdesc lang="en"> +Listener instance to be started (as defined in listener.ora). +Defaults to LISTENER. +</longdesc> +<shortdesc lang="en">listener</shortdesc> +<content type="string" default="${OCF_RESKEY_listener_default}" /> +</parameter> + +<parameter name="tns_admin" required="0" unique="0"> +<longdesc lang="en"> + 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. +</longdesc> +<shortdesc lang="en"> + Full path to the directory containing tnsnames.ora +</shortdesc> +<content type="string"/> +</parameter> + +</parameters> + +<actions> +<action name="start" timeout="120s" /> +<action name="stop" timeout="120s" /> +<action name="status" timeout="60s" /> +<action name="monitor" depth="0" timeout="30s" interval="10s" /> +<action name="validate-all" timeout="5s" /> +<action name="meta-data" timeout="5s" /> +<action name="methods" timeout="5s" /> +</actions> +</resource-agent> +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 |