#!/bin/bash
#
# $Copyright: Copyright (c) 2017 Veritas Technologies LLC. All rights reserved VT25-0977-2658-84-51-3 $
#
# THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE SECRETS OF VERITAS
# TECHNOLOGIES LLC.  USE, DISCLOSURE OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
# EXPRESS WRITTEN PERMISSION OF VERITAS TECHNOLOGIES LLC.
#
# The Licensed Software and Documentation are deemed to be commercial computer
# software as defined in FAR 12.212 and subject to restricted rights as defined
# in FAR Section 52.227-19 "Commercial Computer Software - Restricted Rights"
# and DFARS 227.7202, Rights in "Commercial Computer Software or Commercial
# Computer Software Documentation," as applicable, and any successor regulations,
# whether delivered by Veritas as on premises or hosted services.  Any use,
# modification, reproduction release, performance, display or disclosure of
# the Licensed Software and Documentation by the U.S. Government shall be
# solely in accordance with the terms of this Agreement.
#
# Currently using udev-post as a requirement because udev-post is supposed to run after all filesystems are mounted.
# Been having some issues to know when (in the boot process) the VxFS filesystems are available.
# We may wish to have kdump running before starting vpfsd
# Currently tell chkconfig to use a value of 49 because logstash always seems to use 50 (I must be overlooking something)
### BEGIN INIT INFO
# Provides:          pdde-storage
# Required-Start:    $network $udev-post
# Required-Stop:     $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Manages PDDE storage
# Description:       A script to manage spoold and spad and vpfsd processes.
### END INIT INFO
#
# chkconfig: 2345 78 00
# description: Starts and stops the PDDE storage daemons (spoold & spad) and mountpoints (vpfs_mounts)
#	       #
# pidfile: /var/run/spad.pid
# pidfile: /var/run/spoold.pid
# config:  /etc/pdregistry.cfg

# Source function library.
. /etc/rc.d/init.d/functions

# Avoid using root's TMPDIR
unset TMPDIR

PDDE_DIR="/usr/openv/pdde"
VPFS_DIR="${PDDE_DIR}/vpfs"
STORAGE_SERVICE_DIR="${VPFS_DIR}/etc/init.d"
STORAGE_SERVICE_NAMES=("vpfs_mounts" "spoold" "spad")
LOGFILE="/var/log/pdde-storage.log"
PDREG="/etc/pdregistry.cfg"
VPFS_MONITOR_CRON="/etc/cron.d/vpfs_monitor.cron"

touch /var/lock/subsys/pdde-storage

# Check that pdregistry.cfg exists.
#if [ ! -f "$PDREG" ];  then
    #echo "PDDE storage was not installed; $PDREG does not exist"
#
    ## if the request is status, then exit with unknown error (4), otherwise 5 (not installed)
    #[ "$1" == "status" ] || exit 5
    #exit 4
#fi

# Check that the service files (aka local init scripts) exist and are executable
for service in "${STORAGE_SERVICE_NAMES[@]}"
do
    if [ "$service" == "spad" -o "$service" == "spoold" ];then
        continue;
    fi
    if [ ! -x "$STORAGE_SERVICE_DIR/$service" ]; then
        echo "The file $STORAGE_SERVICE_DIR/$service does not exist or it is not executable"

        # if the request is status, then exit with unknown error (4), otherwise 5 (not installed)
        [ "$1" == "status" ] || exit 5
        exit 4
    fi
done

# If exists, then check that pdregistry.cfg configured.
if [ ! -L "$PDREG" ];  then
    echo "PDDE storage was not configured"

    # if the request is status, then exit with unknown error (4), otherwise 6 (not configured)
    [ "$1" == "status" ] || exit 6
    exit 4
fi

cat_tempfile() {
    cat "$1" | tee -a $LOGFILE
}

echo_and_log() {
    echo "$@"
    echo "`date` $@" >> $LOGFILE
}

echo_and_log_no_newline() {
    echo -n "$@"
    echo -n "`date` $@" >> $LOGFILE
}

