#!/bin/ksh # Copyright (c) 2007, 2014 Oracle and/or its affiliates. All rights reserved. # Use is subject to license terms. ############################################################################ # Satellite administration utility. ############################################################################ PATH=/usr/sbin:/usr/bin:/bin export PATH # Defaults #### Global ------------------------------------------------------------ BASE_DATA_DIR=/var/opt/sun/xvm DEFAULT_LOGFILE_LOCATION=${BASE_DATA_DIR}/logs # default ecadm cmd logfile, for those w/out default DEF_ECADM_OPT_TAG="sat-ecadm-`date +%F-%T`" DEF_ECADM_LOGFILE="$DEFAULT_LOGFILE_LOCATION/${DEF_ECADM_OPT_TAG}.log" #### Splash page/diagnostic file REASON_FILE=$BASE_DATA_DIR/logs/reason.log ECHA_DATA_DIR=$BASE_DATA_DIR/ha/ecmonitor #### EC Monitor startup grace period # The ecmonitor should not report failure due to startup until this period has expired. # The overall startup timeout is divided by the ecmonitor run interval. # This count is placed in a file and decremented by the ecmonitor. # The file is cleared anytime ecmonitor succeeds. ECHA_STARTUP_FILE=$ECHA_DATA_DIR/ECMonitor.startup HAEC_STARTUP_COUNT=20 # Default. Recalculated below. #### HA EC support HAEC_PROPERTIES_FILE=${BASE_DATA_DIR}/ha/EnterpriseController_HA_clusterware.properties HAEC_STATUS_FILE=${BASE_DATA_DIR}/ha/HAECStatus HAEC_STATUS_LOG=${BASE_DATA_DIR}/ha/HAECStatus.log HAEC_LOGFILE=${BASE_DATA_DIR}/ha/EnterpriseController.log DEF_HA_OPT_TAG="ha-ecadm-`date +%F-%T`" DEF_HA_LOGFILE="$DEFAULT_LOGFILE_LOCATION/${DEF_HA_OPT_TAG}.log" opt_wait=false opt_cluster=false opt_notify=false #### Remote database support WEBAPP_DIR=$BASE_DATA_DIR/bui/webapps/xvmoc DB_PROPS=$BASE_DATA_DIR/db.properties DBPW_PROPS=$BASE_DATA_DIR/dbpw.properties #### Set variables for SunOS and Linux case "`uname -s`" in SunOS) DEF_BACKUP_CONFIGDIR=/opt/SUNWxvmoc/lib/sat-backupcomps CACAOADM=/usr/sbin/cacaoadm JAVA_HOME=/usr/jdk/latest CACAO_LIB=/usr/lib/cacao/lib CACAO_ENDORSED_DIR=$CACAO_LIB/endorsed JDMK_LIB=/opt/SUNWjdmk/5.1/lib SATMGMT_LIB=/opt/SUNWscnsatmgmt/lib N1GC_LIB=/opt/sun/n1gc/lib HAEC_DIR=/opt/ORCLsysman-haec HAEC_CW_DIR=/opt/ORCLsysman-haec-cw DEF_DB_CONF_PROPS=$DB_PROPS DEF_RUNTIMEMGMT_PKGNAME=SUNWxvm-satrun-base if DEF_RUNTIMEMGMT_BASEDIR=`pkgparam "$DEF_RUNTIMEMGMT_PKGNAME" BASEDIR`; then if [ "`/usr/bin/uname -r`" = "5.10" ]; then DEF_RUNTIMEMGMT_BASEDIR="${DEF_RUNTIMEMGMT_BASEDIR}/SUNWxvmoc" # XXX SunOS only else # pkgparam doesn't return the correct value on S11 because # this package is just a stub DEF_RUNTIMEMGMT_BASEDIR="/opt/SUNWxvmoc" fi else DEF_RUNTIMEMGMT_BASEDIR=/opt/SUNWxvmoc # Fall back default fi DEF_RUNTIMEMGMT_SMF_MANIFEST_DIR=$DEF_RUNTIMEMGMT_BASEDIR/lib/svc SVCADM=/usr/sbin/svcadm SVCCFG=/usr/sbin/svccfg UCE_PROXY_CONF=/var/opt/sun/xvm/uce/etc.opt/server/uce_server/proxy.conf ;; Linux) DEF_BACKUP_CONFIGDIR=/opt/sun/xvmoc/lib/sat-backupcomps CACAOADM=/opt/sun/cacao2/bin/cacaoadm JAVA_HOME=/usr/java/latest CACAO_LIB=/opt/sun/cacao2/share/lib CACAO_ENDORSED_DIR=$CACAO_LIB/endorsed CACAO_LINUX_PSEUDO_FMRI="common-agent-container" JDMK_LIB=/opt/sun/jdmk/5.1/lib SATMGMT_LIB=/opt/sun/sun-scn-satmgmt/lib N1GC_LIB=/opt/sun/n1gc/lib HAEC_DIR=/opt/orcl/orcl-sysman-haec HAEC_CW_DIR=/opt/orcl/orcl-sysman-haec-cw DEF_DB_CONF_PROPS=$DB_PROPS DEF_RUNTIMEMGMT_PKGNAME='' #not used DEF_RUNTIMEMGMT_BASEDIR=/opt/sun/xvmoc DEF_RUNTIMEMGMT_SMF_MANIFEST_DIR=$DEF_RUNTIMEMGMT_BASEDIR/lib/svc SVCADM=/opt/sun/xvmoc/bin/svcadm ECHA_LOCKFILE=/var/opt/sun/xvm/ha/.echalock UCE_PROXY_CONF=/var/opt/sun/xvm/uce/etc/uce_server/proxy.conf ;; *) echo "Unknown OS environment ("`uname -s`"); exiting" 1>&2 exit 100 ;; esac #### Backup ------------------------------------------------------------ DEF_BACKUP_OPT_TAG="sat-backup-`date +%F-%T`" DEF_BACKUP_OPT_OUTPUT="/var/tmp/${DEF_BACKUP_OPT_TAG}.tar" DEF_BACKUP_LOGFILE="$DEFAULT_LOGFILE_LOCATION/${DEF_BACKUP_OPT_TAG}.log" DEF_BACKUP_OPT_DESCRIPTION="Enterprise Controller backup of host \"`hostname`\"" DEF_BACKUP_OPT_TMPDIR="/var/tmp/satadm-temp-$$" #### Restore ------------------------------------------------------------ DEF_RESTORE_OPT_TAG="sat-restore-`date +%F-%T`" DEF_RESTORE_LOGFILE="$DEFAULT_LOGFILE_LOCATION/${DEF_RESTORE_OPT_TAG}.log" ### Migrate DEF_MIGRATE_OPT_TAG="sat-migrate-`date +%F-%T`" DEF_MIGRATE_LOGFILE="$DEFAULT_LOGFILE_LOCATION/${DEF_MIGRATE_OPT_TAG}.log" #### Return states of backup/restore component scripts ERR_CONTINUE=1 # continue executing backup phases for this comp ERR_NOMORE=3 # do not execute next backup phases for this comp ERR_ABORTNOW=5 # catastrophic error; abort entire backup now #### Satellite start/stop ---------------------------------------------- DEF_DB_CONF_SERVERTYPE_KEY=mgmtdb.server.type DEF_SATELLITE_SVC_DB_MANIFEST=${DEF_RUNTIMEMGMT_SMF_MANIFEST_DIR}/satellite-base-svc.xml DEF_SATELLITE_SVC_DB_FMRI="svc:/application/scn/db:default" DB_SMF_SERVICES="" ### XXX TODO PR SMFlite property handling broken, these must be ### XXX TODO PR hard-coded here for now DB_SMF_SUBSERVICES_local="\ svc:/application/scn/oracle:default \ svc:/application/scn/oralistener:default" DB_SMF_SUBSERVICES_remote="" # The security review for Ops Center requested that all jars which access hosted services # via an internet connection be signed in order to verify their integrity. # The jars will only be signed for production builds so satadm should only do # the signature check if it was built in production mode. do_security_check_on_jars() { if $DEBUG; then set -x; fi VERSION_FILE="/n1gc-setup/.version.properties" # Note: In fresh EC installation scenario, $VERSION_FILE may not exist yet # at the time the satadm is executed. In such case, $BUILD_TYPE, which # is extracted from the installation dvd, should have been defined to # tell the build.type value. if [ ! -r $VERSION_FILE ]; then if [ -z "$JAR_SIGN" ]; then # Neither .version.properties exists nor $BUILD_TYPE is set; abort. log ERROR "Unable to determine if jars need signing or not, exiting." exit 100 fi else # Get the build.type from $VERSION_FILE. JAR_SIGN=`/bin/grep '^jar.sign=' $VERSION_FILE 2>/dev/null | sed 's/^jar.sign=//g'` fi # Only proceed if running a production build. if [[ "$JAR_SIGN" = "" || "$JAR_SIGN" = "false" ]]; then # We only do security check for production build. log INFO "This is a developer or team-produced production build, skip jar file security check." return 0; fi log INFO "Checking jar files signature ..." JARFILE_LIST="/usr/share/lib/scn/scn-connmgt.jar /opt/sun/n1gc/lib/mos-impl.jar" JARSIGNER_CMD="$JAVA_HOME/bin/jarsigner" if [ ! -x $JARSIGNER_CMD ]; then JARSIGNER_CMD="/usr/bin/jarsigner" if [ ! -x $JARSIGNER_CMD ]; then # Could not locate jarsigner in $JAVA_HOME/bin or/usr/bin; # Next try search under /usr/jdk or /usr/java. JARSIGNER_LIST="" case "`uname -s`" in SunOS) JARSIGNER_LIST=`find /usr/jdk -name "jarsigner" 2>/dev/null` ;; Linux) JARSIGNER_LIST=`find /usr/java -name "jarsigner" 2>/dev/null` ;; esac while [ "$JARSIGNER_LIST" ]; do pop CURJARSIGNERFILE JARSIGNER_LIST OIFS=$IFS; IFS=':'; set -- $CURJARSIGNERFILE; IFS=$OIFS CURJARSIGNERFILE=$1 CURCONTINUE=$2 CURPRESUCCESS=$3 if [ -x $CURJARSIGNERFILE ]; then JARSIGNER_CMD=$CURJARSIGNERFILE break; fi done if [ ! -x $JARSIGNER_CMD ]; then log ERROR "Could not locate jarsigner in $JAVA_HOME/bin, /usr/bin or anywhere under /usr/jdk (or /usr/java for Linux), exiting." exit 100; fi fi fi log INFO "Verifying jar signature with $JARSIGNER_CMD" while [ "$JARFILE_LIST" ]; do pop CURJARFILE JARFILE_LIST OIFS=$IFS; IFS=':'; set -- $CURJARFILE; IFS=$OIFS CURJARFILE=$1 CURCONTINUE=$2 CURPRESUCCESS=$3 JAR_CHK_RESULT=`$JARSIGNER_CMD -verify $CURJARFILE 2>/dev/null` IS_VERIFIED=`echo $JAR_CHK_RESULT | grep "jar verified" | wc -l` if [ $IS_VERIFIED = 0 ]; then # This jar is unsigned; abort. log ERROR "$CURJARFILE: $JAR_CHK_RESULT" log ERROR "This jar is required to be signed and verified, exiting." exit 100; else log INFO "$CURJARFILE is verified." fi done log INFO "All required jar file signatures have been verified"; } sync_db_service_config() { if $DEBUG; then set -x; fi DB_CONF_SERVERTYPE=`loadprop ${DEF_DB_CONF_PROPS} ${DEF_DB_CONF_SERVERTYPE_KEY} unknown` get_cacaoCurrentFMRI CACAO_SATELLITE_FMRI oem-ec get_oracleUserAndGroup case "`uname -s`" in SunOS) if not smf_present; then log ERROR "SMF appears to not be running on this SunOS system, fatal inconsistency. Exiting in sync_db_service_config()" exit 100 fi if DB_SMF_SERVERTYPE_FMRI=`svcprop -p db-server-type/entities "${DEF_SATELLITE_SVC_DB_FMRI}"`; then if DB_SMF_SERVERTYPE=`expr "${DB_SMF_SERVERTYPE_FMRI}" : "svc:/[^:]*:\(.*\)"`; then if [ "${DB_CONF_SERVERTYPE}" = "${DB_SMF_SERVERTYPE}" ]; then : # Current config matches, do nothing else # Got all config data successfully, need to switch ######################################################################## # FIXME SMF doesn't propogate updated properties immediately # when new manifests are loaded. # The following gymnastics are intended to work around this. # First, disable the base DB service so property updates from new manifest are visible if svcadm disable ${DEF_SATELLITE_SVC_DB_FMRI}; then : # Do nothing else log WARN "Unable to disable old DB service (${DB_SMF_SERVERTYPE_FMRI})" fi # Next, disable the old DB servertype and the services it claims as dependencies if svcadm disable ${DB_SMF_SERVERTYPE_FMRI}; then : # Do nothing else log WARN "Unable to disable old DB service (${DB_SMF_SERVERTYPE_FMRI})" fi ######################################################################### if DB_SMF_SUBSERVICES=`svcprop -p db-subsvc/services "${DB_SMF_SERVERTYPE_FMRI}"`; then DB_SMF_SUBSERVICES=`echo ${DB_SMF_SUBSERVICES}|sed -e 's/\\\\ / /g' -e 's/""//'` # Eliminate quoted spaces else log WARN "Unable to obtain subservice dependency list from DB service (${DB_SMF_SERVERTYPE_FMRI})" fi for svc in ${DB_SMF_SUBSERVICES}; do if svcadm disable ${svc}; then : # Do nothing else log WARN "Unable to disable DB subservice ($svc) during reconfigure" fi done # Now create a new service manifest from the template with current configuration genfile_from_template ${DEF_SATELLITE_SVC_DB_MANIFEST} "${DEF_SATELLITE_SVC_DB_MANIFEST}-tmpl" \ "CACAO_SMF_FMRI=$CACAO_SATELLITE_FMRI" \ "PKGHOME=$DEF_RUNTIMEMGMT_BASEDIR" \ "DB_CURRENT_INSTANCE=$DB_CONF_SERVERTYPE" \ "OC_DB_USER=$OC_DB_USER" \ "OC_DB_GROUP=$OC_DB_GROUP" # ... and import it into SMF if [ "${VERBOSE}" = "true" ]; then VERBOSE_FLAG="-v"; else VERBOSE_FLAG=""; fi if svccfg ${VERBOSE_FLAG} import ${DEF_SATELLITE_SVC_DB_MANIFEST}; then : # Do nothing else log ERROR "Unable to import updated database SMF manifest (${DEF_SATELLITE_SVC_DB_MANIFEST})" fi ######################################################################## # FIXME SMF doesn't propogate updated properties immediately # when new manifests are loaded. # The following gymnastics are intended to work around this. # Argh. The import currently doesn't cause the properties to be updated # according to the updated manifest. First refresh all the services defined # in the updated manifest. if UPDATED_FMRIS=`svccfg ${VERBOSE_FLAG} inventory ${DEF_SATELLITE_SVC_DB_MANIFEST} | grep 'svc:/.*:'`; then if svcadm refresh ${UPDATED_FMRIS}; then : # Do nothing else log ERROR "Unable to refresh SMF service (${UPDATED_FMRIS})" fi else log ERROR "Cannot inventory updated database SMF manifest (${DEF_SATELLITE_SVC_DB_MANIFEST})" fi # The refresh turns out to be inadequate. We need to poll the property in SMF # and wait for it to update. Has been taking 1-2 seconds. Grrr. timeout=30 # iterations, * sleeptime sleeptime=1 # seconds while [ "${timeout}" -gt 0 ]; do if tmp_FMRI=`svcprop -p db-server-type/entities "${DEF_SATELLITE_SVC_DB_FMRI}"` && tmp_SERVERTYPE=`expr "${tmp_FMRI}" : "svc:/[^:]*:\(.*\)"` && [ "${DB_CONF_SERVERTYPE}" = "${tmp_SERVERTYPE}" ]; then break fi log INFO "Waiting for SMF property update: `date`"; sleep 1 timeout=`expr ${timeout} - 1` done if [ "${timeout}" -le 0 ]; then log ERROR "Timed out waiting for SMF property update during database type switch" fi ######################################################################## fi return 0 else # Beginning of error conditions: we default to not changing anything DB_SMF_SERVICES="" # Couldn't parse SMF SERVERTYPE FMRI (dependency) log WARN "Unable to parse 'db-server-type' database dependency FMRI (${DB_CUR_SERVERTYPE_FMRI}), did not resync database service to configuration" fi else # Unable to get 'db-server-type' dependency list from db:default service instance log WARN "Unable to obtain 'db-server-type' database dependency from DB service (${DEF_SATELLITE_SVC_DB_FMRI}), did not resync database service to configuration" fi return 1 ;; Linux) # For Linux, we always re-create a current manifest from the template for SMFlite to munch on # Because SMFlite cannot retrieve the dependencies as properties, they are initialized in satadm # as default values of variables. genfile_from_template ${DEF_SATELLITE_SVC_DB_MANIFEST} "${DEF_SATELLITE_SVC_DB_MANIFEST}-tmpl" \ "CACAO_SMF_FMRI=$CACAO_SATELLITE_FMRI" \ "PKGHOME=$DEF_RUNTIMEMGMT_BASEDIR" \ "DB_CURRENT_INSTANCE=$DB_CONF_SERVERTYPE" \ "OC_DB_USER=$OC_DB_USER" \ "OC_DB_GROUP=$OC_DB_GROUP" # SMFlite does not require importing, it just references the manifests` ;; esac } load_startstop() { if $DEBUG; then set -x; fi DEF_STARTSTOP_OPT_TEMPORARY= # set timeouts to 4 hours DEF_STARTSTOP_SHUTDOWN_TIMEOUT=14400 DEF_STARTSTOP_STARTUP_TIMEOUT=14400 DEF_STARTSTOP_SATELLITE_SVC_ENABLE="svc:/application/scn/satellite-enable:default" DEF_STARTSTOP_SATELLITE_SVC_AVAILABLE="svc:/application/scn/satellite-available:default" # May have been set by db_setup_service_config above, but needed where # load_startstop not invoked after db_setup_service_config DB_CONF_SERVERTYPE=`loadprop ${DEF_DB_CONF_PROPS} ${DEF_DB_CONF_SERVERTYPE_KEY} unknown` case "`uname -s`" in SunOS) # Add the dynamic FMRIs to the startstop list if DB_SMF_SERVICES=`svcprop -p db-server-type/entities "${DEF_SATELLITE_SVC_DB_FMRI}"`; then if DB_SMF_SUBSERVICES=`svcprop -p db-subsvc/services "${DB_SMF_SERVICES}"`; then DB_SMF_SUBSERVICES=`echo ${DB_SMF_SUBSERVICES}|sed -e 's/\\\\ / /g' -e 's/""//'` # Eliminate quoted spaces DB_SMF_SERVICES="${DB_SMF_SERVICES} ${DB_SMF_SUBSERVICES}" fi else log WARN "Unable to retrieve updated database instance dependency from (${DEF_SATELLITE_SVC_DB_FMRI})" fi DEF_STARTSTOP_SATELLITE_SVC_LIST=`svcs -d -H -o FMRI $DEF_STARTSTOP_SATELLITE_SVC_AVAILABLE` DEF_STARTSTOP_SATELLITE_SVC_LIST="$DEF_STARTSTOP_SATELLITE_SVC_LIST $DB_SMF_SERVICES" ;; Linux) # Linux (smflite) doesn't have "svcs -d -H -o FMRI" capability yet DEF_STARTSTOP_SATELLITE_SVC_LIST=" svc:/application/management/common-agent-container:oem-ec svc:/application/scn/db:default svc:/application/scn/uce-server:default svc:/application/scn/uce-scheduler:default " #svc:/application/scn/console:default # Generate the appropriate DB FMRI (local, remote, etc) from the default # DB FMRI instance, then pull via SMFlite the property that shows the # dependent subservices that must be enabled DB_SMF_SERVICES="" if DB_SMF_SERVICES=`expr "${DEF_SATELLITE_SVC_DB_FMRI}" : "\(.*:\)[^:]*"`; then DB_SMF_SERVICES="${DB_SMF_SERVICES}${DB_CONF_SERVERTYPE}" # XXX TODO PR Need SMFlite property handling fix # if DB_SMF_SUBSERVICES=`svcprop -p db-subsvc/services "${DB_SMF_SERVICES}"`; then # DB_SMF_SUBSERVICES=`echo ${DB_SMF_SUBSERVICES}|sed -e 's/\\\\ / /g'` # Eliminate quoted spaces # DB_SMF_SERVICES="${DB_SMF_SERVICES} ${DB_SMF_SUBSERVICES}" # fi eval "DB_SMF_SUBSERVICES=\${DB_SMF_SUBSERVICES_${DB_CONF_SERVERTYPE}}" DB_SMF_SERVICES="${DB_SMF_SERVICES} ${DB_SMF_SUBSERVICES}" fi DEF_STARTSTOP_SATELLITE_SVC_LIST="$DEF_STARTSTOP_SATELLITE_SVC_LIST $DB_SMF_SERVICES" DEF_STARTSTOP_SATELLITE_SVC_LIST=`registeredFMRIs $DEF_STARTSTOP_SATELLITE_SVC_LIST` ;; *) echo "Unknown OS environment ("`uname -s`"); exiting" 1>&2 exit 100 ;; esac } ############################################################################# # Internal variables VERSION=1 # actual name used to invoke script, maybe 'satadm' or 'ecadm' MYNAME=`basename $0` VERBOSE=false ECHO_ON_ERROR=false unset LOGFILE unset TRACEFILE # Is the real, honest-to-goodness, SMF present? SMFlite doesn't count. if [ -e /lib/svc/share/smf_include.sh ]; then . /lib/svc/share/smf_include.sh else smf_present() { false; } # Put SMFlite into the path. PATH=/opt/sun/xvmoc/bin:$PATH; export PATH fi ############################################################################# # Cross-platform option processing # # Usage: # load_getopt # Load the cross-platform option processing mechanism. # # GETOPT_LINUX="" # Set this to a GNU-style list of options. # e.g.: # GETOPT_LINUX="-o vql: -l verbose,quiet,log:" # # GETOPT_SUNOS="" # Set this to a SunOS-style list of options. # e.g.: # GETOPT_SUNOS="v(verbose)q(quiet)l:(log)" # # GETOPT_MYNAME="" # Set this to the name of the calling program, for use # in error messages. # e.g.: # GETOPT_MYNAME=`basename $0` # # eval "$GETOPT_INIT" # Does initial getopt processing on the current argument list. # Invalid options a failure return code, with a message in # $GETOPT_ERR. # e.g.: # if eval "$GETOPT_INIT"; then # : # else # echo "$GETOPT_ERR" # usage # exit 10027 # fi # # eval "$GETOPT" # Extracts a single option. # The option is returned in $GETOPT_OPT. # An invalid option may cause GETOPT_OPT to be returned as "?", # with a message in $GETOPT_ERR. # GETOPT_OPT may be returned as a single option letter "v", # a dash and option letter "v", or as a long option "--verbose". # Returns failure when the end of the options is reached. # e.g.: # while eval "$GETOPT"; do # case "$GETOPT_OPT" in # v|-v|--verbose) # ... # ;; # \?) # echo "$GETOPT_ERR" # usage # exit 10027 # ;; # esac # done # # eval "$GETOPT_GETOPTARG" # Retrieves the current option's option-argument into $GETOPT_OPTARG. # Must be invoked if the current option accepts an option-argument, # and must not be invoked if it does not. # e.g.: # eval "$GETOPT_GETOPTARG" # echo arg="\"$GETOPT_OPTARG\"" # # eval "$GETOPT_FINI" # Leaves the non-option arguments in the argument list for # conventional processing. # e.g.: # eval "$GETOPT_FINI" # echo "Args: $*" # load_getopt() { case `uname -s` in SunOS) GETOPT_INIT=' OPTIND=1 GETOPT_OPTSTR=$GETOPT_SUNOS true ' GETOPT=' if getopts ":$GETOPT_OPTSTR" GETOPT_OPT; then case "$GETOPT_OPT" in \?) GETOPT_ERR="$GETOPT_MYNAME: illegal option -- $OPTARG" ;; :) GETOPT_ERR="$GETOPT_MYNAME: option requires an argument -- $OPTARG" GETOPT_OPT="?" ;; esac true else false fi ' GETOPT_GETOPTARG='GETOPT_OPTARG=$OPTARG' GETOPT_FINI=' shift `expr $OPTIND - 1` ' ;; Linux) GETOPT_TMP=/var/run/getopt.err.$$ GETOPT_INIT=' GETOPT_ARGS=` POSIXLY_CORRECT=true \ getopt $GETOPT_LINUX --name "$GETOPT_MYNAME" -s sh -- "$@" \ 2>$GETOPT_TMP` if [ $? -eq 0 ]; then eval set -- "$GETOPT_ARGS" rm -f $GETOPT_TMP true else read GETOPT_ERR < $GETOPT_TMP rm -f $GETOPT_TMP false fi ' GETOPT=' GETOPT_OPT=$1 shift [ x"$GETOPT_OPT" != x-- ] ' GETOPT_GETOPTARG=' GETOPT_OPTARG=$1 shift ' GETOPT_FINI= ;; esac } ############################################################################# loadprop() { # if ${DEBUG}; then set +x; fi _cf="$1" _key="$2" _default="$3" if _out=`sed -n -e ' /^[ ]*'"${_key}"'[ ]*[:=]/{ s/^[ ]*'"${_key}"'[ ]*[:=]// p d }' "${_cf}"` && [ "${_out}" ]; then echo ${_out} else echo ${_default} fi } genfile_from_template() { # [KEY=value ...] if ${DEBUG}; then set -x; fi _out="$1" _template="$2" shift 2 (umask 027; touch $_out) _sedscript='' for _subparam in "$@"; do _sedscript="${_sedscript};`echo ${_subparam} | sed -e \"s/\([^=:]*\)[=:]\(.*\)/s|##\1##|\2|g/\"`" done if [ -r "${_template}" ]; then if sed -e "${_sedscript}" < ${_template} > "${_out}-temp"; then mv "${_out}-temp" "${_out}" else log ERROR "genfile_from_template: could not create or edit '$_out' from '$_template'" return 1 fi else log ERROR "genfile_from_template: could not read template file '$_template'" return 1 fi } ######################################################################################### ######################################################################################### # The following routines (up to and including findMaxJvmPath) are copied from the # installer and shovel code and replicated here. The purpose of these routines is # to find the correct Java for Ops Center to use. # # getRel ( filename ) # # A little utility routine to strip viable prefixes from release names. # Note that this only works for release names by Sun convention, not the # whole, generalized JSR 56 name set. # # The current and legacy prefixes are: # jdk (default for these packages) # jre # j2re # j2sdk # # Parameters: # $1 filename Filesystem filename # # Returns: # Version portion of the file name. # getRel() { if [ "`echo $1 | cut -c 1-3`" = "jdk" ]; then echo $1 | cut -c 4- elif [ "`echo $1 | cut -c 1-3`" = "jre" ]; then echo $1 | cut -c 4- elif [ "`echo $1 | cut -c 1-4`" = "j2re" ]; then echo $1 | cut -c 5- elif [ "`echo $1 | cut -c 1-5`" = "j2sdk" ]; then echo $1 | cut -c 6- else echo $1 fi } # # expandPrefix ( release ) # # This shell routine expands JVM release identifier prefixes to the # full, four element tuple. expandPrefix zero extends as per JSR 56. # # Parameters: # $1 release Partial or complete release name tuple. # expandPrefix() { echo $1 | sed -e "s/_/\./g" | \ awk 'BEGIN {FS="."}{printf "%.2d.%.2d.%.2d_%.2d\n", $1, $2, $3, $4}' } # # relCmp ( rel1 rel2 ) # # Styled as much as possible after strcmp, this routine returns one of the # strings "lt", "eq", or "gt" based on the relationship of the two release # version identifier strings passed as parameters. The sort is done only # on the first four fields (Major, Minor, Micro, Patch). Internal identifiers # beyond that are ignored and releases differing only in the internal # identifier will compare as equal. # # Parameters: # $1 rel1 Release identifier # $2 rel2 Release identifier # # Returns: # "lt", "eq", or "gt" based on the relationship of the two releases # relCmp() { r1=`echo $1 | sed -e "s/-.*//" -e "s/_/\./g"` r2=`echo $2 | sed -e "s/-.*//" -e "s/_/\./g"` if [ "$r1" = "$r2" ]; then echo "eq" else lrel=`printf "%s\n%s\n" ${r1} ${r2} | \ sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n | \ head -1` if [ "$r1" = "$lrel" ]; then echo "lt" else echo "gt" fi fi } # # findMaxJvmPath # Returns the path of the greatest version of java runtime installed on the system. # arguments: none # output : echo path of the greatest version of java runtime installed on the system. # findMaxJvmPath() { TARGET_OS=`uname -s` java_base="" if [ "$TARGET_OS" = "Linux" ]; then java_base="/usr/java" elif [ "$TARGET_OS" = "SunOS" ]; then java_base="/usr/jdk" fi max_jvm_version="" max_jvm_path="" for prefix in jdk jre j2sdk j2re "i386/jdk" "instances/jdk"; do for d in $java_base/$prefix*; do if [ ! -d "$d" ]; then continue fi r=`getRel \`basename "$d"\`` r=`expandPrefix "$r"` if [ "`relCmp $r $max_jvm_version`" = "gt" ]; then max_jvm_version="$r" max_jvm_path="$d" fi done done echo "$max_jvm_path" } ######################################################################################### ######################################################################################### set_satmgr_classpath() { CLASSPATH=$JDMK_LIB/jdmkrt.jar:$CACAO_LIB/cacao_admin.jar:$CACAO_LIB/cacao_cacao.jar:$CACAO_LIB/cacao_rmi.jar:$CACAO_LIB/cacao_rbac.jar:$SATMGMT_LIB/satmgmt-common.jar:$SATMGMT_LIB/scn-common.jar:$SATMGMT_LIB/scn-vo.jar:$N1GC_LIB/commonservices.jar:$N1GC_LIB/channel_client.jar:$N1GC_LIB/csdata.jar } set_bui_classpath() { CLASSPATH=$WEBAPP_DIR:$WEBAPP_DIR/WEB-INF:$WEBAPP_DIR/WEB-INF/classes for i in `find $WEBAPP_DIR/WEB-INF/lib -name '*.jar'`; do CLASSPATH=$CLASSPATH:$i done } # set classpath for HA commands set_haec_classpath() { case "`uname -s`" in SunOS) CLASSPATH=$HAEC_CW_DIR/ha/integ/cw/haec.jar:/opt/sun/n1gc/lib/domain.jar:/opt/sun/n1gc/lib/jsch-xvm.jar:/usr/lib/cacao/lib/cacao_cached_connector.jar:/usr/lib/cacao/lib/cacao_cacao.jar ;; Linux) CLASSPATH=$HAEC_CW_DIR/ha/integ/cw/haec.jar:/opt/sun/n1gc/lib/domain.jar:/opt/sun/n1gc/lib/jsch-xvm.jar:/opt/sun/cacao2/share/lib/cacao_cached_connector.jar:/opt/sun/cacao2/share/lib/cacao_cacao.jar ;; *) echo "Unknown OS environment ("`uname -s`"); exiting" 1>&2 exit 100 ;; esac } get_oracleUserAndGroup() { case "`uname -s`" in SunOS) DB_ROOT_DIR=/opt/ORCLsysman-db ;; Linux) DB_ROOT_DIR=/opt/orcl/orcl-sysman-db ;; *) echo "Unknown OS environment ("`uname -s`"); exiting" 1>&2 exit 100 ;; esac # Collect properties from Oracle db definition file LOCALORACLEPROPS=$DB_ROOT_DIR/etc/localOracleConfig.properties if [ -r $LOCALORACLEPROPS ]; then OC_DB_USER=`grep embedded_oracle_user $LOCALORACLEPROPS | awk -F= '{print $2}' | sed 's/\"//g'` OC_DB_GROUP=`grep embedded_oinstall_group $LOCALORACLEPROPS | awk -F= '{print $2}' | sed 's/\"//g'` ###################################################################### # CR7141805: migration requires target db privs/tablespaces # to match the source tablespaces ###################################################################### embedded_data_ts=`grep embedded_data_ts $LOCALORACLEPROPS | awk -F= '{print $2}' | sed 's/\"//g'` embedded_index_ts=`grep embedded_index_ts $LOCALORACLEPROPS | awk -F= '{print $2}' | sed 's/\"//g'` embedded_default_ts=`grep embedded_default_ts $LOCALORACLEPROPS | awk -F= '{print $2}' | sed 's/\"//g'` embedded_report_ts=`grep embedded_report_ts $LOCALORACLEPROPS | awk -F= '{print $2}' | sed 's/\"//g'` remote_data_ts=`grep remote_data_ts $LOCALORACLEPROPS | awk -F= '{print $2}' | sed 's/\"//g'` remote_index_ts=`grep remote_index_ts $LOCALORACLEPROPS | awk -F= '{print $2}' | sed 's/\"//g'` remote_default_ts=`grep remote_default_ts $LOCALORACLEPROPS | awk -F= '{print $2}' | sed 's/\"//g'` remote_report_ts=`grep remote_report_ts $LOCALORACLEPROPS | awk -F= '{print $2}' | sed 's/\"//g'` fi if [ X$OC_DB_USER == X ]; then OC_DB_USER=oracleoc fi if [ X$OC_DB_GROUP == X ]; then OC_DB_GROUP=oinstoc fi } get_cacaoCurrentFMRI() { # if ${DEBUG}; then set -x; fi case `uname -s` in SunOS) if _f=`$CACAOADM show smf-fmri -i $2`; then eval "$1=\"${_f}\"" else log ERROR "$CACAOADM show smf-fmri -i $2: failed to get FMRI ($?)" return 1 fi ;; Linux) eval "$1=\"${CACAO_LINUX_PSEUDO_FMRI}:$2\"" ;; *) echo "Unknown OS environment ("`uname -s`"); exiting" 1>&2 exit 100 ;; esac } registeredFMRIs() { while [ "$#" -gt 0 -a -n "$1" ]; do if svcprop -p restarter/state "$1" > /dev/null 2>&1; then echo "$1" fi shift done } # !!!!!!!!!!!!!! CR 6857873 workaround cacaoSMFdependencies_areInvalid() { if $DEBUG; then set -x; fi if smf_present; then invalid=false for fmri in `svcs -o FMRI -H -D "$DEF_STARTSTOP_SATELLITE_SVC_ENABLE"`; do case "$fmri" in *common-agent-container*) if not svcprop -q -p satellite-enable-cacao "$fmri" > /dev/null; then log WARN "Enterprise Controller SMF dependency for Cacao is invalid ($fmri dep=satellite-enable-cacao)" invalid=true fi if restarterstate=`svcprop -p restarter/state "$fmri" 2>/dev/null`; then case "$restarterstate" in -) log WARN "Enterprise Controller SMF dependency for Cacao is invalid ($fmri restarter/state=$restarterstate)" invalid=true ;; esac else log WARN "Enterprise Controller SMF dependency for Cacao is invalid ($fmri read(restarter/state)=$?)" invalid=true fi if [[ "`basename $fmri`" != "`$CACAOADM show smf-fmri -i oem-ec`" ]]; then log WARN "Enterprise Controller SMF dependency for Cacao is invalid ($fmri not current cacao fmri)" invalid=true fi ;; esac done if $invalid; then return 0 fi fi return 1 } cacaoSMFdependencies_doRestore() { if $DEBUG; then set -x; fi if smf_present; then # This gets a little tricky given some SMF ideosyncracies. # # To reestablish the forward and backward dependencies for a cacao service # we will have to # 1) Identify services that have dependencies against the prior # cacao service as named by the dependency FMRI # 2) Delete the instance and base definitions for those services, which will # allow the skeletal cacao service definition (holding the # relationship intact) to be released # 3) Identify the SMF service manifest that defined the services we had to # delete # 4) Re-edit those manifests from their template form substituting in the # "real" cacao service FMRI in places where the dependencies are specified # 5) Re-import those manifests with svccfg # After all that, we can successfully perform the service administrative task # we were attempting in the first place. # First, give fair warning about what we're about to attempt, and disable # all constituent services. (If we remove the -enable milestone, the member # services will be free to go online if they're not disabled. Not what we # want to happen while we're fixing things) log NOTICE "Reloading Enterprise Controller SMF manifest(s)" for fmri in $DEF_STARTSTOP_SATELLITE_SVC_LIST; do if not svcadm disable "$fmri"; then log WARN "svcadm disable: error while temporarily disabling ($fmri) for SMF manifest reload, continuing..." fi done # Get a list of the manifest files to search if manifestFiles=`ls -1 $DEF_RUNTIMEMGMT_SMF_MANIFEST_DIR/*.xml`; then : else log ERROR "Could not get listing of SMF manifests for $DEF_RUNTIMEMGMT_PKGNAME" fi # Make a list of manifest file names that define a service that has a # relationship to cacao. Each of those services will be undefined, and the manifest # file will need to be identified to re-import it. manifestFileList='' for fmri in $DEF_STARTSTOP_SATELLITE_SVC_LIST $DEF_STARTSTOP_SATELLITE_SVC_ENABLE ; do if `svcprop "$fmri" | egrep '^(dependents/satellite|[^/]*/entities).*common-agent-container' > /dev/null`; then for manifest in $manifestFiles; do if expr "`svccfg inventory $manifest`" : ".*$fmri" > /dev/null; then if not expr "$manifestFileList" : ".*$manifest" > /dev/null; then append "$manifest" manifestFileList fi fi done if not svccfg delete "$fmri"; then log WARN "svccfg delete $fmri: failed to delete service instance, continuing..." fi if not svccfg delete `expr $fmri : '\(.*\):.*'`; then log WARN "svccfg delete $fmri: failed to delete base service, continuing..." fi fi done # Do a bit of cacao preparatory work. If cacao was re-installed, it may not have had # any administrative operations performed yet, and thus it may not have been linked into # SMF. The first cacaoadm operation will establish that linkage if it doesn't exist. # Once we're pretty sure cacao has an SMF definition, get the FMRI associated with it. $CACAOADM status > /dev/null # Prophylactic to make sure cacao (re)links into SMF get_cacaoCurrentFMRI cacaoCurrentFMRI oem-ec get_oracleUserAndGroup # At this point, we should have these conditions hold true: # - Any of our services that had relations to a prior cacao service # have been undefined # - As a consequence, the skeleton service definition for the prior cacao service # should no longer exist # - Cacaoadm has defined an SMF service for the current installation of cacao, # and we have identified it in $cacaoCurrentFMRI # - A list of manifest files that have a definition of at least one of the affected # services is contained in $manifestFileList # Now, just re-edit the manifest files from their templates, substituting the cacao FMRI # (and BASEDIR) as needed. Then import them. # (NOTE: We cannot just import an updated service definition on top of an existing # service definition with a lingering relation. The 'svccfg' command # encounters a fatal error when attempting that, and core dumps.) # We need the database type (instance) for editing the templates DB_CONF_SERVERTYPE=`loadprop ${DEF_DB_CONF_PROPS} ${DEF_DB_CONF_SERVERTYPE_KEY} unknown` for manifest in $manifestFileList; do manifestTmpl="${manifest}-tmpl" if genfile_from_template "$manifest" "$manifestTmpl" \ "CACAO_SMF_FMRI=$cacaoCurrentFMRI" \ "PKGHOME=$DEF_RUNTIMEMGMT_BASEDIR" \ "DB_CURRENT_INSTANCE=$DB_CONF_SERVERTYPE" \ "OC_DB_USER=$OC_DB_USER" \ "OC_DB_GROUP=$OC_DB_GROUP" ; then : else log ERROR "Editing template SMF manifest ($manifest) failed (rc=$?)" continue fi if [ -r "$manifest" ]; then if svccfg import "$manifest"; then : else log ERROR "Import of Enterprise Controller SMF manifest $manifest failed ($?)" fi else log ERROR "Could not read Enterprise Controller SMF manifest $manifest" fi done # Normally *adm won't enable the cacao container explicitly. We need to # do this here as a final step if not svcadm enable "$cacaoCurrentFMRI"; then log WARNING "Could not re-enable cacao service (fmri=$cacaoCurrentFMRI)" fi fi } # !!!!!!!!!!!! End ############################################################################# do_ha_status_update() { if [ -f $HAEC_PROPERTIES_FILE ]; then set_haec_classpath $JAVA_HOME/bin/java -cp $CLASSPATH com.orcl.sysman.haec_cw.HAECClusterwareAdapter ha-status > /dev/null satret=$? if [ $satret -ne 0 ]; then echo "$MYNAME: do_ha_status_update failed. Returned $satret" >> $ECHA_LOGFILE fi fi } ############################################################################# do_startup() { if $DEBUG; then set -x; fi do_security_check_on_jars sync_db_service_config load_startstop opt_temporary=$DEF_STARTSTOP_OPT_TEMPORARY GETOPT_MYNAME="$MYNAME start" GETOPT_LINUX="-o cntvwl:h -l cluster,notify,temporary,verbose,wait,logfile:,help" GETOPT_SUNOS="c(cluster)n(notify)t(temporary)v(verbose)w(wait)l:(logfile)h(help)" if eval "$GETOPT_INIT"; then : else log ERROR "$GETOPT_ERR" show_usage_startup return 1 fi # Crack subcommand arguments while eval "$GETOPT"; do case "$GETOPT_OPT" in c|-c|--cluster) opt_cluster=true ;; n|-n|--notify) opt_notify=true ;; t|-t|--temporary) opt_temporary=-t ;; w|-w|--wait) opt_wait=true ;; l|-l|--logfile) eval "$GETOPT_GETOPTARG" opt_logfile=$GETOPT_OPTARG ;; v|-v|--verbose) VERBOSE=true ;; h|-h|--help) show_usage_startup return 0 ;; \?) log ERROR "$GETOPT_ERR" show_usage_startup return 1 ;; *) # Internal error, shouldn't get here. log ERROR "$GETOPT_MYNAME: Unexpected option \"$GETOPT_OPT\"" return 1 ;; esac done # check to see if running in cluster environment set_haec_classpath # TODO Add support for other cluster adapters # LOCAL_NODE_NAME=`/bin/uname -n` logexec INFO $JAVA_HOME/bin/java -cp $CLASSPATH com.orcl.sysman.haec_cw.HAECClusterwareAdapter -q ha-status # Stop the ha ec server splash page service do_DisableSplashPageService # check for cluster flag if [ $opt_cluster == true ]; then if [ -f $HAEC_PROPERTIES_FILE ]; then if [ ! -f $HAEC_STATUS_LOG ]; then (umask 027; touch $HAEC_STATUS_LOG) fi echo "INFO do_startup entered with cluster flag" >> $HAEC_STATUS_LOG HAEC_ACTIVE_NAME=`/bin/grep haec.cluster.active.node $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}'` HAEC_CLUSTER_NODES=`/bin/grep haec.cluster.nodes $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}'` HAEC_RESOURCE_NAME=`/bin/grep haec.cluster.resourcename $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}'` HAEC_STATUS=`/bin/grep haec.ec.status $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}'` echo "INFO HAEC_ACTIVE_NAME:$HAEC_ACTIVE_NAME" >> $HAEC_STATUS_LOG echo "INFO HAEC_CLUSTER_NODES:$HAEC_CLUSTER_NODES" >> $HAEC_STATUS_LOG echo "INFO HAEC_STATUS:$HAEC_STATUS" >> $HAEC_STATUS_LOG echo "INFO LOCAL_NODE_NAME:$LOCAL_NODE_NAME" >> $HAEC_STATUS_LOG if [ $HAEC_STATUS == "ONLINE" ]; then echo "ERROR $HAEC_RESOURCE_NAME resource status is ONLINE. Not starting $HAEC_RESOURCE_NAME resource." >> $HAEC_STATUS_LOG log ERROR "$HAEC_RESOURCE_NAME resource status is ONLINE. Not starting $HAEC_RESOURCE_NAME resource." return 1 fi if [ ! $HAEC_ACTIVE_NAME == "None" ]; then echo "Node $HAEC_ACTIVE_NAME is currently running. Not starting $HAEC_RESOURCE_NAME resource." >> $HAEC_STATUS_LOG log ERROR "Node $HAEC_ACTIVE_NAME is currently running. Not starting $HAEC_RESOURCE_NAME resource." return 1 fi if [ `uname -s` = "SunOS" ]; then # Enable services till next reboot. The cluster software is responsible for startup opt_temporary='-t' else # On Linux work around the fact that there is no -t option to svcadm enable. enableSMFAutoStart fi fi else # If HAEC properties file exists, then do not start if [ -f $HAEC_PROPERTIES_FILE ]; then echo "ERROR Node is in a cluster. Not started. Use '$MYNAME ha-start' command." >> $HAEC_STATUS_LOG log ERROR "Node is in a cluster. Not started. Use '$MYNAME ha-start' command." return 1 fi fi # done with checking cluster environment eval "$GETOPT_FINI" if [ $# -gt 0 ]; then log ERROR "Unexpected parameters for start: $*" show_usage_startup return 1 fi if [ "$opt_logfile" ]; then LOGFILE=${DEFAULT_LOGFILE_LOCATION}/"$opt_logfile" validate_log_file $LOGFILE $DEF_ECADM_LOGFILE $opt_logfile if [ $? -ne 0 ]; then log ERROR "Invalid Log File. See previous error" return 1 fi fi # Clear the apache proxy.conf file. This file will only have contents # for remote Proxy Controllers echo "" > $UCE_PROXY_CONF satellite_svc_milestone=$DEF_STARTSTOP_SATELLITE_SVC_ENABLE satellite_svc_list=$DEF_STARTSTOP_SATELLITE_SVC_LIST if smf_present; then log NOTICE "Starting Enterprise Controller with SMF..." # !!!!!!!!!!!!!! CR 6857873 workaround if cacaoSMFdependencies_areInvalid; then if not cacaoSMFdependencies_doRestore; then log ERROR "Restoration of SMF service definitions failed" log ERROR "Manual repair of SMF services required. Exiting." exit 100 fi fi svcadm enable -r nfs/client else log NOTICE "Starting Enterprise Controller with SMFlite..." fi for svc in $satellite_svc_list; do if svcadm enable $svc; then state="`svcprop -p restarter/state $svc`" if [ "$state" = "maintenance" ]; then if svcadm clear $svc; then : # do nothing else log ERROR "Error clearing maintenance state on $svc (rc=$?); continuing ..." fi fi else log ERROR "Error enabling service $svc (rc=$?); continuing..." fi done if svcadm enable $opt_temporary $satellite_svc_milestone; then log INFO "... milestone \"satellite-enable\" successfully enabled" else log ERROR "Error enabling Enterprise Controller run-time milestone $satellite_svc_milestone (rc=$?)" return 1 fi if $opt_wait; then log INFO "... Waiting for Enterprise Controller services to go \"online\"" timeout=$DEF_STARTSTOP_STARTUP_TIMEOUT cur_svc_list=$satellite_svc_list while [ "$timeout" -gt 0 -a "$cur_svc_list" ]; do sleep 1 new_svc_list="" for svc in $cur_svc_list; do if [ "`svcprop -p restarter/state $svc`" != "online" -o \ "`svcprop -p restarter/next_state $svc`" != "none" ]; then new_svc_list="$new_svc_list $svc" fi done cur_svc_list="$new_svc_list" timeout=`expr $timeout - 1` done if [ "$cur_svc_list" ]; then log WARN "Timeout waiting for Enterprise Controller services to start ($cur_svc_list)" log WARN "Use \"svcs \\*scn\\* \\*container\\*\" to verify all services in \"online\" state" return 1 fi log NOTICE "Enterprise Controller services have started" fi [ -f $REASON_FILE ] && rm -f $REASON_FILE [ -d $ECHA_DATA_DIR ] || mkdir -m 750 -p $ECHA_DATA_DIR chmod o-rwx "$ECHA_DATA_DIR" # Calculate the count for the startup grace period if [ -f $HAEC_PROPERTIES_FILE ]; then do_ha_status_update HAEC_START_TIMEOUT=`/bin/grep haec.cluster.resourcestarttimeout $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}'` HAEC_CHECK_INTERVAL=`/bin/grep haec.cluster.checkinterval $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}'` HAEC_STARTUP_COUNT=$(($HAEC_START_TIMEOUT / $HAEC_CHECK_INTERVAL)) else TMP=`/bin/grep ecmonitor.startup.count $DB_PROPS` # if ecmonitor.startup.count found if [ $? -eq 0 ]; then HAEC_STARTUP_COUNT=`echo $TMP | /bin/awk -F= '{print $2}'` fi fi [ "$HAEC_STARTUP_COUNT" -lt 1 ] && HAEC_STARTUP_COUNT=1 (umask 027; echo $HAEC_STARTUP_COUNT > $ECHA_STARTUP_FILE) # If starting in cluster, then disable autostart if [ $opt_cluster == true ]; then disableSMFAutoStart fi if $opt_notify; then send_notification start `hostname` fi return 0 } show_usage_startup() { log NOTICE "Usage: $MYNAME start [options] Optional flags: -c|--cluster Cluster environment -l|--logfile Save output from command in -t|--temporary Make this state change temporary until next reboot -v|--verbose Increase verbosity level (may be repeated) -w|--wait Wait for services to complete starting " } ############################################################################# ############################################################################# do_maintenance() { # [options] if $DEBUG; then set -x; fi load_startstop opt_temporary=$DEF_STARTSTOP_OPT_TEMPORARY GETOPT_MYNAME="$MYNAME maintenance" GETOPT_LINUX="-o cnr:tvwl:ah -l cluster,notify,reason:,temporary,verbose,wait,logfile:,async,help" GETOPT_SUNOS="c(cluster)n(notify)r:(reason)t(temporary)v(verbose)w(wait)l:(logfile)a(async)h(help)" if eval "$GETOPT_INIT"; then : else log ERROR "$GETOPT_ERR" show_usage_maintenance return 1 fi opt_wait=false # Crack subcommand arguments while eval "$GETOPT"; do case "$GETOPT_OPT" in c|-c|--cluster) opt_cluster=true ;; n|-n|--notify) opt_notify=true ;; r|-r|--reason) eval "$GETOPT_GETOPTARG" opt_reason="$GETOPT_OPTARG" ;; t|-t|--temporary) opt_temporary=-t ;; w|-w|--wait) opt_wait=true ;; l|-l|--logfile) eval "$GETOPT_GETOPTARG" opt_logfile=$GETOPT_OPTARG ;; v|-v|--verbose) VERBOSE=true ;; a|-a|--async) opt_async=true ;; h|-h|--help) show_usage_maintenance return 0 ;; \?) log ERROR "$GETOPT_ERR" show_usage_maintenance return 1 ;; *) # Internal error, shouldn't get here. log ERROR "$GETOPT_MYNAME: Unexpected option \"$GETOPT_OPT\"" return 1 ;; esac done # Install the reason file if it has been provided if [ "$opt_reason" ]; then if [ -f "$opt_reason" ]; then (umask 027; cat "$opt_reason" > $REASON_FILE) else log ERROR "Specified reason file $opt_reason not found" return 1 fi fi ## Manage/observe shutdown of EC service # The DB connection monitoring "method" will trigger service shutdown # so the monitor will start this script in the background with the async # option. In this mode the shutdown arranged by SMF will be # observed and once complete the splashpage service will be started. # SMFlite does not organize the shutdown so if [ "$opt_async" ]; then if [ "$opt_reason" ]; then # Having captured the reason schedule a rerun of this method # to startup the webserver after the other services have been shutdown if [ `uname -s` = "SunOS" ]; then echo "$0 maintenance --async" | at now >/dev/null 2>&1 else # SMFLite does not co-ordinate a stop of the services, so # arrange to directly stop the services outside of this process echo "$0 maintenance" | at now >/dev/null 2>&1 fi return 0 fi # Wait for shutdown to complete before enabling the splashpage service timeout=$DEF_STARTSTOP_SHUTDOWN_TIMEOUT # A proper shutdown waits for all the services which satellite-available # depends upon, however to enable the splashpage service we only need # the uce-server to stop cur_svc_list="svc:/application/scn/uce-server:default" while [ "$timeout" -gt 0 -a "$cur_svc_list" ]; do sleep 1 new_svc_list="" for svc in $cur_svc_list; do if [ `svcprop -p restarter/state $svc` = "online" -o \ `svcprop -p restarter/next_state $svc` != "none" ]; then new_svc_list="$new_svc_list $svc" fi done cur_svc_list="$new_svc_list" timeout=`expr $timeout - 1` done if [ "$timeout" -eq 0 ]; then # failed to stop service in time - dont start splashpage return 1 fi else # Call shutdown directly do_wait="" $opt_wait && do_wait="--wait" do_shutdown $do_wait fi ## Startup SplashPageService do_EnableSplashPageService return 0 } show_usage_maintenance() { log NOTICE "Usage: $MYNAME maintenance Optional flags: -c|--cluster Cluster environment -l|--logfile Save output from command in -r|--reason Record reason for shutdown from message in -t|--temporary Make this state change temporary until next reboot -v|--verbose Increase verbosity level (may be repeated) -w|--wait Wait for services to complete stopping " } ############################################################################# ############################################################################# do_shutdown() { # [options] if $DEBUG; then set -x; fi load_startstop opt_temporary=$DEF_STARTSTOP_OPT_TEMPORARY GETOPT_MYNAME="$MYNAME stop" GETOPT_LINUX="-o cntvwl:h -l cluster,notify,temporary,verbose,wait,logfile:,help" GETOPT_SUNOS="c(cluster)n(notify)t(temporary)v(verbose)w(wait)l:(logfile)h(help)" if eval "$GETOPT_INIT"; then : else log ERROR "$GETOPT_ERR" show_usage_shutdown return 1 fi # Crack subcommand arguments while eval "$GETOPT"; do case "$GETOPT_OPT" in c|-c|--cluster) opt_cluster=true ;; n|-n|--notify) opt_notify=true ;; t|-t|--temporary) opt_temporary=-t ;; w|-w|--wait) opt_wait=true ;; l|-l|--logfile) eval "$GETOPT_GETOPTARG" opt_logfile=$GETOPT_OPTARG ;; v|-v|--verbose) VERBOSE=true ;; h|-h|--help) show_usage_shutdown return 0 ;; \?) log ERROR "$GETOPT_ERR" show_usage_shutdown return 1 ;; *) # Internal error, shouldn't get here. log ERROR "$GETOPT_MYNAME: Unexpected option \"$GETOPT_OPT\"" return 1 ;; esac done # check to see if running in cluster environment if [ $opt_cluster == false ]; then # If HAEC properties file exists, the do not start if [ -f $HAEC_PROPERTIES_FILE ]; then if [ ! -f $HAEC_STATUS_LOG ]; then (umask 027; touch $HAEC_STATUS_LOG) fi echo "ERROR Node is in a cluster. Not started. Use '$MYNAME ha-relocate' command to stop running on this node and relocate to standby node." >> $HAEC_STATUS_LOG log ERROR "Node is in a cluster. Not started. Use '$MYNAME ha-relocate' command to stop running on this node and relocate to standby node." return 1 fi fi # done with checking cluster environment eval "$GETOPT_FINI" if [ $# -gt 0 ]; then log ERROR "Unexpected parameters for stop: $*" show_usage_shutdown return 1 fi if [ "$opt_logfile" ]; then LOGFILE=${DEFAULT_LOGFILE_LOCATION}/"$opt_logfile" validate_log_file $LOGFILE $DEF_ECADM_LOGFILE $opt_logfile if [ $? -ne 0 ]; then log ERROR "Invalid Log File. See previous error" return 1 fi fi if [ ! -f $REASON_FILE ]; then (umask 027; echo "Operator initiated shutdown" > $REASON_FILE) fi # try to send a notification if $opt_notify; then send_notification stop `hostname` fi satellite_svc_milestone=$DEF_STARTSTOP_SATELLITE_SVC_ENABLE satellite_svc_list=$DEF_STARTSTOP_SATELLITE_SVC_LIST # !!!!!!!!!!!!!! CR 6857873 workaround if cacaoSMFdependencies_areInvalid; then if not cacaoSMFdependencies_doRestore; then log ERROR "Restoration of SMF service definitions failed" log ERROR "Manual repair of SMF services required. Exiting." exit 100 fi fi runstate=`svcprop -p restarter/state $satellite_svc_milestone` if [ "$runstate" = "online" ]; then if smf_present; then log NOTICE "Shutting down Enterprise Controller using SMF..." else log NOTICE "Shutting down Enterprise Controller using SMFlite..." fi if svcadm disable $opt_temporary $satellite_svc_milestone; then log INFO "... milestone \"satellite-enable\" successfully disabled" if $opt_wait; then log INFO "... waiting for services to go \"offline\"" timeout=$DEF_STARTSTOP_SHUTDOWN_TIMEOUT cur_svc_list=$satellite_svc_list while [ "$timeout" -gt 0 -a "$cur_svc_list" ]; do sleep 1 new_svc_list="" for svc in $cur_svc_list; do if [ `svcprop -p restarter/state $svc` = "online" -o \ `svcprop -p restarter/next_state $svc` != "none" ]; then new_svc_list="$new_svc_list $svc" fi done cur_svc_list="$new_svc_list" timeout=`expr $timeout - 1` done if [ "$cur_svc_list" ]; then log WARN "Timeout waiting for Enterprise Controller services to stop ($cur_svc_list)" log WARN "Use \"svcs \\*scn\\* \\*container\\*\" to verify all services in \"offline\" state" return 1 else log NOTICE "Enterprise Controller services have stopped" fi fi return 0 else log ERROR "ERROR during shutdown of milestone \"satellite-enable\" rc=$?" log ERROR "Use \"svcs \\*scn\\*\ \\*container\\*\" to determine all service states(s)" return 1 fi else log NOTICE "Enterprise Controller services already stopped" return 0 fi } show_usage_shutdown() { log NOTICE "Usage: $MYNAME stop [options] Optional flags: -c|--cluster Cluster environment -l|--logfile Save output from command in -t|--temporary Make this state change temporary until next reboot -v|--verbose Increase verbosity level (may be repeated) -w|--wait Wait for services to complete stopping " } ############################################################################# ############################################################################# do_configure() { # [options] opt_config_file= local_proxy=true local_proxy_wait= if $DEBUG; then set -x; fi GETOPT_MYNAME="$MYNAME configure" GETOPT_LINUX="-o f:l:pPvwh -l config:,logfile:,proxy,noproxy,verbose,wait,help" GETOPT_SUNOS="f:(config)l:(logfile)p(proxy)P(noproxy)v(verbose)w(wait)h(help)" if eval "$GETOPT_INIT"; then : else log ERROR "$GETOPT_ERR" show_usage_configure return 1 fi while eval "$GETOPT"; do case "$GETOPT_OPT" in f|-f|--config) eval "$GETOPT_GETOPTARG" opt_config_file=$GETOPT_OPTARG ;; l|-l|--logfile) eval "$GETOPT_GETOPTARG" opt_logfile=$GETOPT_OPTARG ;; v|-v|--verbose) VERBOSE=true ;; p|-p|--proxy) local_proxy=true ;; P|-P|--noproxy) local_proxy=false ;; w|-w|--wait) local_proxy_wait="-w" ;; h|-h|--help) show_usage_configure return 0 ;; \?) log ERROR "$GETOPT_ERR" show_usage_configure return 1 ;; *) # Internal error, shouldn't get here. log ERROR "$GETOPT_MYNAME: Unexpected option \"$GETOPT_OPT\"" return 1 ;; esac done # check to see if running in cluster environment - should not configure if in a cluster and not active node set_haec_classpath logexec INFO $JAVA_HOME/bin/java -cp $CLASSPATH com.orcl.sysman.haec_cw.HAECClusterwareAdapter -q ha-status # TODO Add support for other cluster adapters LOCAL_NODE_NAME=`/bin/uname -n` # Verify EC Status File exists - so maybe running in cluster if [ -f $HAEC_STATUS_FILE ]; then if [ ! -f $HAEC_STATUS_LOG ]; then (umask 027; touch $HAEC_STATUS_LOG) fi echo "INFO Entered do_configure" >> $HAEC_STATUS_LOG HAEC_ACTIVE_NAME=`/bin/grep haec.cluster.active.node $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}'` HAEC_CLUSTER_NODES=`/bin/grep haec.cluster.nodes $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}'` NODES=`/bin/grep haec.cluster.nodes $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}' | /bin/awk -F, '{print $1" "$2" "$3" "$4" "$5}'` HAEC_RESOURCE_NAME=`/bin/grep haec.cluster.resourcename $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}'` HAEC_STATUS=`/bin/grep haec.ec.status $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}'` echo "INFO HAEC_ACTIVE_NAME:$HAEC_ACTIVE_NAME" >> $HAEC_STATUS_LOG echo "INFO HAEC_CLUSTER_NODES:$HAEC_CLUSTER_NODES" >> $HAEC_STATUS_LOG echo "INFO HAEC_STATUS:$HAEC_STATUS" >> $HAEC_STATUS_LOG echo "INFO LOCAL_NODE_NAME:$LOCAL_NODE_NAME" >> $HAEC_STATUS_LOG # Check if node is a cluster member. If so, then disallow for NODE in $NODES; do if [ "$NODE" == "$LOCAL_NODE_NAME" ]; then if [ "$NODE" != "$HAEC_ACTIVE_NAME" ]; then echo "ERROR Node $NODE is in a cluster, configure failed. Need to run '$MYNAME ha-unconfigure-standby'" >> $HAEC_STATUS_LOG log ERROR " Node $NODE is in a cluster, configure failed. Need to run '$MYNAME ha-unconfigure-standby'" >> $HAEC_STATUS_LOG return 1 fi fi done fi # done with checking cluster environment eval "$GETOPT_FINI" if [ $# -gt 0 ]; then log ERROR "Unexpected parameters for configure: $*" show_usage_configure return 1 fi if [ ! "$opt_config_file" ]; then opt_config_file=`mktemp -t -p /tmp satadm.config.XXXXXX` if [ -z "$opt_config_file" ]; then log ERROR "configure: cannot create temp config file, exiting" return 1 fi trap 'rm -f $opt_config_file' 0 OLDUMASK=`umask` umask 027 cat > $opt_config_file < Properties file containing registration info. If not provided then Enterprise Controller will be configured in disconnected mode. -p|--proxy Enable local Proxy Controller after Enterprise Controller is configured (default). -P|--noproxy Do NOT enable the local Proxy Controller. -l|--logfile Save output from command in -v|--verbose Increase verbosity level (may be repeated) -w|--wait Wait for local Proxy Controller to complete configuration " } ############################################################################# ############################################################################# do_unconfigure() { # [options] if $DEBUG; then set -x; fi opt_connections= GETOPT_MYNAME="$MYNAME unconfigure" GETOPT_LINUX="-o vcl:h -l verbose,logfile:,help" GETOPT_SUNOS="v(verbose)c(connections)l:(logfile)h(help)" if eval "$GETOPT_INIT"; then : else log ERROR "$GETOPT_ERR" show_usage_unconfigure return 1 fi while eval "$GETOPT"; do case "$GETOPT_OPT" in l|-l|--logfile) eval "$GETOPT_GETOPTARG" opt_logfile=$GETOPT_OPTARG ;; v|-v|--verbose) VERBOSE=true ;; c|-c|--connections) opt_connections="-c" ;; h|-h|--help) show_usage_unconfigure return 0 ;; \?) log ERROR "$GETOPT_ERR" show_usage_unconfigure return 1 ;; *) # Internal error, shouldn't get here. log ERROR "$GETOPT_MYNAME: Unexpected option \"$GETOPT_OPT\"" return 1 ;; esac done # check to see if running in cluster environment - should not unconfigure if in a cluster set_haec_classpath VERBOSE_FLAG= if [ $VERBOSE == "true" ]; then VERBOSE_FLAG="-v" fi logexec INFO $JAVA_HOME/bin/java -cp $CLASSPATH com.orcl.sysman.haec_cw.HAECClusterwareAdapter -q ha-status # TODO Add support for other cluster adapters LOCAL_NODE_NAME=`/bin/uname -n` # Verify EC Status File exists - so maybe running in cluster if [ -f $HAEC_STATUS_FILE ]; then if [ ! -f $HAEC_STATUS_LOG ]; then (umask 027; touch $HAEC_STATUS_LOG) fi echo "INFO Entered do_unconfigure" >> $HAEC_STATUS_LOG HAEC_ACTIVE_NAME=`/bin/grep haec.cluster.active.node $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}'` HAEC_CLUSTER_NODES=`/bin/grep haec.cluster.nodes $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}'` NODES=`/bin/grep haec.cluster.nodes $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}' | /bin/awk -F, '{print $1" "$2" "$3" "$4" "$5}'` HAEC_RESOURCE_NAME=`/bin/grep haec.cluster.resourcename $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}'` HAEC_STATUS=`/bin/grep haec.ec.status $HAEC_STATUS_FILE | /bin/awk -F= '{print $2}'` echo "INFO HAEC_ACTIVE_NAME:$HAEC_ACTIVE_NAME" >> $HAEC_STATUS_LOG echo "INFO HAEC_CLUSTER_NODES:$HAEC_CLUSTER_NODES" >> $HAEC_STATUS_LOG echo "INFO HAEC_STATUS:$HAEC_STATUS" >> $HAEC_STATUS_LOG echo "INFO LOCAL_NODE_NAME:$LOCAL_NODE_NAME" >> $HAEC_STATUS_LOG # Check if node is a cluster member. If so, then disallow for NODE in $NODES; do if [ "$NODE" == "$LOCAL_NODE_NAME" ]; then echo "ERROR Node $LOCAL_NODE_NAME is in a cluster, unconfigure failed. Need to run '$MYNAME ha-unconfigure-standby or $MYNAME ha-unconfigure-primary'" >> $HAEC_STATUS_LOG log ERROR " Node $LOCAL_NODE_NAME is in a cluster, unconfigure failed. Need to run '$MYNAME ha-unconfigure-standby' or '$MYNAME ha-unconfigure-primary'" >> $HAEC_STATUS_LOG return 1 fi done fi # done with checking cluster environment eval "$GETOPT_FINI" if [ $# -gt 0 ]; then log ERROR "Unexpected parameters for unconfigure: $*" show_usage_unconfigure return 1 fi if [ "$opt_logfile" ]; then LOGFILE=${DEFAULT_LOGFILE_LOCATION}/"$opt_logfile" validate_log_file $LOGFILE $DEF_ECADM_LOGFILE $opt_logfile if [ $? -ne 0 ]; then log ERROR "Invalid Log File. See previous error" return 1 fi fi set_satmgr_classpath if logexec INFO $JAVA_HOME/bin/java -cp $CLASSPATH com.sun.scn.sat.client.UnconfigureSatellite $opt_connections; then log NOTICE " --- Enterprise Controller unconfigured" else log ERROR " --- Enterprise Controller unconfigure failed" exit 100 fi } show_usage_unconfigure() { log NOTICE "Usage: $MYNAME unconfigure Optional flags: -l|--logfile Save output from command in -v|--verbose Increase verbosity level (may be repeated) -c|--connections Remove all registered Proxy Controller and Agent connections " } ############################################################################# ############################################################################# do_clear_locks() { # [options] if $DEBUG; then set -x; fi opt_asset= GETOPT_MYNAME="$MYNAME clear-locks" GETOPT_LINUX="-o va:l:h -a asset,-l verbose,logfile:,help" GETOPT_SUNOS="v(verbose)a:(asset)l:(logfile)h(help)" if eval "$GETOPT_INIT"; then : else log ERROR "$GETOPT_ERR" show_usage_clear_locks return 1 fi while eval "$GETOPT"; do case "$GETOPT_OPT" in l|-l|--logfile) eval "$GETOPT_GETOPTARG" opt_logfile=$GETOPT_OPTARG ;; a|-a|--asset) eval "$GETOPT_GETOPTARG" opt_asset=$GETOPT_OPTARG ;; v|-v|--verbose) VERBOSE=true ;; h|-h|--help) show_usage_clear_locks return 0 ;; \?) log ERROR "$GETOPT_ERR" show_usage_clear_locks return 1 ;; *) # Internal error, shouldn't get here. log ERROR "$GETOPT_MYNAME: Unexpected option \"$GETOPT_OPT\"" return 1 ;; esac done if [ ! "$opt_asset" ]; then log ERROR "Must provide asset object name." show_usage_clear_locks return 1 fi set_satmgr_classpath if logexec INFO $JAVA_HOME/bin/java -cp $CLASSPATH com.sun.scn.sat.client.ClearLocks $opt_asset; then log NOTICE " --- Locks cleared" else log ERROR " --- Clear locks failed" exit 100 fi } show_usage_clear_locks() { log NOTICE "Usage: $MYNAME clear-locks -a Optional flags: -l|--logfile Save output from command in -v|--verbose Increase verbosity level (may be repeated) -a|--asset Specifies the asset that will have its locks cleared " } ############################################################################# ############################################################################# do_clear_cache() { # [options] if $DEBUG; then set -x; fi opt_asset= GETOPT_MYNAME="$MYNAME clear-cache" GETOPT_LINUX="-o va:l:h,-l verbose,logfile:,help" GETOPT_SUNOS="v(verbose)l:(logfile)h(help)" if eval "$GETOPT_INIT"; then : else log ERROR "$GETOPT_ERR" show_usage_clear_cache return 1 fi while eval "$GETOPT"; do case "$GETOPT_OPT" in l|-l|--logfile) eval "$GETOPT_GETOPTARG" opt_logfile=$GETOPT_OPTARG ;; a|-a|--asset) eval "$GETOPT_GETOPTARG" opt_asset=$GETOPT_OPTARG ;; v|-v|--verbose) VERBOSE=true ;; h|-h|--help) show_usage_clear_cache return 0 ;; \?) log ERROR "$GETOPT_ERR" show_usage_clear_cache return 1 ;; *) # Internal error, shouldn't get here. log ERROR "$GETOPT_MYNAME: Unexpected option \"$GETOPT_OPT\"" return 1 ;; esac done set_satmgr_classpath if logexec INFO $JAVA_HOME/bin/java -cp $CLASSPATH com.sun.scn.sat.client.ClearCache; then log NOTICE " --- Cache cleared" else log ERROR " --- Clear cache failed" exit 100 fi } show_usage_clear_cache() { log NOTICE "Usage: $MYNAME clear-cache Clears the authorization and Job Managment caches. Optional flags: -l|--logfile Save output from command in -v|--verbose Increase verbosity level (may be repeated) " } ########################################################################### ########################################################################### # # # validate_output_file() { outputFile=$1 # cannot exist. In the case default was used, ensure it id rm'd before here if [ -e "${outputFile}" ]; then log ERROR "file = $outputFile already exists. will not overwrite" return 1 fi # make sure it can be written touch ${outputFile} 1>/dev/null 2>&1 if [ $? -ne 0 ]; then log ERROR "touch cannot create file=$outputFile" return 1 fi # limit who has access to the log chmod o-xrw ${outputFile} if [ $? -ne 0 ]; then log ERROR "Cannot set privs for $outputFile" return 1 fi # because touch created it rm -f ${outputFile} if [ $? -ne 0 ]; then log ERROR "Cannot remove $outputFile after touch created it" return 1 fi } ########################################################################### ########################################################################### # # helper function to detect a valid log file param # # see code/comments for what we allow. This is partly in # response to CR176154. # # $1 logFile passed in, with the $DEFAULT_LOG_LOCATION prepended to it. # $2 defaultLogFile, need to check, because we allow overwrite in that case. # validate_log_file() { logFile=$1 defaultLogFile=$2 logfileparam=$3 if [ "$logFile" = "" ]; then log ERROR "Null logFile not allowed" returnCode=1 elif [ -d "$logfileparam" ]; then log ERROR "No directory specfication allowed logfileparam=$logfileparam. Specify a filename only" returnCode=1 elif [ "$logFile" = "$defaultLogFile" ]; then # we allow overwrite of the default, no existence check log Notice "Using default log file = $logFile" rm $logFile returnCode=0 elif [ "`dirname $logFile`" != "$DEFAULT_LOGFILE_LOCATION" ]; then echo $logFile echo $DEFAULT_LOGFILE_LOCATION log ERROR "No directory specification allowed in log file name = $logFile. Specify a filename only." returnCode=1 elif [ -e "$logFile" ]; then log ERROR "logFile = $logFile already exists. Please specify another filename" returnCode=1 elif [ ! -e "$DEFAULT_LOG_LOCATION/$logFile" ]; then #log Notice "using logFile = $logFile" returnCode=0 else log ERROR "unknown logFile state. Use the default or pass another value with -l param" returnCode=1 fi if [ $returnCode -ne 0 ]; then return $returnCode fi # ensure the log file can be opened, and set privs for log files umask 027 if [ $? -ne 0 ]; then log ERROR "Cannot set umask for $logFile" return 1 fi # validate it (cannot exist, touch, etc.) validate_output_file $logFile if [ $? -ne 0 ]; then log ERROR "Invalid logFile = $logFile. See previous error" return 1 fi log NOTICE "using logFile = $logFile" return 0 } ############################################################################ ############################################################################ do_rebuild_index() { # [options] if $DEBUG; then set -x; fi unset rebuild_mode GETOPT_MYNAME="$MYNAME rebuild-db-index" GETOPT_SUNOS="h(help)v(verbose)" GETOPT_LINUX="-o h:v -l help;,verbose" if eval "$GETOPT_INIT"; then : else log ERROR "$GETOPT_ERR" show_usage_rebuild return 1 fi # Crack subcommand arguments while eval "$GETOPT"; do case "$GETOPT_OPT" in h|-h|--help) show_usage_rebuild return 0 ;; v|-v|--verbose) VERBOSE=true ;; \?) log ERROR "$GETOPT_ERR" show_usage_rebuild return 1 ;; *) # Internal error, shouldn't get here. log ERROR "$GETOPT_MYNAME: Unexpected option \"$GETOPT_OPT\"" return 1 ;; esac done BASE_DATA_DIR=/var/opt/sun/xvm DBPROPS_FILE=$BASE_DATA_DIR/db.properties REBUILD_INDEX_LOG=$BASE_DATA_DIR/logs/satadmsqlplus.log OUTPUT_MODE=/dev/null if [ ! -f $DBPROPS_FILE ]; then log ERROR " $DBPROPS_FILE file does not exist on this system" exit $ERR_ABORTNOW fi db_type=`grep mgmtdb.server.type $DBPROPS_FILE | cut -d= -f2` if [ "$db_type" = "remote" ]; then log WARN "This operation can be performed only on OpsCenter with embedded database setup." exit $ERR_ABORTNOW fi if [ "$VERBOSE" = "true" ] ; then OUTPUT_MODE=/dev/tty fi if [ "`uname -s`" = "SunOS" ]; then DB_ROOT_DIR=/opt/ORCLsysman-db SATADM_DIR=/opt/SUNWxvmoc elif [ "`uname -s`" = "Linux" ]; then DB_ROOT_DIR=/opt/orcl/orcl-sysman-db SATADM_DIR=/opt/sun/xvmoc fi SATADM=$SATADM_DIR/bin/ecadm ec_status=`$SATADM status` if [ "$ec_status" = "online" ]; then log ERROR " Enterprise Controller should be offline to perform this operation" exit $ERR_ABORTNOW fi log NOTICE "Coalesce index will happen when the % deleted index leaf is in between 10 - 15 and the table rows are more than 1 million. Rebuild index will happen when the % deleted index leaf is more than 50 and the table rows are more than 1 million. If no index meet this criteria, the rebuild operation will be skipped. " get_oracleUserAndGroup su - $OC_DB_USER -c "echo startup | sqlplus / as sysdba" | tee $OUTPUT_MODE >> $REBUILD_INDEX_LOG su - $OC_DB_USER -c "cd $DB_ROOT_DIR/sql/common/oracle ; echo @rebuild_indexes.sql | sqlplus / as sysdba" | tee /dev/tty >> $REBUILD_INDEX_LOG su - $OC_DB_USER -c "echo shutdown | sqlplus / as sysdba" | tee $OUTPUT_MODE >> $REBUILD_INDEX_LOG } show_usage_rebuild() { log NOTICE "Usage: $MYNAME rebuild-db-index [options] Optional flags: -v|--verbose Increase verbosity level (may be repeated) " } ############################################################################# ############################################################################# do_backup() { # [options] if $DEBUG; then set -x; fi unset opt_config opt_tempdir opt_logfile opt_description opt_output opt_tag GETOPT_MYNAME="$MYNAME backup" GETOPT_LINUX="-o c:T:d:o:t:l:rvh -l configdir:,tempdir:,description:,output:,tag:,remotedb,logfile:,verbose,help" GETOPT_SUNOS="c:(configdir)T:(tempdir)d:(description)o:(output)r(remotedb)t:(tag)l:(logfile)v(verbose)h(help)" if eval "$GETOPT_INIT"; then : else log ERROR "$GETOPT_ERR" show_usage_backup return 1 fi # Crack subcommand arguments while eval "$GETOPT"; do case "$GETOPT_OPT" in c|-c|--configdir) eval "$GETOPT_GETOPTARG" opt_config=$GETOPT_OPTARG ;; T|-T|--tempdir) eval "$GETOPT_GETOPTARG" opt_tempdir=$GETOPT_OPTARG/satadm-temp-$$ ;; l|-l|--logfile) eval "$GETOPT_GETOPTARG" opt_logfile=$GETOPT_OPTARG ;; d|-d|--description) eval "$GETOPT_GETOPTARG" opt_description=$GETOPT_OPTARG ;; o|-o|--output) eval "$GETOPT_GETOPTARG" opt_output=$GETOPT_OPTARG ;; r|-r|--remotedb) REMOTEDB=true ;; t|-t|--tag) eval "$GETOPT_GETOPTARG" opt_tag=$GETOPT_OPTARG ;; v|-v|--verbose) VERBOSE=true ;; h|-h|--help) show_usage_backup return 0 ;; \?) log ERROR "$GETOPT_ERR" show_usage_backup return 1 ;; *) # Internal error, shouldn't get here. log ERROR "$GETOPT_MYNAME: Unexpected option \"$GETOPT_OPT\"" return 1 ;; esac done eval "$GETOPT_FINI" if [ $# -gt 0 ]; then log ERROR "Unexpected parameters for backup: $*" show_usage_backup return 1 fi # fill in option defaults BACKUP_OUTPUT="${opt_output:-$DEF_BACKUP_OPT_OUTPUT}" BACKUP_TAG="${opt_tag:-$DEF_BACKUP_OPT_TAG}" BACKUP_DESCRIPTION="${opt_description:-$DEF_BACKUP_OPT_DESCRIPTION}" BACKUP_TMPDIR="${opt_tempdir:-$DEF_BACKUP_OPT_TMPDIR}" CONFIGDIR=${opt_config:-$DEF_BACKUP_CONFIGDIR} # get list of component modules which perform backups (and drop files # in $BACKUP_TMPDIR) # N.B. NO BLANKS in component directory names! BACKUPCOMPONENTS=`get_components | sort` BACKUP_FAILED=false ######################################################################### # PreBackup Phase validate_output_file ${BACKUP_OUTPUT} if [ $? -ne 0 ]; then log ERROR "${BACKUP_OUTPUT} is not valid. See previous error" BACKUP_FAILED=true return 1 fi get_oracleUserAndGroup if [ -d "$BACKUP_TMPDIR" ]; then BACKUP_CREATED_TMPDIR=false chmod 770 "$BACKUP_TMPDIR" chown root:$OC_DB_GROUP "$BACKUP_TMPDIR" elif mkdir -m 770 -p "$BACKUP_TMPDIR"; then chown root:$OC_DB_GROUP "$BACKUP_TMPDIR" BACKUP_CREATED_TMPDIR=true else log ERROR "could not create temporary directory $BACKUP_TMPDIR" BACKUP_FAILED=true return 1 fi REMOTE_FLAG="local" if [ "$REMOTEDB" == "true" ]; then export REMOTE_FLAG="remote" fi # Now we can turn on logging TRACEFILE="$BACKUP_TMPDIR/Backup_logfile.txt" [ "$TRACEFILE" ] && rm -f "$TRACEFILE" if [ "$opt_logfile" != "" ]; then LOGFILE=${DEFAULT_LOGFILE_LOCATION}/${opt_logfile} else LOGFILE=${DEF_BACKUP_LOGFILE} fi validate_log_file $LOGFILE $DEF_BACKUP_LOGFILE $opt_logfile if [ $? -ne 0 ]; then log ERROR "Invalid Log File. See previous error" BACKUP_FAILED=true return 1 fi log NOTICE "*** PreBackup Phase" echo "$BACKUP_DESCRIPTION" > $BACKUP_TMPDIR/Backup_description echo "$VERSION" > "$BACKUP_TMPDIR/Backup_version" echo "$BACKUP_TAG" > "$BACKUP_TMPDIR/Backup_tag" TODOCOMPONENTS="$BACKUPCOMPONENTS" NEWCOMPONENTS="" while [ "$TODOCOMPONENTS" ]; do pop CURCOMPONENT TODOCOMPONENTS OIFS=$IFS; IFS=':'; set -- $CURCOMPONENT; IFS=$OIFS CURCOMPONENT=$1 CURSUCCESS=true CURCONTINUE=true CURCOMPONENTCONFDIR=$CONFIGDIR/$CURCOMPONENT CURCOMPONENTNAME=$CURCOMPONENT [ -r $CURCOMPONENTCONFDIR/component-name ] \ && CURCOMPONENTNAME=`cat $CURCOMPONENTCONFDIR/component-name` PREBACKUPCMD=$CURCOMPONENTCONFDIR/prebackup if [ -x $PREBACKUPCMD ] ; then log INFO " --- $CURCOMPONENTNAME: Executing prebackup" if logexec INFO $PREBACKUPCMD "$BACKUP_TAG" "$BACKUP_TMPDIR" "$CURCOMPONENTCONFDIR"; then CURSUCCESS=true CURCONTINUE=true log INFO " --- $CURCOMPONENTNAME: Successful prebackup" else case $? in $ERR_CONTINUE) CURSUCCESS=false CURCONTINUE=true log ERROR " --- $CURCOMPONENTNAME: Failed prebackup" ;; $ERR_ABORTNOW ) CURSUCCESS=false CURCONTINUE=false log ERROR " --- $CURCOMPONENTNAME: Fatal failure in prebackup (backup terminated)" exit 100 ;; $ERR_NOMORE | *) CURSUCCESS=false CURCONTINUE=false log ERROR " --- $CURCOMPONENTNAME: Failed prebackup (will not continue)" ;; esac BACKUP_FAILED=true fi fi append "$CURCOMPONENT:$CURCONTINUE:$CURSUCCESS" NEWCOMPONENTS done BACKUPCOMPONENTS="$NEWCOMPONENTS" ######################################################################### # Backup Phase if $BACKUP_FAILED; then log WARN "*** Backup Phase (Skipped due to errors)" else log NOTICE "*** Backup Phase" fi TODOCOMPONENTS="$BACKUPCOMPONENTS" NEWCOMPONENTS="" while [ "$TODOCOMPONENTS" ]; do pop CURCOMPONENT TODOCOMPONENTS OIFS=$IFS; IFS=':'; set -- $CURCOMPONENT; IFS=$OIFS CURCOMPONENT=$1 CURCONTINUE=$2 CURPRESUCCESS=$3 # We continue to here even if we're skipping backup to fill in the # success codes in BACKUPCOMPONENTS as well as reverse the list order if $BACKUP_FAILED; then CURSUCCESS=false else CURCOMPONENTCONFDIR=$CONFIGDIR/$CURCOMPONENT CURCOMPONENTNAME=$CURCOMPONENT [ -r $CURCOMPONENTCONFDIR/component-name ] \ && CURCOMPONENTNAME=`cat $CURCOMPONENTCONFDIR/component-name` BACKUPCMD=$CURCOMPONENTCONFDIR/backup if [ -x $BACKUPCMD ]; then if $CURCONTINUE ; then log INFO " --- $CURCOMPONENTNAME: Executing backup" if logexec INFO $BACKUPCMD "$BACKUP_TAG" "$BACKUP_TMPDIR" "$CURCOMPONENTCONFDIR" "$CURPRESUCCESS" ; then CURSUCCESS=true log INFO " --- $CURCOMPONENTNAME: Successful backup" else case $? in $ERR_CONTINUE) CURSUCCESS=false log ERROR " --- $CURCOMPONENTNAME: Failed backup" ;; $ERR_ABORTNOW ) CURSUCCESS=false CURCONTINUE=false log ERROR " --- $CURCOMPONENTNAME: Fatal failure in backup (backup terminated)" exit 100 ;; $ERR_NOMORE | *) CURSUCCESS=false CURCONTINUE=false log ERROR " --- $CURCOMPONENTNAME: Failed backup (will not continue later steps)" ;; esac BACKUP_FAILED=true fi else log NOTICE " --- $CURCOMPONENTNAME: Skipping backup" fi fi fi # We REVERSE the order here! prepend "$CURCOMPONENT:$CURCONTINUE:$CURPRESUCCESS:$CURSUCCESS" NEWCOMPONENTS done BACKUPCOMPONENTS="$NEWCOMPONENTS" ######################################################################### # PostBackup Phase log NOTICE "*** PostBackup Phase" TODOCOMPONENTS="$BACKUPCOMPONENTS" ERRCOMPONENTS="" #this stores the list of components that have failed while [ "$TODOCOMPONENTS" ]; do pop CURCOMPONENT TODOCOMPONENTS OIFS=$IFS; IFS=':'; set -- $CURCOMPONENT; IFS=$OIFS CURCOMPONENT=$1 CURCONTINUE=$2 CURPRESUCCESS=$3 CURBAKSUCCESS=$4 CURSUCCESS=$CURBAKSUCCESS CURCOMPONENTCONFDIR=$CONFIGDIR/$CURCOMPONENT CURCOMPONENTNAME=$CURCOMPONENT [ -r $CURCOMPONENTCONFDIR/component-name ] \ && CURCOMPONENTNAME=`cat $CURCOMPONENTCONFDIR/component-name` POSTBACKUPCMD=$CURCOMPONENTCONFDIR/postbackup if [ -x $POSTBACKUPCMD ] ; then if $CURCONTINUE; then log INFO " --- $CURCOMPONENTNAME: Executing postbackup" if logexec INFO $POSTBACKUPCMD "$BACKUP_TAG" "$BACKUP_TMPDIR" "$CURCOMPONENTCONFDIR" "$CURPRESUCCESS" "$CURBAKSUCCESS"; then log INFO " --- $CURCOMPONENTNAME: Successful postbackup" else case $? in $ERR_CONTINUE) CURSUCCESS=false prepend $CURCOMPONENTNAME ERRCOMPONENTS log ERROR " --- $CURCOMPONENTNAME: Error during postbackup. See backup logs for details. Backup will continue." ;; $ERR_ABORTNOW ) CURSUCCESS=false CURCONTINUE=false log ERROR " --- $CURCOMPONENTNAME: Fatal failure in postbackup (backup terminated)" exit 100 ;; $ERR_NOMORE | *) prepend $CURCOMPONENTNAME ERRCOMPONENTS log ERROR " --- $CURCOMPONENTNAME: Failed postbackup (will not continue)" ;; esac BACKUP_FAILED=true fi else log NOTICE " --- $CURCOMPONENTNAME: Skipping postbackup" fi fi done if $BACKUP_FAILED && [ "$ERRCOMPONENTS" != "000_startstop.d " ]; then # set return code for do_backup() log ERROR "*** Errors during backup -- no output written" return 1 fi ######################################################################### # Archive $BACKUP_TMPDIR to $BACKUP_OUTPUT # Include a copy of the configuration directory machine_os=`uname -s` if [ "$machine_os" = "SunOS" ]; then tar_option="cEf" else tar_option="cf" fi if (cd $CONFIGDIR; tar $tar_option $BACKUP_TMPDIR/Backup_configdir.tar .); then # Get the absolute path if needed. DIRNAME=`dirname $BACKUP_OUTPUT` BASENAME=`basename $BACKUP_OUTPUT` if [ "$DIRNAME" == "." ] then BACKUP_OUTPUT=`pwd`/$BASENAME fi if (umask 027; cd $BACKUP_TMPDIR; tar $tar_option $BACKUP_OUTPUT .); then log NOTICE "*** Backup complete" log NOTICE "*** Output in $BACKUP_OUTPUT" log NOTICE "*** Log in $LOGFILE" return 0 else log ERROR "Errors during archive of $BACKUP_TMPDIR to $BACKUP_OUTPUT" log ERROR "**** Aborting -- output deleted" log ERROR "**** Log in $LOGFILE" rm -f $BACKUP_OUTPUT BACKUP_FAILED=true return 1 fi else log WARN "Could not back up configuration directory $CONFIGDIR" BACKUP_FAILED=true return 1 fi } cleanup_backup() { #if $DEBUG; then set -x; fi if $BACKUP_CREATED_TMPDIR \ && [ \! -z "$BACKUP_TMPDIR" -a -d "$BACKUP_TMPDIR" ] ; then rm -fr "$BACKUP_TMPDIR" fi } show_usage_backup() { log NOTICE "Usage: $MYNAME backup [options] Note: The $MYNAME backup command does not back up the /var/opt/sun/xvm/images/os directory. This directory contains OS images downloaded or imported into Ops Center. This is intentional, because the size of some of the files can be prohibitively large, such as those found under the /iso sub-directory. In addition to running the $MYNAME backup command, you should optionally back up the /var/opt/sun/xvm/images/os directory and manually archive the files to another server, file-share facility, or a location outside of the /var/opt/sun directory. This is to avoid having to re-download or import the large OS images should the content need to be restored. Options: -o|--output Specify the file in which the backup archive will be generated. Do not specify the path inside the xvm install directories(/opt/*xvm*). Default: /var/tmp/sat-backup--