blob: c09169b19280fd4d21bbc66f4e829e39794756fb [file]
#!/bin/bash
#
# @@@ START COPYRIGHT @@@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# @@@ END COPYRIGHT @@@
# Perform an SQ shutdown
function Usage {
echo
echo "Usage: $0 [ abrupt | immediate ]"
echo
echo "This command is used to perform a shutdown of the SQ environment."
echo "If a parameter is not specified, then a normal shutdown is performed."
echo
}
function LogIt {
echo "`date`: $1" >> $TRAF_HOME/logs/startup.log
}
function echoLog {
echo $1 | tee -a $SQMON_LOG
}
script_name=`/bin/basename $0`
SQLOG_DIR=$TRAF_HOME/logs
SQMON_LOG=$SQLOG_DIR/sqmon.log
SQGOMON_FILE=$TRAF_HOME/sql/scripts/gomon.cold
SQSTOP_EXIT_STATUS=$TRAF_HOME/sql/scripts/sqstop.exit_status
if [ $# -eq 0 ]; then
shutdowntype=normal
sparam=
else
if (
[ $1 != "abrupt" ] &&
[ $1 != "immediate" ]
); then
echo "Invalid parameter: $1";
Usage;
exit 1;
else
shutdowntype=$1;
sparam=$1;
fi
fi
LogIt "Begin $script_name $shutdowntype"
if [[ ! -e $SQGOMON_FILE ]]; then
echo "Unable to find file: gomon.cold. An sqgen may need to be run"
exit 0;
fi
# Check if the SQ environment is up or not
sqcheck -i 1 -d 1 > /dev/null 2>&1
sq_stat=$?
if [[ $sq_stat -eq 255 ]]; then
lv_msg="SQ environment is not up."
echo "$lv_msg"
LogIt "End $script_name $shutdowntype, exit code: 0, $lv_msg"
exit 0;
fi
rm -f $SQSTOP_EXIT_STATUS
# Stop the REST Service
reststop
# Stop the DCS Service
dcsstop
# Stop the lob Service
#lobstop
# Issue the shutdown request
echoLog "Shutting down ($shutdowntype) the SQ environment!"
echoLog "`date`"
sqshell -a <<eof
ps
shutdown $sparam
eof
echoLog "Issued a 'shutdown $shutdowntype' request"
sleep 2
# Now check whether the SQ environment is still up or not
# try to attach the SQ shell, if it fails, then it means
# that the environment is down.
declare -i lv_num_checks
declare -i lv_max_checks
declare -i lv_done
declare -i lv_process_count_curr
declare -i lv_process_count_last
declare -i lv_displayed_process_still_executing
declare -i lv_exit_status
let lv_num_checks=0
let lv_max_checks=200
let lv_done=0
let lv_process_count_curr=0
let lv_process_count_last=0
let lv_displayed_process_still_executing=0
bFirst=1
sq_stat=0
echoLog
echoLog "Shutdown in progress";
echoLog
while [[ $sq_stat == 0 ]]; do
sleep 5
# Count the number of processes
lv_process_count_curr=`cstat 2>/dev/null | grep -v "\-\-\- \-\-\-\-" | grep -v 'pid ppid' | wc -l`
let sq_stat=(lv_process_count_curr '==' 0)
let lv_cnt_check=(lv_process_count_curr '<' lv_process_count_last)
if [ $lv_cnt_check '==' 1 ]; then
let lv_num_checks=0
fi
lv_process_count_last=lv_process_count_curr
if [ $lv_num_checks '==' 0 ]; then
echo -ne "\r# of SQ processes: $lv_process_count_last"
else
echo -n "."
fi
let ++lv_num_checks
if [[ $lv_num_checks -eq 100 ]]; then
date >> $SQMON_LOG
cstat >> $SQMON_LOG
fi
let lv_done=(lv_num_checks '>' lv_max_checks)
if [ $lv_done '==' 1 ]; then
if [ $lv_displayed_process_still_executing '==' 0 ]; then
let lv_displayed_process_still_executing=1
echoLog
echoLog "These are the processes still running. Please check if any application process (such as sqlci) is still running that might hamper shutdown"
cstat | tee -a $SQMON_LOG
let lv_num_checks=0
else
lv_shutdown_status=2
echoLog "`date`"
lv_msg="SQ Shutdown is taking longer than usual and seems to be stalled at $lv_process_count_curr processes. "
echoLog "$lv_msg"
cstat >> $SQMON_LOG
echoLog "Exiting."
let lv_exit_status=1
LogIt "End $script_name $shutdowntype, exit code: $lv_exit_status, $lv_msg"
echo "$lv_exit_status" > $SQSTOP_EXIT_STATUS
exit $lv_exit_status
fi
fi
done
echoLog
shutdownmsg="SQ Shutdown ($shutdowntype) from $PWD Successful"
if [ -e $SQ_PDSH ]; then
L_PDSH="$PDSH $MY_NODES $PDSH_SSH_CMD"
else
L_PDSH=
fi
$L_PDSH rm -f /dev/shm/sem.rms* 2>/dev/null
# Clean up Floating IP bound
if (test -n "${CLUSTERNAME}"); then
# Check whether floating ip is configured.
gv_floating_ip=`grep -i "begin floating_ip" $TRAF_HOME/sql/scripts/sqconfig | grep -v '^#'`
if [ -n "$gv_floating_ip" ]; then
echoLog "Clean up Floating IP..."
cmd_timeout="-u 30"
# Get floating ip addresses.
gv_float_external_ip=`sed -n '/begin floating_ip/,/end floating_ip/p' $TRAF_HOME/sql/scripts/sqconfig | grep -v '^#' | grep external-ip | awk 'BEGIN{FS=";"}{split($3, ary, "="); print ary[2];}'`
gv_float_external_interface=`sed -n '/begin floating_ip/,/end floating_ip/p' $TRAF_HOME/sql/scripts/sqconfig | grep -v '^#' | grep external-ip | awk 'BEGIN{FS=";"}{split($2, ary, "="); print ary[2];}'`
gv_float_internal_ip=`sed -n '/begin floating_ip/,/end floating_ip/p' $TRAF_HOME/sql/scripts/sqconfig | grep -v '^#' | grep internal-ip | awk 'BEGIN{FS=";"}{split($3, ary, "="); print ary[2];}'`
gv_float_internal_interface=`sed -n '/begin floating_ip/,/end floating_ip/p' $TRAF_HOME/sql/scripts/sqconfig | grep -v '^#' | grep internal-ip | awk 'BEGIN{FS=";"}{split($2, ary, "="); print ary[2];}'`
# Check and get all the nodes that the ext/int IP address have been set. And do the unbind.
# Unbind External IP.
for curnode in `pdsh $cmd_timeout $MY_NODES ip addr show | grep $gv_float_external_ip | awk -F' ' '/^.+:[[:space:]]+.*/ {print $1;}' | cut -d':' -f1 | sed '/^$/d'`; do
for myinterface in `pdsh $cmd_timeout -N -w $curnode ip link show | awk -F': ' '/^[0-9]+:.*/ {print $2}'`; do
# Check whether the ext/int ip addresses are bound to any interface already.
# We delete the IP address anyway, no matter which interface and port number it is bound on.
match_ip_interface=`pdsh $cmd_timeout -N -w $curnode ip addr show $myinterface | grep $gv_float_external_ip`
if [ -n "$match_ip_interface" ]; then
unbindip=`echo "$match_ip_interface"|awk '{print $2}'`
unbindlb=`echo "$match_ip_interface"|awk '{print $NF}'`
echoLog "pdsh $cmd_timeout -S -w $curnode sudo ip addr del $unbindip dev $myinterface label $unbindlb"
pdsh $cmd_timeout -S -w $curnode sudo ip addr del $unbindip dev $myinterface label $unbindlb >> $TRAF_HOME/logs/ndcsunbind.log
fi
done
done
# Unbind Internal IP.
for curnode in `pdsh $cmd_timeout $MY_NODES ip addr show | grep $gv_float_internal_ip | awk -F' ' '/^.+:[[:space:]]+.*/ {print $1;}' | cut -d':' -f1 | sed '/^$/d'`; do
for myinterface in `pdsh $cmd_timeout -N -w $curnode ip link show | awk -F': ' '/^[0-9]+:.*/ {print $2}'`; do
# Check whether the ext/int ip addresses are bound to any interface already.
# We delete the IP address anyway, no matter which interface and port number it is bound on.
match_ip_interface=`pdsh $cmd_timeout -N -w $curnode ip addr show $myinterface | grep $gv_float_internal_ip`
if [ -n "$match_ip_interface" ]; then
unbindip=`echo "$match_ip_interface"|awk '{print $2}'`
unbindlb=`echo "$match_ip_interface"|awk '{print $NF}'`
echoLog "pdsh $cmd_timeout -S -w $curnode sudo ip addr del $unbindip dev $myinterface label $unbindlb"
pdsh $cmd_timeout -S -w $curnode sudo ip addr del $unbindip dev $myinterface label $unbindlb >> $TRAF_HOME/logs/ndcsunbind.log
fi
done
done
fi
fi
echoLog "$shutdownmsg"
echoLog "`date`"
let lv_exit_status=0
LogIt "End $script_name $shutdowntype, exit code: $lv_exit_status"
echo "$lv_exit_status" > $SQSTOP_EXIT_STATUS
exit $lv_exit_status