1#!@BASH_SHELL@
2#
3# Copyright (C) 1997-2003 Sistina Software, Inc.  All rights reserved.
4# Copyright (C) 2004-2013 Red Hat, Inc.  All rights reserved.
5#
6# This program is free software; you can redistribute it and/or
7# modify it under the terms of the GNU General Public License
8# as published by the Free Software Foundation; either version 2
9# of the License, or (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19#
20# Author(s):
21#     Hardy Merrill <hmerrill at redhat.com>
22#     Lon Hohberger <lhh at redhat.com>
23#     Michael Moon <Michael dot Moon at oracle.com>
24#     Ryan McCabe <rmccabe at redhat.com>
25#
26# NOTES:
27#
28# (1) You can comment out the LOCKFILE declaration below.  This will prevent
29# the need for this script to access anything outside of the ORACLE_HOME
30# path.
31#
32# (2) You MUST customize ORACLE_USER, ORACLE_HOME, ORACLE_SID, and
33# ORACLE_HOSTNAME to match your installation if not running from within
34# rgmanager.
35#
36# (3) Do NOT place this script in shared storage; place it in ORACLE_USER's
37# home directory in non-clustered environments and /usr/share/cluster
38# in rgmanager/Red Hat cluster environments.
39#
40# Oracle is a registered trademark of Oracle Corporation.
41# Oracle9i is a trademark of Oracle Corporation.
42# Oracle10g is a trademark of Oracle Corporation.
43# Oracle11g is a trademark of Oracle Corporation.
44# All other trademarks are property of their respective owners.
45#
46
47. $(dirname $0)/ocf-shellfuncs
48. $(dirname $0)/utils/config-utils.sh
49. $(dirname $0)/utils/messages.sh
50. $(dirname $0)/utils/ra-skelet.sh
51
52. /etc/init.d/functions
53
54declare SCRIPT="`basename $0`"
55declare SCRIPTDIR="`dirname $0`"
56
57[ -n "$OCF_RESKEY_user" ] && ORACLE_USER=$OCF_RESKEY_user
58[ -n "$OCF_RESKEY_home" ] && ORACLE_HOME=$OCF_RESKEY_home
59[ -n "$OCF_RESKEY_name" ] && ORACLE_SID=$OCF_RESKEY_name
60[ -n "$OCF_RESKEY_listener_name" ] && ORACLE_LISTENER=$OCF_RESKEY_listener_name
61[ -n "$OCF_RESKEY_lockfile" ] && LOCKFILE=$OCF_RESKEY_lockfile
62[ -n "$OCF_RESKEY_type" ] && ORACLE_TYPE=$OCF_RESKEY_type
63[ -n "$OCF_RESKEY_vhost" ] && ORACLE_HOSTNAME=$OCF_RESKEY_vhost
64[ -n "$OCF_RESKEY_tns_admin" ] && export TNS_ADMIN=$OCF_RESKEY_tns_admin
65
66######################################################
67# Customize these to match your Oracle installation. #
68######################################################
69#
70# 1. Oracle user.  Must be the same across all cluster members.  In the event
71#    that this script is run by the super-user, it will automatically switch
72#    to the Oracle user and restart.  Oracle needs to run as the Oracle
73#    user, not as root.
74#
75#[ -n "$ORACLE_USER" ] || ORACLE_USER=oracle
76
77#
78# 2. Oracle home.  This is set up during the installation phase of Oracle.
79#    From the perspective of the cluster, this is generally the mount point
80#    you intend to use as the mount point for your Oracle Infrastructure
81#    service.
82#
83#[ -n "$ORACLE_HOME" ] || ORACLE_HOME=/mnt/oracle/home
84
85#
86# 3. This is your SID.  This is set up during oracle installation as well.
87#
88#[ -n "$ORACLE_SID" ] || ORACLE_SID=orcl
89
90#
91# 4. The oracle user probably doesn't have the permission to write to
92# /var/lock/subsys, so use the user's home directory.
93#
94#[ -n "$LOCKFILE" ] || LOCKFILE="/home/$ORACLE_USER/.oracle-ias.lock"
95[ -n "$LOCKFILE" ] || LOCKFILE="$ORACLE_HOME/.oracle-ias.lock"
96#[ -n "$LOCKFILE" ] || LOCKFILE="/var/lock/subsys/oracle-ias" # Watch privileges
97
98#
99# 5. Type of Oracle Database.  Currently supported: 10g 10g-iAS(untested!)
100#
101[ -n "$ORACLE_TYPE" ] || ORACLE_TYPE="base-em"
102
103#
104# 6. Oracle virtual hostname.  This is the hostname you gave Oracle during
105#    installation.
106#
107#[ -n "$ORACLE_HOSTNAME" ] || ORACLE_HOSTNAME=svc0.foo.test.com
108
109
110
111###########################################################################
112ORACLE_TYPE=`echo $ORACLE_TYPE | tr A-Z a-z`
113export ORACLE_USER ORACLE_HOME ORACLE_SID LOCKFILE ORACLE_TYPE
114export ORACLE_HOSTNAME
115
116
117##########################
118# Set up paths we'll use.  Not all are used by all the different types of
119# Oracle installations
120#
121export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$ORACLE_HOME/opmn/lib
122export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/opmn/bin:$ORACLE_HOME/dcm/bin:$PATH
123
124declare -i	RESTART_RETRIES=0
125declare -r	DB_PROCNAMES="pmon"
126#declare -r	DB_PROCNAMES="pmonXX" # testing
127#declare -r	DB_PROCNAMES="pmon smon dbw0 lgwr"
128
129declare -r	LSNR_PROCNAME="tnslsnr"
130#declare -r	LSNR_PROCNAME="tnslsnrXX" # testing
131
132# clulog will not log messages when run by the oracle user.
133# This is a hack to work around that.
134if [ "`id -u`" = "`id -u $ORACLE_USER`" ]; then
135	ocf_log() {
136		prio=$1
137		shift
138		logger -i -p daemon."$prio" -- "$*"
139	}
140fi
141
142##########################################################
143# (Hopefully) No user-serviceable parts below this line. #
144##########################################################
145meta_data()
146{
147	cat <<EOT
148<?xml version="1.0" ?>
149<resource-agent name="oracledb" version="rgmanager 2.0">
150    <version>1.0</version>
151
152    <longdesc lang="en">
153	Oracle 10g/11g Failover Instance
154    </longdesc>
155    <shortdesc lang="en">
156	Oracle 10g/11g Failover Instance
157    </shortdesc>
158
159    <parameters>
160        <parameter name="name" primary="1">
161	    <longdesc lang="en">
162		Instance name (SID) of oracle instance
163	    </longdesc>
164            <shortdesc lang="en">
165		Oracle SID
166            </shortdesc>
167	    <content type="string"/>
168        </parameter>
169
170        <parameter name="listener_name" unique="1">
171	    <longdesc lang="en">
172		Oracle Listener Instance Name.  If you have multiple 
173		instances of Oracle running, it may be necessary to 
174		have multiple listeners on the same machine with
175		different names.
176	    </longdesc>
177            <shortdesc lang="en">
178		Oracle Listener Instance Name
179            </shortdesc>
180	    <content type="string"/>
181        </parameter>
182
183        <parameter name="user" required="1">
184	    <longdesc lang="en">
185		Oracle user name.  This is the user name of the Oracle
186		user which the Oracle AS instance runs as.
187	    </longdesc>
188            <shortdesc lang="en">
189		Oracle User Name
190            </shortdesc>
191	    <content type="string"/>
192        </parameter>
193
194        <parameter name="home" required="1">
195	    <longdesc lang="en">
196		This is the Oracle (application, not user) home directory.
197		This is configured when you install Oracle.
198	    </longdesc>
199            <shortdesc lang="en">
200		Oracle Home Directory
201            </shortdesc>
202	    <content type="string"/>
203        </parameter>
204
205        <parameter name="type" required="0">
206	    <longdesc lang="en">
207		This is the Oracle installation type:
208		base - Database Instance and Listener only
209		base-11g - Oracle11g Database Instance and Listener Only
210		base-em (or 10g) - Database, Listener, Enterprise Manager,
211				   and iSQL*Plus
212		base-em-11g - Database, Listener, Enterprise Manager dbconsole
213		ias (or 10g-ias) - Internet Application Server (Infrastructure)
214	    </longdesc>
215            <shortdesc lang="en">
216		Oracle Installation Type
217            </shortdesc>
218	    <content type="string"/>
219        </parameter>
220
221        <parameter name="vhost" required="0" unique="1">
222	    <longdesc lang="en">
223	        Virtual Hostname matching the installation hostname of
224		Oracle 10g.  Note that during the start/stop of an oracledb
225		resource, your hostname will temporarily be changed to
226		this hostname.  As such, it is recommended that oracledb
227		resources be instanced as part of an exclusive service only.
228	    </longdesc>
229            <shortdesc lang="en">
230		Virtual Hostname
231            </shortdesc>
232	    <content type="string"/>
233        </parameter>
234
235        <parameter name="tns_admin" required="0" unique="1">
236	    <longdesc lang="en">
237			Full path to the directory that contains the Oracle
238        listener tnsnames.ora configuration file.  The shell
239        variable TNS_ADMIN is set to the value provided.
240	    </longdesc>
241            <shortdesc lang="en">
242		Full path to the directory containing tnsnames.ora
243            </shortdesc>
244	    <content type="string"/>
245        </parameter>
246    </parameters>
247
248    <actions>
249        <action name="start" timeout="900"/>
250	<action name="stop" timeout="90"/>
251        <action name="recover" timeout="990"/>
252
253	<!-- Checks to see if it's mounted in the right place -->
254	<action name="status" timeout="10"/>
255	<action name="monitor" timeout="10"/>
256
257	<action name="status" depth="10" timeout="30" interval="30"/>
258	<action name="monitor" depth="10" timeout="30" interval="30"/>
259
260	<action name="meta-data" timeout="5"/>
261	<action name="validate-all" timeout="5"/>
262    </actions>
263
264    <special tag="rgmanager">
265	<attributes maxinstances="1"/>
266    </special>
267</resource-agent>
268EOT
269}
270
271#
272# Start Oracle9i/10g/11g (database portion)
273#
274start_db()
275{
276	declare -i rv
277	declare startup_cmd
278	declare startup_stdout
279
280	ocf_log info "Starting Oracle DB $ORACLE_SID"
281
282	# Set up our sqlplus script.  Basically, we're trying to
283	# capture output in the hopes that it's useful in the case
284	# that something doesn't work properly.
285	startup_cmd="set heading off;\nstartup;\nquit;\n"
286	startup_stdout=$(echo -e "$startup_cmd" | sqlplus -S "/ as sysdba")
287	rv=$?
288
289	# Dump output to syslog for debugging
290	ocf_log debug "[$ORACLE_SID] [$rv] sent $startup_cmd"
291	ocf_log debug "[$ORACLE_SID] [$rv] got $startup_stdout"
292
293	if [ $rv -ne 0 ]; then
294	    ocf_log error "Starting Oracle DB $ORACLE_SID failed, sqlplus returned $rv"
295	    return 1
296	fi
297
298	# If we see:
299	# ORA-.....: failure, we failed
300	# Troubleshooting:
301	#   ORA-00845 - Try rm -f /dev/shm/ora_*
302	#   ORA-01081 - Try echo -e 'shutdown abort;\nquit;'|sqlplus "/ as sysdba"
303	if [[ "$startup_stdout" =~ "ORA-" ]] || [[ "$startup_stdout" =~ "failure" ]]; then
304	    ocf_log error "Starting Oracle DB $ORACLE_SID failed, found errors in stdout"
305	    return 1
306	fi
307
308	ocf_log info "Started Oracle DB $ORACLE_SID successfully"
309	return 0
310}
311
312
313#
314# Stop Oracle (database portion)
315#
316stop_db()
317{
318	declare stop_cmd
319	declare stop_stdout
320	declare -i rv
321	declare how_shutdown="$1"
322
323	if [ -z "$1" ]; then
324		how_shutdown="immediate"
325	fi
326
327	ocf_log info "Stopping Oracle DB $ORACLE_SID $how_shutdown"
328
329	# Setup for Stop ...
330	stop_cmd="set heading off;\nshutdown $how_shutdown;\nquit;\n"
331	stop_stdout=$(echo -e "$stop_cmd" | sqlplus -S "/ as sysdba")
332	rv=$?
333
334	# Log stdout of the stop command
335	ocf_log debug "[$ORACLE_SID] sent stop command $stop_cmd"
336	ocf_log debug "[$ORACLE_SID] got $stop_stdout"
337
338	# sqlplus returned failure. We'll return failed to rhcs
339	if [ $rv -ne 0 ]; then
340	    ocf_log error "Stopping Oracle DB $ORACLE_SID failed, sqlplus returned $rv"
341	    return 1
342	fi
343
344	# If we see 'ORA-' or 'failure' in stdout, we're done.
345	if [[ "$startup_stdout" =~ "ORA-" ]] || [[ "$startup_stdout" =~ "failure" ]]; then
346	    ocf_log error "Stopping Oracle DB $ORACLE_SID failed, errors in stdout"
347	    return 1
348	fi
349
350	ocf_log info "Stopped Oracle DB $ORACLE_SID successfully"
351	return 0
352}
353
354
355#
356# Destroy any remaining processes with refs to $ORACLE_HOME
357#
358force_cleanup()
359{
360	declare pids
361	declare pid
362
363	# Patch from Shane Bradley to fix 471266
364	pids=`ps ax | grep "ora_.*_${ORACLE_SID}" | grep -v grep | awk '{print $1}'`
365
366	ocf_log error "Not all Oracle processes for $ORACLE_SID exited cleanly, killing"
367
368	for pid in $pids; do
369		kill -9 $pid
370		rv=$?
371		if [ $rv -eq 0 ]; then
372			ocf_log info "Cleanup $ORACLE_SID Killed PID $pid"
373		else
374			ocf_log error "Cleanup $ORACLE_SID Kill PID $pid failed: $rv"
375		fi
376	done
377
378	return 0
379}
380
381
382
383#
384# Wait for oracle processes to exit.  Time out after 60 seconds
385#
386exit_idle()
387{
388	declare -i n=0
389
390	ocf_log debug "Waiting for Oracle processes for $ORACLE_SID to terminate..."
391	# grep -q "." keeps this loop going if the previous commands produce any stdout
392	while ps ax | grep "ora_.*_${ORACLE_SID}" | grep -v grep | awk '{print $1}' | grep -q "."; do
393		if [ $n -ge 90 ]; then
394			ocf_log debug "Timed out while waiting for Oracle processes for $ORACLE_SID to terminate"
395			force_cleanup
396			return 0
397		fi
398		sleep 1
399		((n++))
400	done
401
402	ocf_log debug "All Oracle processes for $ORACLE_SID have terminated"
403	return 0
404}
405
406
407#
408# Get database background process status.  Restart it if it failed and
409# we have seen the lock file.
410#
411get_db_status()
412{
413	declare -i subsys_lock=$1
414	declare -i i=0
415	declare -i rv=0
416	declare ora_procname
417
418	for procname in $DB_PROCNAMES ; do
419
420		ora_procname="ora_${procname}_${ORACLE_SID}"
421
422		status $ora_procname
423		if [ $? -eq 0 ] ; then
424			# This one's okay; go to the next one.
425			continue
426		fi
427
428		#
429		# We're not supposed to be running, and we are,
430		# in fact, not running...
431		# XXX only works when monitoring one db process; consider
432		# extending in future.
433		#
434		if [ $subsys_lock -ne 0 ]; then
435			return 3
436		fi
437
438		for (( i=$RESTART_RETRIES ; i; i-- )) ; do
439			# this db process is down - stop and
440			# (re)start all ora_XXXX_$ORACLE_SID processes
441			ocf_log info "Restarting Oracle Database $ORACLE_SID"
442			stop_db immediate
443			if [ $? -ne 0 ] ; then
444				# stop failed - return 1
445				ocf_log error "Error stopping Oracle Database $ORACLE_SID"
446				return 1
447			fi
448
449			start_db
450			if [ $? -eq 0 ] ; then
451				# ora_XXXX_$ORACLE_SID processes started
452				# successfully, so break out of the
453				# stop/start # 'for' loop
454				ocf_log info "Restarted Oracle Database $ORACLE_SID successfully"
455				break
456			fi
457		done
458
459		if [ $i -eq 0 ]; then
460			# stop/start's failed - return 1 (failure)
461			ocf_log error "Failed to restart Oracle Database $ORACLE_SID after $RESTART_RETRIES tries"
462			return 1
463		fi
464	done
465	return 0
466}
467
468
469#
470# Get the status of the Oracle listener process
471#
472get_lsnr_status()
473{
474	declare -i subsys_lock=$1
475	declare -i rv
476
477	ocf_log debug "Checking status for listener $ORACLE_LISTENER"
478	lsnrctl status $ORACLE_LISTENER >& /dev/null
479	rv=$?
480	if [ $rv -eq 0 ] ; then
481		ocf_log debug "Listener $ORACLE_LISTENER is up"
482		return 0 # Listener is running fine
483	fi
484
485	# We're not supposed to be running, and we are,
486	# in fact, not running.  Return 3
487	if [ $subsys_lock -ne 0 ]; then
488		ocf_log debug "Listener $ORACLE_LISTENER is stopped as expected"
489		return 3
490	fi
491
492	# Listener is NOT running (but should be) - try to restart
493	for (( i=$RESTART_RETRIES ; i; i-- )) ; do
494		ocf_log info "Listener $ORACLE_LISTENER is down, attempting to restart"
495		lsnrctl start $ORACLE_LISTENER >& /dev/null
496		lsnrctl status $ORACLE_LISTENER >& /dev/null
497		if [ $? -eq 0 ] ; then
498			ocf_log info "Listener $ORACLE_LISTENER was restarted successfully"
499			break # Listener was (re)started and is running fine
500		fi
501	done
502
503	if [ $i -eq 0 ]; then
504		# stop/start's failed - return 1 (failure)
505		ocf_log error "Failed to restart listener $ORACLE_LISTENER after $RESTART_RETRIES tries"
506		return 1
507	fi
508
509	lsnrctl_stdout=$(lsnrctl status $ORACLE_LISTENER)
510	rv=$?
511	if [ $rv -ne 0 ] ; then
512		ocf_log error "Starting listener $ORACLE_LISTENER failed: $rv output $lsnrctl_stdout"
513		return 1 # Problem restarting the Listener
514	fi
515
516	ocf_log info "Listener $ORACLE_LISTENER started successfully"
517	return 0 # Success restarting the Listener
518}
519
520
521#
522# usage: get_opmn_proc_status <ias-component> [process-type]
523#
524# Get the status of a specific OPMN-managed process.  If process-type
525# is not specified, assume the process-type is the same as the ias-component.
526# If the lock-file exists (or no lock file is specified), try to restart
527# the given process-type if it is not running.
528#
529get_opmn_proc_status()
530{
531	declare comp=$1
532	declare opmntype=$2
533	declare type_pretty
534	declare _pid _status
535
536	[ -n "$comp" ] || return 1
537	if [ -z "$opmntype" ]; then
538		opmntype=$comp
539	else
540		type_pretty=" [$opmntype]"
541	fi
542
543	for (( i=$RESTART_RETRIES ; i; i-- )) ; do
544
545		_status=`opmnctl status | grep "^$comp " | grep " $opmntype " | cut -d '|' -f3,4 | sed -e 's/ //g' -e 's/|/ /g'`
546
547		_pid=`echo $_status | cut -f1 -d' '`
548		_status=`echo $_status | cut -f2 -d' '`
549		if [ "${_status}" == "Alive" ] || [ "${_status}" == "Init" ]; then
550			if [ $i -lt $RESTART_RETRIES ] ; then
551				ocf_log info "$comp$type_pretty restarted"
552			fi
553			ocf_log info "$comp$type_pretty (pid $_pid) is running..."
554			break
555		else
556			ocf_log info "$comp$type_pretty is stopped"
557
558			#
559			# Try to restart it, but don't worry if we fail.  OPMN
560			# is supposed to handle restarting these anyway.
561			#
562			# If it's running and you tell OPMN to "start" it,
563			# you will get an error.
564			#
565			# If it's NOT running and you tell OPMN to "restart"
566			# it, you will also get an error.
567			#
568			opmnctl startproc process-type=$opmntype &> /dev/null
569		fi
570	done
571
572	if [ $i -eq 0 ]; then
573		# restarts failed - return 1 (failure)
574		ocf_log error "Failed to restart OPMN process $comp"
575		return 1
576	fi
577
578	return 0
579}
580
581
582#
583# Get the status of the OPMN-managed processes.
584#
585get_opmn_status()
586{
587	declare -i subsys_lock=$1
588	declare -i ct_errors=0
589
590	opmnctl status &> /dev/null
591	if [ $? -eq 2 ]; then
592		#
593		# OPMN not running??
594		#
595		ocf_log info "OPMN is stopped"
596
597		if [ $subsys_lock -eq 0 ]; then
598			#
599			# Don't handle full opmn-restart. XXX
600			#
601			return 1
602		fi
603
604		# That's okay, it's not supposed to be!
605		return 3
606	fi
607
608	#
609	# Print out the PIDs for everyone.
610	#
611	ocf_log info "OPMN is running..."
612	ocf_log info "opmn components:"
613
614	#
615	# Check the OPMN-managed processes
616	#
617	get_opmn_proc_status OID || ((ct_errors++))
618	get_opmn_proc_status HTTP_Server || ((ct_errors++))
619	get_opmn_proc_status OC4J OC4J_SECURITY || ((ct_errors++))
620
621	#
622	# One or more OPMN-managed processes failed and could not be
623	# restarted.
624	#
625	if [ $ct_errors -ne 0 ]; then
626		ocf_log error "$ct_errors errors occurred while restarting OPMN-managed processes"
627		return 1
628	fi
629	return 0
630}
631
632
633#
634# Helps us keep a running status so we know what our ultimate return
635# code will be.  Returns 1 if the $1 and $2 are not equivalent, otherwise
636# returns $1.  The return code is meant to be the next $1 when this is
637# called, so, for example:
638#
639# update_status 0   <-- returns 0
640# update_status $? 0 <-- returns 0
641# update_status $? 3 <-- returns 1 (values different - error condition)
642# update_status $? 1 <-- returns 1 (same, but happen to be error state!)
643#
644# update_status 3
645# update_status $? 3 <-- returns 3
646#
647# (and so forth...)
648#
649update_status()
650{
651	declare -i old_status=$1
652	declare -i new_status=$2
653
654	if [ -z "$2" ]; then
655		return $old_status
656	fi
657
658	if [ $old_status -ne $new_status ]; then
659		return 1
660	fi
661
662	return $old_status
663}
664
665
666#
667# Print an error message to the user and exit.
668#
669oops()
670{
671	ocf_log error "$ORACLE_SID: Fatal: $1 failed validation checks"
672	exit 1
673}
674
675
676#
677# Do some validation on the user-configurable stuff at the beginning of the
678# script.
679#
680validation_checks()
681{
682	ocf_log debug "Validating configuration for $ORACLE_SID"
683
684	#
685	# If the oracle user doesn't exist, we're done.
686	#
687	[ -n "$ORACLE_USER" ] || oops "ORACLE_USER"
688	id -u $ORACLE_USER > /dev/null || oops "ORACLE_USER"
689	id -g $ORACLE_USER > /dev/null || oops "ORACLE_USER"
690
691	#
692	# If the oracle home isn't a directory, we're done
693	#
694	[ -n "$ORACLE_HOME" ] || oops ORACLE_HOME
695	#[ -d "$ORACLE_HOME" ] || oops ORACLE_HOME
696
697	#
698	# If the oracle SID is NULL, we're done
699	#
700	[ -n "$ORACLE_SID" ] || oops ORACLE_SID
701
702	#
703	# If we don't know the type, we're done
704	#
705	if [ "$ORACLE_TYPE" = "base" ]; then
706		# Other names for base
707		ORACLE_TYPE="base"
708	elif [ "$ORACLE_TYPE" = "10g" ] || [ "$ORACLE_TYPE" = "base-em" ]; then
709		ORACLE_TYPE="base-em"
710	elif [ "$ORACLE_TYPE" = "10g-ias" ] || [ "$ORACLE_TYPE" = "ias" ]; then
711		ORACLE_TYPE="ias"
712	elif [ "$ORACLE_TYPE" = "11g" ] || [ "$ORACLE_TYPE" = "base-em-11g" ]; then
713		ORACLE_TYPE="base-em-11g"
714	elif [ "$ORACLE_TYPE" = "base-11g" ]; then
715		ORACLE_TYPE="base-11g"
716	else
717		oops "ORACLE_TYPE $ORACLE_TYPE"
718	fi
719
720	#
721	# If the hostname is zero-length, fix it
722	#
723	[ -n "$ORACLE_HOSTNAME" ] || ORACLE_HOSTNAME=`hostname`
724
725	#
726	# Super user? Automatically change UID and exec as oracle user.
727	# Oracle needs to be run as the Oracle user, not root!
728	#
729	if [ "`id -u`" = "0" ]; then
730		#echo "Restarting $0 as $ORACLE_USER."
731		#
732		# Breaks on RHEL5
733		# exec sudo -u $ORACLE_USER $0 $*
734		#
735		su $ORACLE_USER -c "$0 $*"
736		exit $?
737	fi
738
739	#
740	# If we're not root and not the Oracle user, we're done.
741	#
742	[ "`id -u`" = "`id -u $ORACLE_USER`" ] || oops "not ORACLE_USER after su"
743	[ "`id -g`" = "`id -g $ORACLE_USER`" ] || oops "not ORACLE_GROUP after su"
744
745	#
746	# Go home.
747	#
748	cd "$ORACLE_HOME"
749
750	ocf_log debug "Validation checks for $ORACLE_SID succeeded"
751	return 0
752}
753
754
755#
756# Start Oracle 9i/10g/11g Application Server Infrastructure
757#
758start_oracle()
759{
760	ocf_log info "Starting service $ORACLE_SID"
761
762	start_db
763	rv=$?
764	if [ $rv -ne 0 ]; then
765		ocf_log error "Starting service $ORACLE_SID failed"
766		return 1
767	fi
768
769	ocf_log info "Starting listener $ORACLE_LISTENER"
770	lsnrctl_stdout=$(lsnrctl start $ORACLE_LISTENER)
771	rv=$?
772	if [ $rv -ne 0 ]; then
773		ocf_log debug "[$ORACLE_SID] Listener $ORACLE_LISTENER start returned $rv output $lsnrctl_stdout"
774		ocf_log error "Starting service $ORACLE_SID failed"
775		return 1
776	fi
777
778	if [ "$ORACLE_TYPE" = "base-em" ]; then
779		ocf_log info "Starting iSQL*Plus for $ORACLE_SID"
780		isqlplusctl start
781		if [ $? -ne 0 ]; then
782			ocf_log error "iSQL*Plus startup for $ORACLE_SID failed"
783			ocf_log error "Starting service $ORACLE_SID failed"
784			return 1
785		else
786			ocf_log info "iSQL*Plus startup for $ORACLE_SID succeeded"
787		fi
788
789		ocf_log info "Starting Oracle EM DB Console for $ORACLE_SID"
790		emctl start dbconsole
791		if [ $? -ne 0 ]; then
792			ocf_log error "Oracle EM DB Console startup for $ORACLE_SID failed"
793			ocf_log error "Starting service $ORACLE_SID failed"
794			return 1
795		else
796			ocf_log info "Oracle EM DB Console startup for $ORACLE_SID succeeded"
797		fi
798	elif [ "$ORACLE_TYPE" = "ias" ]; then
799		ocf_log info "Starting Oracle EM for $ORACLE_SID"
800		emctl start em
801		if [ $? -ne 0 ]; then
802			ocf_log error "Oracle EM startup for $ORACLE_SID failed"
803			ocf_log error "Starting service $ORACLE_SID failed"
804			return 1
805		else
806			ocf_log info "Oracle EM startup for $ORACLE_SID succeeded"
807		fi
808
809		ocf_log info "Starting iAS Infrastructure for $ORACLE_SID"
810		opmnctl startall
811		if [ $? -ne 0 ]; then
812			ocf_log error "iAS Infrastructure startup for $ORACLE_SID failed"
813			ocf_log error "Starting service $ORACLE_SID failed"
814			return 1
815		else
816			ocf_log info "iAS Infrastructure startup for $ORACLE_SID succeeded"
817		fi
818	elif [ "$ORACLE_TYPE" = "base-em-11g" ]; then
819		ocf_log info "Starting Oracle EM DB Console for $ORACLE_SID"
820		emctl start dbconsole
821		if [ $? -ne 0 ]; then
822			ocf_log error "Oracle EM DB Console startup for $ORACLE_SID failed"
823			ocf_log error "Starting service $ORACLE_SID failed"
824			return 1
825		else
826			ocf_log info "Oracle EM DB Console startup for $ORACLE_SID succeeded"
827		fi
828	fi
829
830	if [ -n "$LOCKFILE" ]; then
831		touch "$LOCKFILE"
832	fi
833
834	ocf_log info "Starting service $ORACLE_SID completed successfully"
835	return 0
836}
837
838
839#
840# Stop Oracle 9i/10g/11g Application Server Infrastructure
841#
842stop_oracle()
843{
844	ocf_log info "Stopping service $ORACLE_SID"
845
846	if ! [ -e "$ORACLE_HOME/bin/lsnrctl" ]; then
847		ocf_log error "Oracle Listener Control is not available ($ORACLE_HOME not mounted?)"
848		return 0
849	fi
850
851	if [ "$ORACLE_TYPE" = "base-em" ]; then
852		ocf_log info "Stopping Oracle EM DB Console for $ORACLE_SID"
853		emctl stop dbconsole
854		if [ $? -ne 0 ]; then
855			ocf_log error "Stopping Oracle EM DB Console for $ORACLE_SID failed"
856			ocf_log error "Stopping service $ORACLE_SID failed"
857			return 1
858		else
859			ocf_log info "Stopping Oracle EM DB Console for $ORACLE_SID succeeded"
860		fi
861
862		ocf_log info "Stopping iSQL*Plus for $ORACLE_SID"
863		isqlplusctl stop
864		if [ $? -ne 0 ]; then
865			ocf_log error "Stopping iSQL*Plus for $ORACLE_SID failed"
866			ocf_log error "Stopping service $ORACLE_SID failed"
867			return 1
868		else
869			ocf_log info "Stopping iSQL*Plus for $ORACLE_SID succeeded"
870		fi
871	elif [ "$ORACLE_TYPE" = "ias" ]; then
872		ocf_log info "Stopping iAS Infrastructure for $ORACLE_SID"
873		opmnctl stopall
874		if [ $? -ne 0 ]; then
875			ocf_log error "Stopping iAS Infrastructure for $ORACLE_SID failed"
876			ocf_log error "Stopping service $ORACLE_SID failed"
877			return 1
878		else
879			ocf_log info "Stopping iAS Infrastructure for $ORACLE_SID succeeded"
880		fi
881
882		ocf_log info "Stopping Oracle EM for $ORACLE_SID"
883		emctl stop em
884		if [ $? -ne 0 ]; then
885			ocf_log error "Stopping Oracle EM for $ORACLE_SID failed"
886			ocf_log error "Stopping service $ORACLE_SID failed"
887			return 1
888		else
889			ocf_log info "Stopping Oracle EM for $ORACLE_SID succeeded"
890		fi
891	elif [ "$ORACLE_TYPE" = "base-em-11g" ]; then
892		ocf_log info "Stopping Oracle EM DB Console for $ORACLE_SID"
893		emctl stop dbconsole
894		if [ $? -ne 0 ]; then
895			ocf_log error "Stopping Oracle EM DB Console for $ORACLE_SID failed"
896			ocf_log error "Stopping service $ORACLE_SID failed"
897			return 1
898		else
899			ocf_log info "Stopping Oracle EM DB Console for $ORACLE_SID succeeded"
900		fi
901	fi
902
903	stop_db immediate || stop_db abort
904	if [ $? -ne 0 ]; then
905		ocf_log error "Stopping service $ORACLE_SID failed"
906		return 1
907	fi
908
909	ocf_log info "Stopping listener $ORACLE_LISTENER for $ORACLE_SID"
910	lsnrctl_stdout=$(lsnrctl stop $ORACLE_LISTENER)
911	rv=$?
912	if [ $? -ne 0 ]; then
913		ocf_log error "Listener $ORACLE_LISTENER stop failed for $ORACLE_SID: $rv output $lsnrctl_stdout"
914		# XXX - failure?
915	fi
916
917	exit_idle
918	if [ $? -ne 0 ]; then
919		ocf_log warning "WARNING: Not all Oracle processes exited cleanly for $ORACLE_SID"
920	fi
921
922	if [ -n "$LOCKFILE" ]; then
923		rm -f "$LOCKFILE"
924	fi
925
926	ocf_log info "Stopping service $ORACLE_SID succeeded"
927	return 0
928}
929
930
931#
932# Find and display the status of iAS infrastructure.
933#
934# This has three parts:
935# (1) Oracle database itself
936# (2) Oracle listener process
937# (3) OPMN and OPMN-managed processes
938#
939# - If all are (cleanly) down, we return 3.  In order for this to happen,
940# $LOCKFILE must not exist.  In this case, we try and restart certain parts
941# of the service - as this may be running in a clustered environment.
942#
943# - If some but not all are running (and, if $LOCKFILE exists, we could not
944# restart the failed portions), we return 1 (ERROR)
945#
946# - If all are running, return 0.  In the "all-running" case, we recreate
947# $LOCKFILE if it does not exist.
948#
949status_oracle()
950{
951	declare -i subsys_lock=1
952	declare -i last
953
954	ocf_log debug "Checking status for $ORACLE_SID depth $depth"
955
956	#
957	# Check for lock file.  Crude and rudimentary, but it works
958	#
959	if [ -z "$LOCKFILE" ] || [ -f "$LOCKFILE" ]; then
960		subsys_lock=0
961	fi
962
963	# Check database status
964	get_db_status $subsys_lock
965	update_status $? # Start
966	last=$?
967
968	# Check & report listener status
969	get_lsnr_status $subsys_lock
970	update_status $? $last
971	last=$?
972
973	if [ "$ORACLE_TYPE" = "base-em" ] || [ "$ORACLE_TYPE" = "base-em-11g" ]; then
974		# XXX Add isqlplus status check?!
975		emctl status dbconsole >&/dev/null
976		update_status $? $last
977		last=$?
978	elif [ "$ORACLE_TYPE" = "ias" ]; then
979		# Check & report opmn / opmn-managed process status
980		get_opmn_status $subsys_lock
981		update_status $? $last
982		last=$?
983	fi
984
985	#
986	# No lock file, but everything's running.  Put the lock
987	# file back. XXX - this kosher?
988	#
989	if [ $last -eq 0 ] && [ $subsys_lock -ne 0 ]; then
990		touch "$LOCKFILE"
991	fi
992
993	ocf_log debug "Status returning $last for $ORACLE_SID"
994	return $last
995}
996
997
998########################
999# Do some real work... #
1000########################
1001if [ "$1" = "meta-data" ]; then
1002	meta_data
1003	exit 0
1004fi
1005
1006validation_checks $*
1007
1008case $1 in
1009	start)
1010		start_oracle
1011		exit $?
1012		;;
1013	stop)
1014		stop_oracle
1015		exit $?
1016		;;
1017	status|monitor)
1018		status_oracle
1019		exit $?
1020		;;
1021	restart)
1022		$0 stop || exit $?
1023		$0 start || exit $?
1024		exit 0
1025		;;
1026	*)
1027		echo "usage: $SCRIPT {start|stop|status|restart|meta-data}"
1028		exit 1
1029		;;
1030esac
1031exit 0
1032