#!/bin/ksh # chkconfig: 2345 90 10 # description: rc.listenner: System V start / stop script, Veritas Cluster Agent, \ # and a generic utility. [[ -n $BASH_VERSION ]] && shopt -s extglob OPATH=; unset OPATH OPATH=$PATH GETCONF=; unset GETCONF for GETCONF in /bin/getconf /usr/bin/getconf; do [[ -x $GETCONF ]] && { PATH=$($GETCONF PATH) # avoid ksh93 (m, l, ...) getconf break; # which has problems. } done function shdoc { typeset version="3.0, 2006-09-06, Michael Wang ." typeset help doc file typeset tmpdir=/tmp/shdoc_$$_$RANDOM typeset base tmpf i flag=N eval help=y doc=pod "$@" [[ -n ${OPATH:-} ]] && typeset PATH=$OPATH set -- $(echo $help $doc | tr '[a-z]' '[A-Z]') help=$1 doc=$2 base=${file##*/} base=${base%.*sh} case ${doc} in (POD) mkdir -p ${tmpdir} && tmpf=${tmpdir}/${base}.pod ;; (MAN) mkdir -p ${tmpdir}/man/man1 && tmpf=${tmpdir}/man/man1/${base}.1 ;; esac while IFS= read -r i; do [[ $i = "## ${doc}_START"* ]] && { flag=Y; continue; } [[ $i = "## ${doc}_STOP"* ]] && { flag=N; continue; } if [[ $flag = "Y" ]]; then i=${i#"##"} i=${i#" "} printf "%s\n" "${i}" fi done < ${file} > ${tmpf} case $help in (Y) case ${doc} in (POD) perldoc ${tmpf} ;; (MAN) MANPATH=${tmpdir}/man man ${base} ;; esac ;; (PS|PDF) case ${doc} in (POD) pod2man ${tmpf} ;; (MAN) cat ${tmpf} ;; esac | groff -man | case ${help} in (PS) cat >${base}.ps ;; (PDF) ps2pdf - ${base}.pdf ;; esac ;; (POD) cp ${tmpf} ${base}.pod ;; (HTML) pod2html ${tmpf} > ${base}.html rm pod2htmd.tmp pod2htmi.tmp ;; esac rm -rf ${tmpdir} return 0 } typeset -l my_args="$@" [[ ${my_args} = *"help="?* ]] && { help=; unset help help=${my_args##*help=} help=${help%% *} [[ ${my_args} = *"doc="?* ]] && { doc=; unset doc doc=${my_args##*doc=} doc=${doc%% *} } : ${doc:=man} shdoc file=$0 doc=$doc help=$help exit 0 } [[ ${my_args} == *"version=y"* ]] && { sed -n "/^## version/{p; /^/q;}" $0 exit 0 } my_base=${0##*/} function get_cdate { date "+%Y-%m-%d %H:%M:%S"; } function get_tmpfile { typeset -Z6 pid=$$ random=${RANDOM} cdate=$(get_cdate) cdate=$(echo "$cdate" | sed "s/[-: ]//g") echo /tmp/.rc.listener.${cdate}.${pid}.${random} } my_logdir=$(get_tmpfile) [[ -d ${my_logdir} ]] || mkdir ${my_logdir} my_logfile=${my_logdir}/${my_base}_00.out exec 3>&1 4>&2 1>${my_logfile} 2>&1 find /tmp/. \ \( -name "." -o -prune \) \ -name ".rc.listener.[0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*" \ -type d -mtime +7 -exec rm -rf '{}' \; unset LD_LIBRARY_PATH unset ORA_NLS33 unset NLSPATH my_uname_n=$(uname -n) my_uname_s=$(uname -s) [[ ${my_uname_s} == "HP-UX" ]] && typeset -x UNIX95="set" MY_RUN_USER=$(id -un) MY_RUN_UID=$(id -u) for i in /var/opt/oracle/oratab /etc/oratab; do [[ -r ${i} ]] && { MY_ORATAB=${i}; break; } done [[ -z "${MY_ORATAB}" ]] && { print "$(get_cdate) oratab not found." return 127 } function rc_listener { typeset LSNR LSNR_X SUBJECT typeset -u I FLAG MODE ACTION METHOD FLAG_TAB FLAG_TAB2 typeset i j SID MA MP ENVFILE SID_LINE SID_LINE_A typeset ISQL OWNER PID Perl FTIME TNS_ADMIN_TAB ORACLE_HOME_TAB ORACLE_BASE for i do I=${i} if [[ ${I} == FLAG=@([YN]|NO_CHANGE|NC) || ${I} == ACTION=@(START|STOP|RESTART|STAT?(US)|RELOAD|FLAG|PAGE|MAIL) || ${I} == METHOD=@(IMMEDIATE|ABORT) ]] then eval ${I} elif [[ ${I} == LSNR=+([a-zA-Z0-9_:-]) || ${I} == SUBJECT=* ]] then eval ${I%%=*}=\"${i#*=}\" fi done LSNR_X=${LSNR} LSNR=${LSNR_X%:*} typeset -u MODE=${LSNR_X#*:} [[ -z "${LSNR}" ]] && { print "$(get_cdate) Listener name not specified." return 127 } while IFS= read -r i; do [[ ${i} == "##_${LSNR}:"* ]] && { SID_LINE=${i}; break; } if [[ ${LSNR} == LISTENER_* ]]; then SID=${LSNR#*_} elif [[ ${LSNR} == *_LISTENER ]]; then SID=${LSNR%_*} fi [[ -n "${SID}" && ${i} == "${SID}:"* ]] && { : ${SID_LINE_A:=${i}} } done < ${MY_ORATAB} : ${SID_LINE:=${SID_LINE_A}} [[ -z ${SID_LINE} ]] && { print "$(get_cdate) SID_LINE not found in ${MY_ORATAB}." return 127 } set -- $(echo ${SID_LINE} | sed "s/:/ /g") # $(IFS=:; echo {SID_LINE}) has problems # for some versions of ksh93. LSNR_TAB=${1} ORACLE_HOME_TAB=${2} FLAG_TAB=${3} [[ -z ${ORACLE_HOME_TAB} ]] && { print "$(get_cdate) ORACLE_HOME not found from ${SID_LINE}." return 127 } [[ -d ${ORACLE_HOME_TAB} ]] || { print "$(get_cdate) ${ORACLE_HOME_TAB} not found. Possibly on other node of cluster." return 59 } for i in ${ORACLE_HOME_TAB}/network/admin /var/opt/oracle; do [[ -r ${i}/listener.ora ]] && { TNS_ADMIN_TAB=${i}; break; } done [[ -z ${TNS_ADMIN_TAB} ]] && { print "$(get_cdate) TNS_ADMIN not found." return 127 } ISQL=${ORACLE_HOME_TAB}/bin/lsnrctl [[ -x ${ISQL} ]] || { print "$(get_cdate) ${ISQL} not found." return 127 } ORACLE_BASE=${ORACLE_HOME_TAB%/product/*} for i in $ORACLE_BASE/.ora_${LSNR}_env.ksh \ $ORACLE_BASE/.ora_${SID}_env.ksh ; do [[ -r ${i} ]] && { ENVFILE=${i}; break; } done function get_var { typeset -l var=$1 line typeset envfile=$2 [[ -r ${envfile} ]] || return 1 while read line; do [[ $line == ?(* )${var}?( *)=* ]] && { print ${line##*=*( )} return 0 } done < ${envfile} return 1 } set -- $(ls -l ${ISQL}) OWNER=${3} if (( MY_RUN_UID == 0 )); then chown ${OWNER} ${my_logdir} function RUN_ISQL { su ${1} -c "env ORACLE_HOME=${2} \ TNS_ADMIN=${3} \ ${4} $5" } elif [[ ${MY_RUN_USER} == ${OWNER} ]]; then function RUN_ISQL { ORACLE_HOME=${2} \ TNS_ADMIN=${3} \ ${4} $5 } else print "$(get_cdate) You must be root or ${OWNER} to run this." exit 127 fi [[ -o xtrace ]] && typeset -ft $(typeset +f) case ${ACTION} in (STAT?(US)) : ${FLAG:=N} [[ ${MODE} == "NOMONITOR" ]] && { print "$(get_cdate) ${LSNR} was not tested (nomonitor option)." return 55 } [[ ${FLAG} == Y && ${FLAG_TAB} == N ]] && { print "$(get_cdate) ${LSNR} was not tested (N flag); \c" for i in $( print /opt/VRTSvcs/bin/perl5 print /usr/bin/perl print /bin/perl print /usr/local/bin/perl ); do [[ -x ${i} ]] && { Perl=${i}; break; } done FTIME=$(get_var FLAG_TIME ${ENVFILE}) if [[ ${FTIME} == +([0-9]) && -x ${Perl} ]]; then (( i=$(${Perl} -le "print ((-M \"${MY_ORATAB}\")*1440)") )) if (( i >= FTIME )); then print "N flag >= ${FTIME} minutes." return 54 else print "N flag < ${FTIME} minutes." return 53 fi elif [[ -z $(find ${MY_ORATAB} -mtime -1) ]]; then print "N flag >= 1 day." return 54 else print "N flag < 1 day." return 53 fi } ps -u ${OWNER} -o pid,args > ${my_logdir}/stat_${LSNR}_01.out grep -i "[t]nslsnr ${LSNR} " ${my_logdir}/stat_${LSNR}_01.out || { print "$(get_cdate) ${LSNR} was down." return 51 } [[ ${MODE} == "PSONLY" ]] && { print "$(get_cdate) ${LSNR} was up (psonly option)." return 50 } RUN_ISQL ${OWNER} ${ORACLE_HOME_TAB} ${TNS_ADMIN_TAB} ${ISQL} "stat ${LSNR}" 2>&1 | tee ${my_logdir}/stat_${LSNR}_02.out if grep -w "successfully" ${my_logdir}/stat_${LSNR}_02.out; then print "$(get_cdate) ${LSNR} was up." return 50 else print "$(get_cdate) ${LSNR} needs attention (ps up but stat failed)." return 52 fi ;; (START) : ${FLAG:=Y} RUN_ISQL ${OWNER} ${ORACLE_HOME_TAB} ${TNS_ADMIN_TAB} ${ISQL} "start ${LSNR}" [[ ${FLAG} == [YN] ]] && { rc_listener lsnr=${LSNR} action=flag flag=${FLAG} } ;; (STOP) : ${FLAG:=N} [[ ${FLAG} == [YN] ]] && { rc_listener lsnr=${LSNR} action=flag flag=${FLAG} } if [[ ${METHOD} == ABORT ]]; then ps -u ${OWNER} -o pid,args | grep -i "[t]nslsnr ${LSNR} " > ${my_logdir}/stop_${LSNR}_01.out set -- $(< ${my_logdir}/stop_${LSNR}_01.out) PID=$1 [[ -n "${PID}" ]] && { kill -TERM ${PID} sleep 3 ps -p ${PID} -o pid,args && { kill -KILL ${PID} sleep 3 ps -p ${PID} -o pid,args } } else RUN_ISQL ${OWNER} ${ORACLE_HOME_TAB} ${TNS_ADMIN_TAB} ${ISQL} "stop ${LSNR}" fi ;; (RESTART) $0 lsnr=${LSNR_X} action=stop flag=N sleep 3 $0 lsnr=${LSNR_X} action=start flag=Y ;; (RELOAD) RUN_ISQL "reload ${LSNR_X}" ;; (FLAG) [[ ${FLAG} == [YN] ]] || { print ${FLAG_TAB} return 0 } [[ ${FLAG} == ${FLAG_TAB} ]] && { print "$(get_cdate) ${LSNR_X} flag was already ${FLAG}." return 62 } function lock_unlock { # BASH users should set the following option: # # [[ -n $BASH_VERSION ]] && shopt -s extglob # # or equivalent BEFORE using the function. typeset PATH=$(PATH=/bin:/usr/bin getconf PATH) typeset action psid inode name pid time ttl abba id typeset expire=99999999 wait=99999999 T0 eval "$@" function epoch { typeset y m d H M S d dd i seconds set $(LC_ALL=C date -u +"%Y %m %d %H %M %S") y=${1#0} m=${2#0} d=${3#0} H=${4#0} M=${5#0} S=${6#0} (( t = (y-1600+3)/4 - (y-1600+99)/100 + (y-1600+399)/400 - 90 )) (( dd = (y-1970)*365 + t )) (( i = 1 )) while (( i < m )); do if (( i == 4 || i == 6 || i == 9 || i == 11 )); then (( t = 30 )) elif (( i == 2 )); then if (( y%4 == 0 && y%100 != 0 || y%400 == 0 )); then (( t = 29 )) else (( t = 28 )) fi else (( t = 31 )) fi (( dd = dd + t )) (( i = i + 1 )) done (( dd = dd + d - 1 )) (( seconds = dd*24*60*60 + H*60*60 + M*60 + S )) printf "%s\n" $seconds } abba=$(function t { trap 'printf "%s" a' EXIT; }; t; printf "%s" b) function lock_stat { typeset inode lsout name=$1 [[ -L ${name} ]] || { printf "%s\n" "inode=" && return 0; } set -- $(LC_ALL=C ls -il ${name}) printf "%s\n" "inode=${1} ${12} ${13} ${14} ${15}" } function ps_iden { set -- $(LC_ALL=C ps -o user= -o group= -o ppid= -o pgid= -p $1 2>/dev/null) echo $1.$2.$3.$4 return 0 } case ${action} in lock) (( T0 = SECONDS )) while (( SECONDS - T0 <= wait )); do ln -s "pid=$$ time=$(epoch) ttl=${expire} psid=$(ps_iden $$) id=$id" ${name} 2>/dev/null && { case $abba in ab) trap "trap \"rm -f ${name}\" EXIT" EXIT;; *) trap "rm -f ${name}" EXIT;; esac rm -f ${name}.+([0-9]).+([0-9]) return 0 } eval $(lock_stat ${name}) [[ -n ${inode} ]] && { ps -p ${pid} >/dev/null 2>&1 && [[ $(ps_iden ${pid}) = "$psid" ]] && (( $(epoch) < time + ttl )) || find ${name} -inum ${inode} -exec mv -f {} ${name}.$$.${RANDOM} \; } sleep 3 done;; unlock) eval $(lock_stat ${name}) [[ -n ${inode} ]] && find ${name} -inum ${inode} -exec rm -f {} \; && case $abba in ab) trap "trap - EXIT" EXIT;; *) trap - EXIT;; esac && return 0;; esac return 1 } my_lock=; unset my_lock my_lock=/tmp/rc.listener.lock if lock_unlock action=lock name=$my_lock wait=30; then i=${MY_ORATAB} j=/tmp/oratab.$$.tmp cp -p ${i} ${j} sed "s/^\(${LSNR_TAB}:[^:]*:\)[YNyn]\(.*\)$/\1${FLAG}\2/" ${i} > ${j} (( $(wc -c < ${i}) == $(wc -c < ${j}) )) && ( mv ${j} ${i} 2>/dev/null || cp ${j} ${i} ) && lock_unlock action=unlock name=$my_lock else print "$(get_cdate) ${LSNR_X}: Failed to create lock ($my_lock)." fi FLAG_TAB2=$(rc_listener lsnr=${LSNR} action=flag) if [[ ${FLAG_TAB2} == ${FLAG} ]]; then print "$(get_cdate) ${LSNR_X}: flag change to ${FLAG} was successful." return 60 else print "$(get_cdate) ${LSNR_X}: flag change to ${FLAG} FAILED." return 61 fi ;; PAGE|MAIL) MA=$(get_var ${ACTION}list ${ENVFILE}) MP=$(whence mailx || whence mail) : ${SUBJECT:="${my_uname_n}: ${LSNR_X} ${my_base} alert"} [[ -n ${MA} && -x ${MP} && -n "${SUBJECT}" ]] && { ${MP} -s "${SUBJECT}" ${MA} < /dev/null & } ;; esac } function print2 { print -u1 "$1" print -u3 "$1" } function remove_logdir { [[ ${my_args} == *debug=y* ]] && return 0 [[ $1 == /tmp/rc.listener.+([0-9]).+([0-9]).+([0-9]) ]] && { rm -f $1/*_[0-9][0-9].out rmdir $1 } } function flat_opt { typeset o=: i for i; do o=${o}${i}: done print ${o} } [[ -o xtrace ]] && typeset -ft $(typeset +f) LSNR=; unset LSNR LSNR_X=; unset LSNR_X STATUS=; unset STATUS ESTATUS=; unset ESTATUS case ${my_base} in (monitor) if (( $# >= 5 )); then LSNR_X=${5} elif (( $# == 1 )); then LSNR_X=${1} else print2 "$(get_cdate) Wrong number of arguments, type \"$0 help=y\"." exit 100 fi LSNR=${LSNR_X%%:*} rc_listener lsnr=${LSNR_X} action=status flag=y STATUS=$? m=; unset m if (( STATUS == 50 || STATUS == 55 )); then print2 "$(get_cdate) ${LSNR_X} was up." remove_logdir ${my_logdir} exit 110 elif (( STATUS == 59 )); then remove_logdir ${my_logdir} exit 100 elif (( STATUS == 51 )); then m="$(get_cdate) ${LSNR_X} is down. Details in ${my_logdir}/" print2 "${m}" rc_listener lsnr=${LSNR_X} action=page subject="${m}" exit 100 elif (( STATUS == 52 )); then m="$(get_cdate) ${LSNR_X} needed attention. Details in ${my_logdir}/" print2 "${m}" rc_listener lsnr=${LSNR_X} action=page subject="${m}" exit 110 elif (( STATUS == 53 )); then print2 "$(get_cdate) ${LSNR_X} was not tested with recent N flag." remove_logdir ${my_logdir} exit 110 elif (( STATUS == 54 )); then m="$(get_cdate) ${LSNR_X} is not tested with old N flag." print2 "${m}" T=; unset T (( T = $(date +%Y%H%M)%10000 )) (( T >= 800 && T <= 815 )) && rc_listener lsnr=${LSNR_X} action=mail subject="${m}" remove_logdir ${my_logdir} exit 110 else m="$(get_cdate) ${LSNR_X} had unexpected status. Details in ${my_logdir}/" print2 "${m}" rc_listener lsnr=${LSNR_X} action=mail subject="${m}" exit 110 fi ;; (online) print2 "$(get_cdate) Running ${my_base} with $(flat_opt "$@") option." print2 "This may take a few minutes." print2 "When in doubt, please check ${my_logdir}/" if (( $# >= 5 )); then LSNR_X=${5} elif (( $# == 1 )); then LSNR_X=${1} else print2 "$(get_cdate) Wrong number of arguments, type \"$0 help=y\"." exit 100 fi rc_listener lsnr=${LSNR_X} action=page subject="$(get_cdate) startup ${LSNR_X}" LSNR=${LSNR_X%%:*} rc_listener lsnr=${LSNR} action=status flag=n STATUS=$? if (( STATUS == 51 )); then : elif (( STATUS == 50 )); then print2 "$(get_cdate) ${LSNR_X} was already online." exit 0 elif (( STATUS == 59 )); then print2 "$(get_cdate) ORACLE_HOME for ${LSNR} not found to online." exit 1 else rc_listener lsnr=${LSNR_X} action=stop method=abort flag=NC fi rc_listener lsnr=${LSNR_X} action=start flag=NC sleep 3 rc_listener lsnr=${LSNR} action=status flag=n STATUS=$? if (( STATUS == 50 )); then print2 "$(get_cdate) ${LSNR_X} online was successful." remove_logdir ${my_logdir} ESTATUS=0 else print2 "$(get_cdate) ${LSNR_X} online FAILED." ESTATUS=1 fi print2 "$(rc_listener lsnr=${LSNR_X} action=flag flag=y)" exit ${ESTATUS} ;; (offline) print2 "$(get_cdate) Running ${my_base} with $(flat_opt "$@") option." print2 "This may take a few minutes." print2 "When in doubt, please check ${my_logdir}/" if (( $# >= 5 )); then LSNR_X=${5} elif (( $# == 1 )); then LSNR_X=${1} else print2 "$(get_cdate) Wrong number of arguments, type \"$0 help=y\"." exit 100 fi rc_listener lsnr=${LSNR_X} action=page subject="$(get_cdate) shutdown ${LSNR_X} normal." LSNR=${LSNR_X%%:*} rc_listener lsnr=${LSNR} action=stat flag=n STATUS=$? if (( STATUS == 51 )); then print2 "$(get_cdate) ${LSNR_X} was already offline." ESTATUS=0 elif (( STATUS == 59 )); then print2 "$(get_cdate) ORACLE_HOME for ${LSNR} not found to offline." ESTATUS=1 else rc_listener lsnr=${LSNR_X} action=stop flag=NC sleep 3 rc_listener lsnr=${LSNR} action=stat flag=n STATUS=$? if (( STATUS == 51 )); then print2 "$(get_cdate) ${LSNR_X} offline was successful." remove_logdir ${my_logdir} ESTATUS=0 else print2 "$(get_cdate) ${LSNR_X} offline FAILED." ESTATUS=1 fi fi print2 "$(rc_listener lsnr=${LSNR_X} action=flag flag=y)" exit ${ESTATUS} ;; (clean) print2 "$(get_cdate) Running ${my_base} with $(flat_opt "$@") option." print2 "This may take a few minutes." print2 "When in doubt, please check ${my_logdir}/" if (( $# >= 6 )); then CR=$2 LSNR_X=${6} elif (( $# == 1 )); then LSNR_X=${1} CR="manual" else print2 "$(get_cdate) Wrong number of arguments, type \"$0 help=y\"." exit 100 fi print2 "The reason code for this action is ${CR}." rc_listener lsnr=${LSNR_X} action=page subject="$(get_cdate) shutdown ${LSNR_X} kill." rc_listener lsnr=${LSNR_X} action=stop method=abort flag=NC sleep 3 LSNR=${LSNR_X%%:*} rc_listener lsnr=${LSNR} action=status flag=n STATUS=$? if (( STATUS == 51 )); then print2 "$(get_cdate) ${LSNR_X} clean was successful." remove_logdir ${my_logdir} elif (( STATUS == 59 )); then print2 "$(get_cdate) ORACLE_HOME for ${LSNR} not found to clean." else print2 "$(get_cdate) ${LSNR_X} clean FAILED." fi print2 "$(rc_listener lsnr=${LSNR_X} action=flag flag=y)" exit 0 ;; ([SK]+([0-9])?(rc.)@(listener|oracle)?(-*)) i=; unset i j=; unset j flag_option=; unset flag_option if [[ ${my_base} == *@(oracle|listener)-* ]]; then i=${my_base##*@(oracle|listener)-} flag_option= else i=$(sed -n "s/^##_\([^:]*\):[^:]*:[Yy].*/\1/p" ${MY_ORATAB}) : ${i:=$(sed -n "/#/!s/\([^:]*\):[^:]*:[Yy].*/LISTENER_\1/p" ${MY_ORATAB})} flag_option="flag=NC" fi print2 "$(get_cdate) Running ${my_base} with $(flat_opt "$@") option." print2 "This may take a few minutes." print2 "When in doubt, please check ${my_logdir}/" for j in ${i}; do print2 "Working on ${j} ..." [[ $1 == @(start|stop|restart) ]] && { [[ $1 == stop ]] && [[ -r /etc/redhat-release ]] && rm -f /var/lock/subsys/${my_base##[SK]+([0-9])} rc_listener lsnr=${j} action=$1 ${flag_option} sleep 3 [[ $1 == start ]] && [[ -r /etc/redhat-release ]] && touch /var/lock/subsys/${my_base##[SK]+([0-9])} } print2 "$(rc_listener lsnr=${j} action=status flag=n | grep '^[0-9]\{4\}-')" done exit 0 ;; (rc.listener) exec 1>&- 2>&- 1>&3 2>&4 { rc_listener "$@" print "STATUS=$?" } | while IFS= read -r i do [[ ${i} == STATUS=+([0-9]) ]] && { eval ${i}; break; } if [[ ${my_args} == *@(action=@(start|stop|restart)|verbose=y)* ]]; then print -r -- "${i}" else [[ ${i} == @([0-9][0-9][0-9][0-9]-*|[YN]) ]] && { print -r -- "${i}" } fi done remove_logdir ${my_logdir} if (( STATUS == 50 || STATUS == 60 )); then exit 0 elif (( STATUS == 51 )); then exit 1 elif (( STATUS == 1 )); then exit 127 else exit ${STATUS} fi ;; esac ## POD_START ## =head1 NAME ## ## rc.listener - General purpose maintenance utilities for Oracle listener, ## System V (Solaris, AIX, Linux) start/stop scripts, and VCS Sqlnet agents. ## ## =head1 SYNOPSIS ## ## B ## lsnr=I ## action=I ## flag=I (Default Y) ## verbose=I (Default N) ## ## B ## lsnr=I ## action=I ## flag=I (Default N) ## method=I (Default immediate) ## verbose=I (Default N) ## ## B ## lsnr=I ## action=I ## flag=I (Default No flag check) ## verbose=I (Default N) ## ## B ## lsnr=I ## action=I ## verbose=I (Default N) ## ## B ## lsnr=I ## action=I ## verbose=I (Default N) ## ## B ## lsnr=I ## action=I ## flag=I ## verbose=I (Default N) ## ## BIB I ## ## BIlistener-I I ## ## BIoracle-I I (Depreciated) ## ## B I ## ## B B<. . . .> I ## ## B I ## ## B B<. . . .> I ## ## B I ## ## B B<.> B<0|1|2|3|4> B<. . .> I ## ## B I ## ## B B<. . . .> I ## ## B<*> B ## ## B<*> B ## ## =head1 DESCRIPTION ## ## I is a single shell program to start, stop, test Sqlnet ## listener; check and update the flag; and send ## notifications, if configured, for abnormal listener conditions, and ## when the N flag becomes too old. ## ## I is 3-in-1, multifunctional program serving different ## purposes when installed with different names. When named I, ## its canonical name, it is a general purpose program; when linked as ## BIB or BIB-I, ## it is used as System V start / stop script; when linked as ## B, B, B, and B, it is VCS ## (Veritas Cluster Server) Sqlnet agent. ## ## Before we describe each of 3 functionalities, we need to define ## the oratab entries for listener. ## ## =head2 ORATAB ## ## Oracle does not define oratab entries for listener. We use two ways ## to handle this: (1) each Sid has its own listener named LISTENER_Sid; ## or (2) use a commented out entry in the format: ## ## ##_:oracle_home:Y ## ## Use one or the other, do not mix them. For example, if one non-standard ## listener name needs to be listed as above, list all listeners even for ## standard listener names. Otherwise B do not know how many ## listeners you have, and what their names are. ## ## Please see this section in B for relocation of oratab ## for systems which put oratab on /etc. ## ## =head2 FLAG ## ## Please see this section in B for discussion of oracle ## database flag. We confer the same semantics on listener flag. ## ## The VCS agent uses the flag to determine whether to monitor the listener ## or not. If you shutdown the listener for maintenance, ## you should change the flag to N so that the agent won't start it up. ## Change the flag to Y if you want to the agent to monitor it. ## ## B combines the two steps - listener start/stop and flag change - ## for you. ## ## =head2 GENERAL PURPOSE UTILITY ## ## When used as a general purpose utility for most common use, ## you specify two parameters, the listener you are operate on, and the ## action which is either start, stop, restart, reload, status, flag (show or ## change flag. The I option allows you the B ## output. ## ## For the START action, the default behavior is to startup the listener, ## and change the flag to Y. However you can specify the flag to be either ## Y or N, or NO_CHANGE. ## ## For the STOP action, the default behavior is to shutdown the listener ## and change the flag to N. Again you can specify the flag to be either ## Y or N, or NO_CHANGE. ## ## The method option lets you specify how you want to shutdown. The default ## is IMMEDIATE, which uses B command to shutdown the listener. ## The ABORT method kills the listener process. ## ## The FLAG action shows you the current flag, or change it to what you ## asked for. ## ## The STATUS or STAT action checks the health of the listener. ## If the FLAG option is Y, it checks the flag for the listener in ## oratab and only test the listener when the flag is Y. ## ## The B utility can used manually, or embedded in other ## programs. ## ## =head2 SYSTEM V START/STOP SCRIPT ## ## When the program is named as BIB>, or ## BIB, it can be used as ## system V start/stop scripts. The former is to start/stop ## the particular listener regardless the flag. The latter is to ## start/stop ALL listeners whoes flag is Y. ## ## For example: ## ## To start / stop listeners with Y flag on Solaris: ## ## cp rc.listener /etc/init.d/rc.listener ## ln /etc/init.d/rc.listener /etc/rc2.d/S90listener ## ln /etc/init.d/rc.listener /etc/rc0.d/K10listener ## ## The location and naming conventions are slightly different ## on other Sys V derived systems: ## ## On AIX 5.2: ## ## cp rc.listener /etc/rc.d/init.d/rc.listener ## ln /etc/rc.d/init.d/rc.listener /etc/rc.d/rc2.d/S90listener ## ln /etc/rc.d/init.d/rc.listener /etc/rc.d/rc2.d/K10listener ## ## On SuSE Linux (2.4.7): ## ## cp rc.listener /etc/init.d/rc.listener ## ln /etc/init.d/rc.listener /etc/init.d/rc3.d/S90listener ## ln /etc/init.d/rc.listener /etc/init.d/rc3.d/K90listener ## ## B supports chkconfig. On redhat based systems, you ## can use chkconfig to add and delete the service: ## ## # chkconfig --add rc.listener ## # chkconfig --list rc.listener ## rc.listener 0:off 1:off 2:on 3:on 4:on 5:on 6:off ## # chkconfig --del rc.listener ## ## =head2 VCS Sqlnet AGENT ## ## When the program is named B, B, B, and ## B, it can be used as VCS (Veritas Cluster Server) ## Sqlnet agent. ## ## This is done by installing the Solaris package MERotas provided ## in rc.listener distribution. The following procedure is for ## I purpose only. ## ## #* For illustration purpose only, please use package for your platform. *# ## ## mkdir -p /opt/VRTSvcs/bin/Sqlnet ## cp rc.listener /opt/VRTSvcs/bin/Sqlnet/rc.listener ## cd /opt/VRTSvcs/bin/Sqlnet ## for i in online offline clean monitor; do ## ln rc.listener $i ## done ## ln -s ../ScriptAgent SqlnetAgent # VCS provided ## ## Please also see I in the distribution ## on how to add the service to VCS. Lsnr is the sole parameter ## that needs to register in VCS. Basically, ## ## online LSNR = rc.listener lsnr= action=start flag=Y ## offline LSNR = rc.listener lsnr= action=stop method=immediate flag=Y ## clean LSNR = rc.listener lsnr= action=stop method=abort flag=Y ## monitor LSNR = rc.listener lsnr= action=stat flag=Y ## ## We can run the commands on the left side manually before ## testing VCS. ## ## =head2 PSONLY AND NOMONITOR ## ## The I Lsnr can be used in the format LSNR:psonly|nomonitor. ## The qualifiers I and I, which are case inSENsiTIVE, ## are only applicable how the Lsnr is tested. ## ## I, as the name suggests, is used to test only the existence of ## listener process. The presence of the process does not mean the listener ## is working properly. ## ## I, as the name suggests, is used not to test the the ## listener, but considers it to be up. ## ## These two qualifiers are used mainly for VCS, to prevent it from ## automatically restart the listener. It does not affect the failover. ## ## A monitor program should be in place when used these two qualifiers. ## ## =head2 CONFIGURABLE PARAMETERS AND VCS NOTIFICATION ## ## I configuration is required for normal use of I. ## ## However, following the philosophy of "simple things should be easy ## but complicated things should be possible", the configuration ## file in: ## ## $ORACLE_BASE/.ora_${LSNR}_env.ksh or ## $ORACLE_BASE/.ora_${SID}_env.ksh ## ## can be used for these parameters: ## ## MAILLIST ## PAGELIST ## FTIME ## ## The format of specification is "key = value". The left side should ## I the key, and optionally white spaces and other characters; ## the right side should contain the value and possibly white spaces. ## The key is case INsenSItive. ## ## So the following format all valid, and equivalent: ## ## # MailList = dba_list@foo.com ## MAILlist=dba_list@foo.com ## ## I and I are used for VCS agent notification. ## The agent sends page to I when (a) monitor failed; (b) ## monitor produced an unexpected status; (c) listener start and stop. ## Unfortunately, monitor can not send page when the it times ## out. But hopefully, the notification will be sent by clean and ## online. The agent sends mail to I when the N flag for the ## database becomes too old (older than I if set, or 1 day). ## ## The FTIME is a number in minutes, which provides a way for you to tell ## I that you the flag is changed to N for x minutes. I ## will send email to I if this limit is exceeded, once per day ## between 08:00 and 08:15 hours. ## ## =head2 RETURN CODE AND ERROR MESSAGES ## ## The VCS monitor spits the following informational messages ## which can be used for log monitor. The "110" and "100" are ## return code required by VCS. They are I part of the message. ## ## 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was up. ## 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] needed attention. Details in . ## 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was not tested with recent N flag. ## 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was not tested with old N flag. ## 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] had unexpected status. Details in . ## 100 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was down. Details in . ## ## The return codes for system V start / stop script are not used. ## The brief message informs the SA what is going on: ## ## YYYY-MM-DD HH24:MI:SS Running S|Klistener with start|stop option. ## This may take a few minutes. ## When in doubt, please check . ## Working on ... ## YYYY-MM-DD HH24:MI:SS was up|down. ## ## The return codes for start/stop should not be trusted. Either check the specific ## messages produced by I, or follow up start/stop with stat. The return ## code and informational messages for B status option are: ## ## 0 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was up. ## 1 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was down. ## !0 YYYY-MM-DD HH24:MI:SS ## ## For example, you can say: ## ## rc.listener lsnr= action=stat || print " did not come up." ## ## For flag change, it is better to check directly, for example: ## ## [[ $(rc.listener lsnr= action=flag) == "Y" ]] || exit 1 ## ## =head1 PHILOSOPHY ## ## Please see this section in B. ## ## =head1 MISCELLANEOUS INFORMATION ## ## Please see this section in B. ## ## =head1 AUTHOR AND ACKNOWLEDGMENT ## ## Michael Wang > with help from many people. ## Contributions are acknowledged in the version history within ## the programs. ## ## =head1 VERSION HISTORY ## ## version 10.6, 2008-05-26, Michael Wang . ## * Port to ksh 88 requested and sponsored by ## + DataBase Intelligence Group (http://dbigusa.com). ## * Various fix and clean up. ## ## version 10.5, 2004-10-18, Michael Wang . ## * Enhanced get_var function. ## ## version 10.4, 2004-08-29, Michael Wang . ## * Tested on standalone AIX 5.2 with reboot. ## ## version 10.3, 2004-08-23, Michael Wang . ## * revert to changing flag to Y after online|offline|clean ## + per discovery of VCS behavior by Jose Bacalla. ## * Added flat_opt function. ## ## version 10.2, 2004-08-21, Michael Wang . ## * Tested Linux RAC (Oracle 9.2.0.4 on RHEL 3.0 compatible). ## ## version 10.1, 2004-08-20, Michael Wang . ## * Tested on AIX 5.2 VCS with Roy Morton. ## ## version 10.0, 2004-08-10, Michael Wang . ## * Rewrite to address the following issues: ## + PSONLY and NOMONITOR options. ## + Optional notification for monitor failure and state change. ## + Self maintained logs: clean user experience and capability to debug. ## + Linux (redhat) support: chkconfig and subsys lock. ## + modularity attempt for futher development: rc_listener function. ## ## version 9.6, 2003-06-10, Michael Wang . ## * Handles LISTENER_, listener_, and LisTNer_. ## ## version 9.5, 2003-03-04, Michael Wang . ## * Changed "ksh $0" to "$0" so that what in #! line will be used. ## * Set UNIX95 for HP-UX to get SUSv2 bahavior for ps command (-o option). ## ## version 9.3b, 2002-11-20, Michael Wang . ## * Added "[[ -n "$PID" ]]" before "kill $PID". ## ## version 9.3a, 2002-10-01, Michael Wang . ## * Fixed the typo "RANDOWM => RANDOM". ## ## version 9.3, 2002-04-25, Michael Wang . ## * Added version=y. ## * "kill -KILL $i" => "kill -KILL $PID". ## ## version 9.2, 2002-01-14, Michael Wang . ## * Accepts both LISTENER_SID and SID_LISTENER as site standard. ## * Fixed the problem that "help=y" leaves an empty dir in /tmp. ## * Added the missing 2nd "$" in "cp -p $ORATAB $ORATAB.tmp". ## * Changed "exit -- $?" to "exit $?": (exit -- 1); print $? => 0 in ksh88. ## ## version 9.1, 2001-12-03, Michael Wang (xw73@columbia.edu). ## * New way of getting SID_LINE: ## (1) SID_LISTENER => $ORACLE_BASE/.rc.oracle.cf: ##_:* ## (2) LISTENER_NAME => $ORACLE_BASE/.rc.oracle.cf: ##_:* ## (3) /var/opt/oracle/oratab: ##_ ## (4) /var/opt/oracle/oratab: SID:* ## * Derive owner from $ORACLE_HOME/bin/lsnrctl. ## * TNS_ADMIN default to $ORACLE_HOME/network/admin or /var/opt/oracle ## wherever listener.ora exists. ## * Added reload option. ## * Fix FTIME issue: ## j=; unset j; j=011; print "$j" => 9 ## typeset -Z6 j; j=; print "$j" => "" ## - Bourne shell detection simplification. "PATH= print" and (print) forks, ## and only forked stderr can be redirected in Bourne shell. ## - Changed "exit -- -1" to "exit 127". (exit -- -1); print $? => 0 in ksh88. ## ## version 9.0, 05/26/2001, Michael Wang (xw73@columbia.edu). ## * Added "METHOD=abort" for stop option, which is used by VCS clean, per ## Mike Suarez. This fixes problem preventing failover when network is down. ## * Added "ps" test in monitor to prevent hanging when network is down. ## * Added support for locally installed Oracle software ("VCS Concurrency ## Violation") per Alfonso Di Capo, Andrew Blatt, Babar Saeed, Diane Yee. ## * Added pager/email notification, and action=page|mail, message=... options ## with help from Andrew Blatt, Janet Zhu on CVS. "A nasty solution for a ## nasty problem in a nasty world"(TM). ## * Check FLAG before lsnrctl to ease the upgrade per Raj Pande. ## * "help=y" now uses "real man"(TM) page. Eliminated less helpful online help. ## * FLAG/FTIME update fix. ## - used POSIX PATH. ## - Use of POSIX "id -u" and "id -un" command. ## - Added "print" in additon to "$RANDOM" for ksh test to exclude bash. ## - Fixed "... | SUCCESS=Y". In PD KSH v5.2.14 99/07/13.2 (on Red Hat Linux ## 7.1, Kernel 2.4.4), the last pipeline is not run in current shell. ## - Changed "exit -1" to "exit 127" for PD KSH. ## - Workaround different behaviors on "Ctrl-C" on trap between PD KSH and ## AT&T KSH: PD KSH does not run exit trap upon "Ctrl-C", AT&T KSH does. ## - uses cp -p $ORATAB $ORATAB.tmp to create a temp file with same permission. ## - Eliminate fork (grep) in processing SID_LINE. ## ## version 5.4, 02/21/2001, Michael Wang (xw73@columbia.edu). ## * Tightened up the locking code. ## * Added restart option for convenience only per Raj Pande. It stop and start ## the listener with default options. ## * Added identifier "$LISTENER: " for flag change message. ## * exit 255 => exit -1 ## * Change [[ -z $ORATAB && -r $i ]] && ORATAB=$i to ## [[ -r $i ]] && { ORATAB=$i; break; } ## * Last line of start/stop options was: [[ $SHOW = Y ]] && exit -1. ## [[ $SHOW = Y ]] would be the last command if it is false and hence its ## status becomes the status of the script. The last line is changed to: ## (( status == 0 && fstatus == 0 )). ## ## version 5.3, 01/31/2001, Michael Wang (xw73@columbia.edu). ## * Added date before "tail -1". ## * Change [[ -z $Perl && -x $i ]] && Perl=$i to ## [[ -x $i ]] && { Perl=$i; break; } for efficiency. ## ## version 5.2, 01/26/2001, Michael Wang (xw73@columbia.edu). ## * Added ftime= option for start/stop. ## ## version 5.1, 01/05/2000, Michael Wang (xw73@columbia.edu). ## * change "exit 0" to "exit $?" in oracle-SID case. This affects backup. ## * change "FOREVER" to "1 DAY". ## ## version 5.0, 12/25/2000, Michael Wang (xw73@columbia.edu). ## To keep in sync with rc.oracle ## ## version 4.0, 10/10/2000, Michael Wang (xw73@columbia.edu). ## * version number advanced beyond pi. ## * Exit code changed from 0 to 4 when Oracle executable can not be found. ## * Array can not be reset on Version M-11/16/88f on AIX 4.3.3 ## i[0]=; typeset -u i; i=; unset i; i=b; echo $i => B ## Changed to i to ix to avoid conflict. ## * "==" in [[ string == pattern ]] is replaced by "=" for compatibility ## with older Korn Shell (eg Version M-11/16/88f). ## * Get rid of the_space_holder. ## * Unset name for name=value pair. Example, TEST=. ## ## version 3.14159, 08/18/2000, Michael Wang (xw73@columbia.edu). ## * Rewrite "[[ -z $(eval echo \$$i) ]]" as "eval [[ -z \$$i ]]". ## This reduces the number of forks. This was suggested by ## Dan A. Mercer on the internet. ## * Prerequisite: ## - /var/opt/oracle/listener.LISTENER_NAME: ## LISTENER_NAME:ORACLE_HOME:Y/N:TNS_ADMIN:OWNER ## ## version 3.1415, 07/22/2000, Michael Wang (xw73@columbia.edu). ## * Expanded listener's oratab to include owner in support of running as ## different $OWNER. ## * Enhanced SHOW=Y option to display statement to lsnrctl. ## * FLAG=NULL option for start/stop to leave FLAG alone. ## * unset LD_LIBRARY_PATH. ## Properly linked oracle executables do not need LD_LIBRARY_PATH. ## In Oracle 8i, set LD_LIBRARY_PATH causes listener problem, Ref: ## TAR 12953862.600, Doc ID 1023333.1, Bug ID 1147434. ## * MASSIVE code clean up to support above functionalities and for ## programming purity and efficiency. ## ## version 3.141, 07/09/2000, Michael Wang (xw73@columbia.edu). ## * Minor change on PATH and id for Linux compatibility. ## ## version 3.14, 03/17/2000, Michael Wang (xw73@columbia.edu). ## * implemented TNS_ADMIN. ## ## version 3.1, 01/20/2000, Michael Wang (xw73@columbia.edu). ## * Minor midifications in Oracle env variable determination and verification. ## ## version 3.0, 12/27/1999, Michael Wang (xw73@columbia.edu). ## * Modified in sync with oracle-SID ## ## version 1.0, 07/29/1998, Michael Wang (xw73@columbia.edu). ## * IPO. ## POD_STOP ## MAN_START ## .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 ## .\" ## .\" Standard preamble: ## .\" ======================================================================== ## .de Sh \" Subsection heading ## .br ## .if t .Sp ## .ne 5 ## .PP ## \fB\\$1\fR ## .PP ## .. ## .de Sp \" Vertical space (when we can't use .PP) ## .if t .sp .5v ## .if n .sp ## .. ## .de Vb \" Begin verbatim text ## .ft CW ## .nf ## .ne \\$1 ## .. ## .de Ve \" End verbatim text ## .ft R ## .fi ## .. ## .\" Set up some character translations and predefined strings. \*(-- will ## .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left ## .\" double quote, and \*(R" will give a right double quote. | will give a ## .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to ## .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' ## .\" expand to `' in nroff, nothing in troff, for use with C<>. ## .tr \(*W-|\(bv\*(Tr ## .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' ## .ie n \{\ ## . ds -- \(*W- ## . ds PI pi ## . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch ## . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch ## . ds L" "" ## . ds R" "" ## . ds C` "" ## . ds C' "" ## 'br\} ## .el\{\ ## . ds -- \|\(em\| ## . ds PI \(*p ## . ds L" `` ## . ds R" '' ## 'br\} ## .\" ## .\" If the F register is turned on, we'll generate index entries on stderr for ## .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index ## .\" entries marked with X<> in POD. Of course, you'll have to process the ## .\" output yourself in some meaningful fashion. ## .if \nF \{\ ## . de IX ## . tm Index:\\$1\t\\n%\t"\\$2" ## .. ## . nr % 0 ## . rr F ## .\} ## .\" ## .\" For nroff, turn off justification. Always turn off hyphenation; it makes ## .\" way too many mistakes in technical documents. ## .hy 0 ## .if n .na ## .\" ## .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). ## .\" Fear. Run. Save yourself. No user-serviceable parts. ## . \" fudge factors for nroff and troff ## .if n \{\ ## . ds #H 0 ## . ds #V .8m ## . ds #F .3m ## . ds #[ \f1 ## . ds #] \fP ## .\} ## .if t \{\ ## . ds #H ((1u-(\\\\n(.fu%2u))*.13m) ## . ds #V .6m ## . ds #F 0 ## . ds #[ \& ## . ds #] \& ## .\} ## . \" simple accents for nroff and troff ## .if n \{\ ## . ds ' \& ## . ds ` \& ## . ds ^ \& ## . ds , \& ## . ds ~ ~ ## . ds / ## .\} ## .if t \{\ ## . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" ## . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' ## . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' ## . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' ## . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' ## . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' ## .\} ## . \" troff and (daisy-wheel) nroff accents ## .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' ## .ds 8 \h'\*(#H'\(*b\h'-\*(#H' ## .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] ## .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' ## .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' ## .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] ## .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] ## .ds ae a\h'-(\w'a'u*4/10)'e ## .ds Ae A\h'-(\w'A'u*4/10)'E ## . \" corrections for vroff ## .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' ## .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' ## . \" for low resolution devices (crt and lpr) ## .if \n(.H>23 .if \n(.V>19 \ ## \{\ ## . ds : e ## . ds 8 ss ## . ds o a ## . ds d- d\h'-1'\(ga ## . ds D- D\h'-1'\(hy ## . ds th \o'bp' ## . ds Th \o'LP' ## . ds ae ae ## . ds Ae AE ## .\} ## .rm #[ #] #H #V #F C ## .\" ======================================================================== ## .\" ## .IX Title "RC.LISTENER 1" ## .TH RC.LISTENER 1 "2008-05-29" "perl v5.8.8" "User Contributed Perl Documentation" ## .SH "NAME" ## rc.listener \- General purpose maintenance utilities for Oracle listener, ## System V (Solaris, AIX, Linux) start/stop scripts, and VCS Sqlnet agents. ## .SH "SYNOPSIS" ## .IX Header "SYNOPSIS" ## \&\fBrc.listener\fR ## lsnr=\fI\s-1LNSR\s0\fR ## action=\fIstart\fR ## flag=\fIY|N|NO_CHANGE|NC\fR (Default Y) ## verbose=\fIY|N\fR (Default N) ## .PP ## \&\fBrc.listener\fR ## lsnr=\fI\s-1LNSR\s0\fR ## action=\fIstop\fR ## flag=\fIY|N|NO_CHANGE|NC\fR (Default N) ## method=\fIimmediate|abort\fR (Default immediate) ## verbose=\fIY|N\fR (Default N) ## .PP ## \&\fBrc.listener\fR ## lsnr=\fILNSR:psonly|nomonitor\fR ## action=\fIstatus|stat\fR ## flag=\fIY|N\fR (Default No flag check) ## verbose=\fIY|N\fR (Default N) ## .PP ## \&\fBrc.listener\fR ## lsnr=\fI\s-1LNSR\s0\fR ## action=\fIrestart\fR ## verbose=\fIY|N\fR (Default N) ## .PP ## \&\fBrc.listener\fR ## lsnr=\fI\s-1LNSR\s0\fR ## action=\fIreload\fR ## verbose=\fIY|N\fR (Default N) ## .PP ## \&\fBrc.listener\fR ## lsnr=\fI\s-1LNSR\s0\fR ## action=\fIflag\fR ## flag=\fIY|N\fR ## verbose=\fIY|N\fR (Default N) ## .PP ## \&\fBS|K\fR\fInumber\fR\fBlistener\fR \fIstart|stop|restart|reload|status|stat\fR ## .PP ## \&\fBS|K\fR\fInumber\fRlistener\-\fI\s-1LNSR\s0\fR \fIstart|stop|restart|reload|status|stat\fR ## .PP ## \&\fBS|K\fR\fInumber\fRoracle\-\fI\s-1LNSR\s0\fR \fIstart|stop|restart|reload|status|stat\fR (Depreciated) ## .PP ## \&\fBonline\fR \fILNSR[:psonly|nomonitor]\fR ## .PP ## \&\fBonline\fR \fB. . . .\fR \fILNSR[:psonly|nomonitor]\fR ## .PP ## \&\fBoffline\fR \fILNSR[:psonly|nomonitor]\fR ## .PP ## \&\fBoffline\fR \fB. . . .\fR \fILNSR[:psonly|nomonitor]\fR ## .PP ## \&\fBclean\fR \fILNSR[:psonly|nomonitor]\fR ## .PP ## \&\fBclean\fR \fB.\fR \fB0|1|2|3|4\fR \fB. . .\fR \fILNSR[:psonly|nomonitor]\fR ## .PP ## \&\fBmonitor\fR \fILNSR[:psonly|nomonitor]\fR ## .PP ## \&\fBmonitor\fR \fB. . . .\fR \fILNSR[:psonly|nomonitor]\fR ## .PP ## \&\fB*\fR \fBhelp=y\fR ## .PP ## \&\fB*\fR \fBversion=y\fR ## .SH "DESCRIPTION" ## .IX Header "DESCRIPTION" ## \&\fIrc.listener\fR is a single shell program to start, stop, test Sqlnet ## listener; check and update the flag; and send ## notifications, if configured, for abnormal listener conditions, and ## when the N flag becomes too old. ## .PP ## \&\fIrc.listener\fR is 3\-in\-1, multifunctional program serving different ## purposes when installed with different names. When named \fIrc.listener\fR, ## its canonical name, it is a general purpose program; when linked as ## \&\fBS|K\fR\fInumber\fR\fBlistener\fR or \fBS|K\fR\fInumber\fR\fBlistener\fR\-\fI\s-1LNSR\s0\fR, ## it is used as System V start / stop script; when linked as ## \&\fBonline\fR, \fBoffline\fR, \fBclean\fR, and \fBmonitor\fR, it is \s-1VCS\s0 ## (Veritas Cluster Server) Sqlnet agent. ## .PP ## Before we describe each of 3 functionalities, we need to define ## the oratab entries for listener. ## .Sh "\s-1ORATAB\s0" ## .IX Subsection "ORATAB" ## Oracle does not define oratab entries for listener. We use two ways ## to handle this: (1) each Sid has its own listener named LISTENER_Sid; ## or (2) use a commented out entry in the format: ## .PP ## .Vb 1 ## \& ##_:oracle_home:Y ## .Ve ## .PP ## Use one or the other, do not mix them. For example, if one non-standard ## listener name needs to be listed as above, list all listeners even for ## standard listener names. Otherwise \fBrc.listener\fR do not know how many ## listeners you have, and what their names are. ## .PP ## Please see this section in \fBrc.oracle help=y\fR for relocation of oratab ## for systems which put oratab on /etc. ## .Sh "\s-1FLAG\s0" ## .IX Subsection "FLAG" ## Please see this section in \fBrc.oracle help=y\fR for discussion of oracle ## database flag. We confer the same semantics on listener flag. ## .PP ## The \s-1VCS\s0 agent uses the flag to determine whether to monitor the listener ## or not. If you shutdown the listener for maintenance, ## you should change the flag to N so that the agent won't start it up. ## Change the flag to Y if you want to the agent to monitor it. ## .PP ## \&\fBrc.listener\fR combines the two steps \- listener start/stop and flag change \- ## for you. ## .Sh "\s-1GENERAL\s0 \s-1PURPOSE\s0 \s-1UTILITY\s0" ## .IX Subsection "GENERAL PURPOSE UTILITY" ## When used as a general purpose utility for most common use, ## you specify two parameters, the listener you are operate on, and the ## action which is either start, stop, restart, reload, status, flag (show or ## change flag. The \fIverbose=y\fR option allows you the \fBlsnrctl\fR ## output. ## .PP ## For the \s-1START\s0 action, the default behavior is to startup the listener, ## and change the flag to Y. However you can specify the flag to be either ## Y or N, or \s-1NO_CHANGE\s0. ## .PP ## For the \s-1STOP\s0 action, the default behavior is to shutdown the listener ## and change the flag to N. Again you can specify the flag to be either ## Y or N, or \s-1NO_CHANGE\s0. ## .PP ## The method option lets you specify how you want to shutdown. The default ## is \s-1IMMEDIATE\s0, which uses \fBlsnrctl stop\fR command to shutdown the listener. ## The \s-1ABORT\s0 method kills the listener process. ## .PP ## The \s-1FLAG\s0 action shows you the current flag, or change it to what you ## asked for. ## .PP ## The \s-1STATUS\s0 or \s-1STAT\s0 action checks the health of the listener. ## If the \s-1FLAG\s0 option is Y, it checks the flag for the listener in ## oratab and only test the listener when the flag is Y. ## .PP ## The \fBrc.listener\fR utility can used manually, or embedded in other ## programs. ## .Sh "\s-1SYSTEM\s0 V \s-1START/STOP\s0 \s-1SCRIPT\s0" ## .IX Subsection "SYSTEM V START/STOP SCRIPT" ## When the program is named as \fBS|K\fR\fInumber\fR\fBlistener\-\f(BI\s-1LSNR\s0\fB\fR, or ## \&\fBS|K\fR\fInumber\fR\fBlistener\fR, it can be used as ## system V start/stop scripts. The former is to start/stop ## the particular listener regardless the flag. The latter is to ## start/stop \s-1ALL\s0 listeners whoes flag is Y. ## .PP ## For example: ## .PP ## To start / stop listeners with Y flag on Solaris: ## .PP ## .Vb 3 ## \& cp rc.listener /etc/init.d/rc.listener ## \& ln /etc/init.d/rc.listener /etc/rc2.d/S90listener ## \& ln /etc/init.d/rc.listener /etc/rc0.d/K10listener ## .Ve ## .PP ## The location and naming conventions are slightly different ## on other Sys V derived systems: ## .PP ## On \s-1AIX\s0 5.2: ## .PP ## .Vb 3 ## \& cp rc.listener /etc/rc.d/init.d/rc.listener ## \& ln /etc/rc.d/init.d/rc.listener /etc/rc.d/rc2.d/S90listener ## \& ln /etc/rc.d/init.d/rc.listener /etc/rc.d/rc2.d/K10listener ## .Ve ## .PP ## On SuSE Linux (2.4.7): ## .PP ## .Vb 3 ## \& cp rc.listener /etc/init.d/rc.listener ## \& ln /etc/init.d/rc.listener /etc/init.d/rc3.d/S90listener ## \& ln /etc/init.d/rc.listener /etc/init.d/rc3.d/K90listener ## .Ve ## .PP ## \&\fBrc.listener\fR supports chkconfig. On redhat based systems, you ## can use chkconfig to add and delete the service: ## .PP ## .Vb 4 ## \& # chkconfig --add rc.listener ## \& # chkconfig --list rc.listener ## \& rc.listener 0:off 1:off 2:on 3:on 4:on 5:on 6:off ## \& # chkconfig --del rc.listener ## .Ve ## .Sh "\s-1VCS\s0 Sqlnet \s-1AGENT\s0" ## .IX Subsection "VCS Sqlnet AGENT" ## When the program is named \fBonline\fR, \fBoffline\fR, \fBclean\fR, and ## \&\fBmonitor\fR, it can be used as \s-1VCS\s0 (Veritas Cluster Server) ## Sqlnet agent. ## .PP ## This is done by installing the Solaris package MERotas provided ## in rc.listener distribution. The following procedure is for ## \&\fIillustration\fR purpose only. ## .PP ## .Vb 1 ## \& #* For illustration purpose only, please use package for your platform. *# ## .Ve ## .PP ## .Vb 7 ## \& mkdir -p /opt/VRTSvcs/bin/Sqlnet ## \& cp rc.listener /opt/VRTSvcs/bin/Sqlnet/rc.listener ## \& cd /opt/VRTSvcs/bin/Sqlnet ## \& for i in online offline clean monitor; do ## \& ln rc.listener $i ## \& done ## \& ln -s ../ScriptAgent SqlnetAgent # VCS provided ## .Ve ## .PP ## Please also see \fIadd_sqlnet_to_vcs.ksh\fR in the distribution ## on how to add the service to \s-1VCS\s0. Lsnr is the sole parameter ## that needs to register in \s-1VCS\s0. Basically, ## .PP ## .Vb 4 ## \& online LSNR = rc.listener lsnr= action=start flag=Y ## \& offline LSNR = rc.listener lsnr= action=stop method=immediate flag=Y ## \& clean LSNR = rc.listener lsnr= action=stop method=abort flag=Y ## \& monitor LSNR = rc.listener lsnr= action=stat flag=Y ## .Ve ## .PP ## We can run the commands on the left side manually before ## testing \s-1VCS\s0. ## .Sh "\s-1PSONLY\s0 \s-1AND\s0 \s-1NOMONITOR\s0" ## .IX Subsection "PSONLY AND NOMONITOR" ## The \fIextended\fR Lsnr can be used in the format LSNR:psonly|nomonitor. ## The qualifiers \fIpsonly\fR and \fInomonitor\fR, which are case inSENsiTIVE, ## are only applicable how the Lsnr is tested. ## .PP ## \&\fIpsonly\fR, as the name suggests, is used to test only the existence of ## listener process. The presence of the process does not mean the listener ## is working properly. ## .PP ## \&\fInomonitor\fR, as the name suggests, is used not to test the the ## listener, but considers it to be up. ## .PP ## These two qualifiers are used mainly for \s-1VCS\s0, to prevent it from ## automatically restart the listener. It does not affect the failover. ## .PP ## A monitor program should be in place when used these two qualifiers. ## .Sh "\s-1CONFIGURABLE\s0 \s-1PARAMETERS\s0 \s-1AND\s0 \s-1VCS\s0 \s-1NOTIFICATION\s0" ## .IX Subsection "CONFIGURABLE PARAMETERS AND VCS NOTIFICATION" ## \&\fI\s-1ZERO\s0\fR configuration is required for normal use of \fIrc.listener\fR. ## .PP ## However, following the philosophy of \*(L"simple things should be easy ## but complicated things should be possible\*(R", the configuration ## file in: ## .PP ## .Vb 2 ## \& $ORACLE_BASE/.ora_${LSNR}_env.ksh or ## \& $ORACLE_BASE/.ora_${SID}_env.ksh ## .Ve ## .PP ## can be used for these parameters: ## .PP ## .Vb 3 ## \& MAILLIST ## \& PAGELIST ## \& FTIME ## .Ve ## .PP ## The format of specification is \*(L"key = value\*(R". The left side should ## \&\fIcontains\fR the key, and optionally white spaces and other characters; ## the right side should contain the value and possibly white spaces. ## The key is case INsenSItive. ## .PP ## So the following format all valid, and equivalent: ## .PP ## .Vb 2 ## \& # MailList = dba_list@foo.com ## \& MAILlist=dba_list@foo.com ## .Ve ## .PP ## \&\fI\s-1MAILLIST\s0\fR and \fI\s-1PAGELIST\s0\fR are used for \s-1VCS\s0 agent notification. ## The agent sends page to \fI\s-1PAGELIST\s0\fR when (a) monitor failed; (b) ## monitor produced an unexpected status; (c) listener start and stop. ## Unfortunately, monitor can not send page when the it times ## out. But hopefully, the notification will be sent by clean and ## online. The agent sends mail to \fI\s-1MAILLIST\s0\fR when the N flag for the ## database becomes too old (older than \fI\s-1FTIME\s0\fR if set, or 1 day). ## .PP ## The \s-1FTIME\s0 is a number in minutes, which provides a way for you to tell ## \&\fIrc.listener\fR that you the flag is changed to N for x minutes. \fIrc.listener\fR ## will send email to \fI\s-1MAILLIST\s0\fR if this limit is exceeded, once per day ## between 08:00 and 08:15 hours. ## .Sh "\s-1RETURN\s0 \s-1CODE\s0 \s-1AND\s0 \s-1ERROR\s0 \s-1MESSAGES\s0" ## .IX Subsection "RETURN CODE AND ERROR MESSAGES" ## The \s-1VCS\s0 monitor spits the following informational messages ## which can be used for log monitor. The \*(L"110\*(R" and \*(L"100\*(R" are ## return code required by \s-1VCS\s0. They are \fInot\fR part of the message. ## .PP ## .Vb 6 ## \& 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was up. ## \& 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] needed attention. Details in . ## \& 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was not tested with recent N flag. ## \& 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was not tested with old N flag. ## \& 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] had unexpected status. Details in . ## \& 100 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was down. Details in . ## .Ve ## .PP ## The return codes for system V start / stop script are not used. ## The brief message informs the \s-1SA\s0 what is going on: ## .PP ## .Vb 5 ## \& YYYY-MM-DD HH24:MI:SS Running S|Klistener with start|stop option. ## \& This may take a few minutes. ## \& When in doubt, please check . ## \& Working on ... ## \& YYYY-MM-DD HH24:MI:SS was up|down. ## .Ve ## .PP ## The return codes for start/stop should not be trusted. Either check the specific ## messages produced by \fIlsnrctl\fR, or follow up start/stop with stat. The return ## code and informational messages for \fBrc.listener\fR status option are: ## .PP ## .Vb 3 ## \& 0 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was up. ## \& 1 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was down. ## \& !0 YYYY-MM-DD HH24:MI:SS ## .Ve ## .PP ## For example, you can say: ## .PP ## .Vb 1 ## \& rc.listener lsnr= action=stat || print " did not come up." ## .Ve ## .PP ## For flag change, it is better to check directly, for example: ## .PP ## .Vb 1 ## \& [[ $(rc.listener lsnr= action=flag) == "Y" ]] || exit 1 ## .Ve ## .SH "PHILOSOPHY" ## .IX Header "PHILOSOPHY" ## Please see this section in \fBrc.oracle help=y\fR. ## .SH "MISCELLANEOUS INFORMATION" ## .IX Header "MISCELLANEOUS INFORMATION" ## Please see this section in \fBrc.oracle help=y\fR. ## .SH "AUTHOR AND ACKNOWLEDGMENT" ## .IX Header "AUTHOR AND ACKNOWLEDGMENT" ## Michael Wang <\fIxw73@columbia.edu\fR> with help from many people. ## Contributions are acknowledged in the version history within ## the programs. ## .SH "VERSION HISTORY" ## .IX Header "VERSION HISTORY" ## .Vb 4 ## \& version 10.6, 2008-05-26, Michael Wang . ## \& * Port to ksh 88 requested and sponsored by ## \& + DataBase Intelligence Group (http://dbigusa.com). ## \& * Various fix and clean up. ## .Ve ## .PP ## .Vb 2 ## \& version 10.5, 2004-10-18, Michael Wang . ## \& * Enhanced get_var function. ## .Ve ## .PP ## .Vb 2 ## \& version 10.4, 2004-08-29, Michael Wang . ## \& * Tested on standalone AIX 5.2 with reboot. ## .Ve ## .PP ## .Vb 4 ## \& version 10.3, 2004-08-23, Michael Wang . ## \& * revert to changing flag to Y after online|offline|clean ## \& + per discovery of VCS behavior by Jose Bacalla. ## \& * Added flat_opt function. ## .Ve ## .PP ## .Vb 2 ## \& version 10.2, 2004-08-21, Michael Wang . ## \& * Tested Linux RAC (Oracle 9.2.0.4 on RHEL 3.0 compatible). ## .Ve ## .PP ## .Vb 2 ## \& version 10.1, 2004-08-20, Michael Wang . ## \& * Tested on AIX 5.2 VCS with Roy Morton. ## .Ve ## .PP ## .Vb 7 ## \& version 10.0, 2004-08-10, Michael Wang . ## \& * Rewrite to address the following issues: ## \& + PSONLY and NOMONITOR options. ## \& + Optional notification for monitor failure and state change. ## \& + Self maintained logs: clean user experience and capability to debug. ## \& + Linux (redhat) support: chkconfig and subsys lock. ## \& + modularity attempt for futher development: rc_listener function. ## .Ve ## .PP ## .Vb 2 ## \& version 9.6, 2003-06-10, Michael Wang . ## \& * Handles LISTENER_, listener_, and LisTNer_. ## .Ve ## .PP ## .Vb 3 ## \& version 9.5, 2003-03-04, Michael Wang . ## \& * Changed "ksh $0" to "$0" so that what in #! line will be used. ## \& * Set UNIX95 for HP-UX to get SUSv2 bahavior for ps command (-o option). ## .Ve ## .PP ## .Vb 2 ## \& version 9.3b, 2002-11-20, Michael Wang . ## \& * Added "[[ -n "$PID" ]]" before "kill $PID". ## .Ve ## .PP ## .Vb 2 ## \& version 9.3a, 2002-10-01, Michael Wang . ## \& * Fixed the typo "RANDOWM => RANDOM". ## .Ve ## .PP ## .Vb 3 ## \& version 9.3, 2002-04-25, Michael Wang . ## \& * Added version=y. ## \& * "kill -KILL $i" => "kill -KILL $PID". ## .Ve ## .PP ## .Vb 5 ## \& version 9.2, 2002-01-14, Michael Wang . ## \& * Accepts both LISTENER_SID and SID_LISTENER as site standard. ## \& * Fixed the problem that "help=y" leaves an empty dir in /tmp. ## \& * Added the missing 2nd "$" in "cp -p $ORATAB $ORATAB.tmp". ## \& * Changed "exit -- $?" to "exit $?": (exit -- 1); print $? => 0 in ksh88. ## .Ve ## .PP ## .Vb 16 ## \& version 9.1, 2001-12-03, Michael Wang (xw73@columbia.edu). ## \& * New way of getting SID_LINE: ## \& (1) SID_LISTENER => $ORACLE_BASE/.rc.oracle.cf: ##_:* ## \& (2) LISTENER_NAME => $ORACLE_BASE/.rc.oracle.cf: ##_:* ## \& (3) /var/opt/oracle/oratab: ##_ ## \& (4) /var/opt/oracle/oratab: SID:* ## \& * Derive owner from $ORACLE_HOME/bin/lsnrctl. ## \& * TNS_ADMIN default to $ORACLE_HOME/network/admin or /var/opt/oracle ## \& wherever listener.ora exists. ## \& * Added reload option. ## \& * Fix FTIME issue: ## \& j=; unset j; j=011; print "$j" => 9 ## \& typeset -Z6 j; j=; print "$j" => "" ## \& - Bourne shell detection simplification. "PATH= print" and (print) forks, ## \& and only forked stderr can be redirected in Bourne shell. ## \& - Changed "exit -- -1" to "exit 127". (exit -- -1); print $? => 0 in ksh88. ## .Ve ## .PP ## .Vb 22 ## \& version 9.0, 05/26/2001, Michael Wang (xw73@columbia.edu). ## \& * Added "METHOD=abort" for stop option, which is used by VCS clean, per ## \& Mike Suarez. This fixes problem preventing failover when network is down. ## \& * Added "ps" test in monitor to prevent hanging when network is down. ## \& * Added support for locally installed Oracle software ("VCS Concurrency ## \& Violation") per Alfonso Di Capo, Andrew Blatt, Babar Saeed, Diane Yee. ## \& * Added pager/email notification, and action=page|mail, message=... options ## \& with help from Andrew Blatt, Janet Zhu on CVS. "A nasty solution for a ## \& nasty problem in a nasty world"(TM). ## \& * Check FLAG before lsnrctl to ease the upgrade per Raj Pande. ## \& * "help=y" now uses "real man"(TM) page. Eliminated less helpful online help. ## \& * FLAG/FTIME update fix. ## \& - used POSIX PATH. ## \& - Use of POSIX "id -u" and "id -un" command. ## \& - Added "print" in additon to "$RANDOM" for ksh test to exclude bash. ## \& - Fixed "... | SUCCESS=Y". In PD KSH v5.2.14 99/07/13.2 (on Red Hat Linux ## \& 7.1, Kernel 2.4.4), the last pipeline is not run in current shell. ## \& - Changed "exit -1" to "exit 127" for PD KSH. ## \& - Workaround different behaviors on "Ctrl-C" on trap between PD KSH and ## \& AT&T KSH: PD KSH does not run exit trap upon "Ctrl-C", AT&T KSH does. ## \& - uses cp -p $ORATAB $ORATAB.tmp to create a temp file with same permission. ## \& - Eliminate fork (grep) in processing SID_LINE. ## .Ve ## .PP ## .Vb 12 ## \& version 5.4, 02/21/2001, Michael Wang (xw73@columbia.edu). ## \& * Tightened up the locking code. ## \& * Added restart option for convenience only per Raj Pande. It stop and start ## \& the listener with default options. ## \& * Added identifier "$LISTENER: " for flag change message. ## \& * exit 255 => exit -1 ## \& * Change [[ -z $ORATAB && -r $i ]] && ORATAB=$i to ## \& [[ -r $i ]] && { ORATAB=$i; break; } ## \& * Last line of start/stop options was: [[ $SHOW = Y ]] && exit -1. ## \& [[ $SHOW = Y ]] would be the last command if it is false and hence its ## \& status becomes the status of the script. The last line is changed to: ## \& (( status == 0 && fstatus == 0 )). ## .Ve ## .PP ## .Vb 4 ## \& version 5.3, 01/31/2001, Michael Wang (xw73@columbia.edu). ## \& * Added date before "tail -1". ## \& * Change [[ -z $Perl && -x $i ]] && Perl=$i to ## \& [[ -x $i ]] && { Perl=$i; break; } for efficiency. ## .Ve ## .PP ## .Vb 2 ## \& version 5.2, 01/26/2001, Michael Wang (xw73@columbia.edu). ## \& * Added ftime= option for start/stop. ## .Ve ## .PP ## .Vb 3 ## \& version 5.1, 01/05/2000, Michael Wang (xw73@columbia.edu). ## \& * change "exit 0" to "exit $?" in oracle-SID case. This affects backup. ## \& * change "FOREVER" to "1 DAY". ## .Ve ## .PP ## .Vb 2 ## \& version 5.0, 12/25/2000, Michael Wang (xw73@columbia.edu). ## \& To keep in sync with rc.oracle ## .Ve ## .PP ## .Vb 10 ## \& version 4.0, 10/10/2000, Michael Wang (xw73@columbia.edu). ## \& * version number advanced beyond pi. ## \& * Exit code changed from 0 to 4 when Oracle executable can not be found. ## \& * Array can not be reset on Version M-11/16/88f on AIX 4.3.3 ## \& i[0]=; typeset -u i; i=; unset i; i=b; echo $i => B ## \& Changed to i to ix to avoid conflict. ## \& * "==" in [[ string == pattern ]] is replaced by "=" for compatibility ## \& with older Korn Shell (eg Version M-11/16/88f). ## \& * Get rid of the_space_holder. ## \& * Unset name for name=value pair. Example, TEST=. ## .Ve ## .PP ## .Vb 7 ## \& version 3.14159, 08/18/2000, Michael Wang (xw73@columbia.edu). ## \& * Rewrite "[[ -z $(eval echo \e$$i) ]]" as "eval [[ -z \e$$i ]]". ## \& This reduces the number of forks. This was suggested by ## \& Dan A. Mercer on the internet. ## \& * Prerequisite: ## \& - /var/opt/oracle/listener.LISTENER_NAME: ## \& LISTENER_NAME:ORACLE_HOME:Y/N:TNS_ADMIN:OWNER ## .Ve ## .PP ## .Vb 11 ## \& version 3.1415, 07/22/2000, Michael Wang (xw73@columbia.edu). ## \& * Expanded listener's oratab to include owner in support of running as ## \& different $OWNER. ## \& * Enhanced SHOW=Y option to display statement to lsnrctl. ## \& * FLAG=NULL option for start/stop to leave FLAG alone. ## \& * unset LD_LIBRARY_PATH. ## \& Properly linked oracle executables do not need LD_LIBRARY_PATH. ## \& In Oracle 8i, set LD_LIBRARY_PATH causes listener problem, Ref: ## \& TAR 12953862.600, Doc ID 1023333.1, Bug ID 1147434. ## \& * MASSIVE code clean up to support above functionalities and for ## \& programming purity and efficiency. ## .Ve ## .PP ## .Vb 2 ## \& version 3.141, 07/09/2000, Michael Wang (xw73@columbia.edu). ## \& * Minor change on PATH and id for Linux compatibility. ## .Ve ## .PP ## .Vb 2 ## \& version 3.14, 03/17/2000, Michael Wang (xw73@columbia.edu). ## \& * implemented TNS_ADMIN. ## .Ve ## .PP ## .Vb 2 ## \& version 3.1, 01/20/2000, Michael Wang (xw73@columbia.edu). ## \& * Minor midifications in Oracle env variable determination and verification. ## .Ve ## .PP ## .Vb 2 ## \& version 3.0, 12/27/1999, Michael Wang (xw73@columbia.edu). ## \& * Modified in sync with oracle-SID ## .Ve ## .PP ## .Vb 2 ## \& version 1.0, 07/29/1998, Michael Wang (xw73@columbia.edu). ## \& * IPO. ## .Ve ## MAN_STOP