my_echo_success() {
    [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
    echo -n "[" | tee -a $LOGFILE
    [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS
    echo -n $"  OK  " | tee -a $LOGFILE
    [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
    echo "]" | tee -a $LOGFILE
    return 0
}

my_echo_failure() {
    [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
    echo -n "[" | tee -a $LOGFILE
    [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
    echo -n $"FAILED" | tee -a $LOGFILE
    [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
    echo "]" | tee -a $LOGFILE
    return 1
}

my_echo_warn_status() {
    [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
    echo -n "[" | tee -a $LOGFILE
    [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
    echo -n $"$1" | tee -a $LOGFILE
    [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
    echo "]" | tee -a $LOGFILE
    return 1
}

start_all() {
    RV=0
    echo_and_log "Starting PDDE storage services"
    for (( idx=${#STORAGE_SERVICE_NAMES[@]}-1 ; idx>=0 ; idx-- )) ; do
        service=${STORAGE_SERVICE_NAMES[idx]}
        SRV_RV=0
        echo_and_log_no_newline "Starting service $service..."
        if [ "$service" == "spad" -o "$service" == "spoold" ]; then
            ${PDDE_DIR}/pdconfigure/pdde $service start > tempfile 2>&1 || SRV_RV=$?
        else
            "$STORAGE_SERVICE_DIR/$service" start > tempfile 2>&1 || SRV_RV=$?
        fi
        if [ "$SRV_RV" -ne 0 ]; then
            my_echo_failure    
            echo_and_log
            cat_tempfile tempfile        
            RV="$SRV_RV"
        else
            my_echo_success    
        fi
    done
    return $RV
}

stop_all() {
    RV=0
    echo_and_log "Stopping PDDE storage services"
    for service in "${STORAGE_SERVICE_NAMES[@]}"
    do
        echo_and_log_no_newline "Stopping service $service..."
        SRV_RV=0
        # the following is not "standard", but we want to not have such a long wait with force stop
        if [ "$service" == "spad" -o "$service" == "spoold" ]; then
            ${PDDE_DIR}/pdconfigure/pdde $service stop > tempfile 2>&1 || SRV_RV=$?
        else
            "$STORAGE_SERVICE_DIR/$service" stop "$@" > tempfile 2>&1 || SRV_RV=$?
        fi
        if [ "$SRV_RV" -ne 0 ]; then
            my_echo_failure    
            echo_and_log
            cat_tempfile tempfile        
            echo_and_log
            RV="$SRV_RV"
        else
            my_echo_success    
            echo_and_log
        fi
    done
    return $RV
}

pddestatus() {
    NAME=$1
    status -p /var/run/${NAME}.pid $NAME
    ST_RV=$?
    if [ "$ST_RV" -ne 0 ]; then 
        return $ST_RV
    fi

    if [ "$srv" == "spoold" ];  then
        if [ `id -u` -uq 0 ]; then
            ${PDDE_DIR}/pdcr/bin/crcontrol --dsstat 2>/dev/null
        else
            sudo ${PDDE_DIR}/pdcr/bin/crcontrol --dsstat 2>/dev/null
        fi
    fi

    DSSTAT_RV=$?
    if [ "$DSSTAT_RV" -ne 0 ]; then
        echo "$NAME is in startup mode"
        return 4;
    fi
    return 0;
}

status_all() {
    # this is kinda messy; don't currently depend on accurate status values other than 0 or 3 if they really are all running
    # or are all stopped (respectively)
    RV=0
    for service in "${STORAGE_SERVICE_NAMES[@]}"
    do
        echo_and_log_no_newline "$service status..."
        SRV_RV=0
        if [ "$service" == "spad" -o "$service" == "spoold" ]; then
            pddestatus $service > tempfile 2>&1 || SRV_RV=$?
        else
            "$STORAGE_SERVICE_DIR/$service" status > tempfile 2>&1 || SRV_RV=$?
        fi
        if [ "$SRV_RV" -eq 0 ]; then
            my_echo_success    
            echo_and_log
        elif [ "$SRV_RV" -eq 3 ]; then
            my_echo_warn_status "STOPPED"
            echo_and_log
            # Only set the return value if it is zero, otherwise we should defer to other status
            [ "$RV" -ne 0 ] || RV="$SRV_RV"
        elif [ "$SRV_RV" -eq 4 ]; then
            my_echo_warn_status "STARTUP MODE"
            echo_and_log
            if [ "$RV" -eq 0 ] || [ "$RV" -eq 3 ]; then
                RV="$SRV_RV"
            fi
        else
            my_echo_failure    
            echo_and_log
            cat_tempfile tempfile        
            echo_and_log
            RV="$SRV_RV"
        fi
    done
    return $RV
}

restart_all() {
    stop_all
    start_all
}

# only use this option if you don't care about data or about how long it takes to restart vpfsd later
force_stop() {
    # give vpfsd only 10 seconds to stop -- we don't want to wait a long time with force stop
    stop_all 10 1

    RV=0
    if [ ! -f "/etc/velocity-release" ]; then
        echo_and_log "This is not Velocity ISO, force-stopping vpfs_mounts but ignore result"
        "$STORAGE_SERVICE_DIR/vpfs_mounts" force-stop > tempfile 2>&1
    else
        "$STORAGE_SERVICE_DIR/vpfs_mounts" force-stop > tempfile 2>&1 || RV=$?
    fi
    # If vpfsd failed to stop normally and was force-stopped, then we need to try to stop spoold and spad again
    ${PDDE_DIR}/pdconfigure/pdde spoold stop > tempfile 2>&1 || RV=$?
    ${PDDE_DIR}/pdconfigure/pdde spad stop > tempfile 2>&1 || RV=$?
    return $RV
}

case "$1" in
  start)
  	start_all
	;;
  stop)
  	stop_all
	;;
  restart)
  	restart_all
	;;
  status)
  	status_all
	;;
  force-stop)
        force_stop
        ;;
  reload)
	echo $"Usage: $0 {start|stop|restart|status}"
	exit 3
	;;
  *)
	echo $"Usage: $0 {start|stop|restart|status}"
	exit 2
esac

exit $?
