#!/bin/bash
#
# rh-postgresql95-postgresql
#
# This is the init script for starting up the PostgreSQL server.
#
# This script is slightly unusual in that the name of the daemon (postmaster)
# is not the same as the name of the subsystem (postgresql)
#
# chkconfig: - 64 36
# description: PostgreSQL database server.
# processname: postmaster
# pidfile: /var/run/postmaster.PORT.pid

### BEGIN INIT INFO
# Provides: rh-postgresql95-postgresql
# Required-Start: $local_fs $remote_fs $network $named $syslog $time
# Required-Stop: $local_fs $remote_fs $network $named $syslog $time
# Short-Description: start and stop PostgreSQL 9.5.4 server
# Description: PostgreSQL database server
### END INIT INFO

# PGVERSION is the full package version, e.g., 9.0.2
# Note: the specfile inserts the correct value during package build
PGVERSION=9.5.4

# PGMAJORVERSION is major version, e.g., 9.0 (this should match PG_VERSION)
PGMAJORVERSION=9.5

# PGDOCDIR is the directory containing the package's documentation
# Note: the specfile inserts the correct value during package build

# Distribution README file
README_DIST=/opt/rh/rh-postgresql95/root/usr/share/doc/rh-postgresql95-postgresql-9.5.4/README.rpm-dist

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

# Get network config.
. /etc/sysconfig/network

# postgresql-setup library
. "/opt/rh/rh-postgresql95/root/usr/share/postgresql-setup/library.sh"

source scl_source enable rh-postgresql95 ;

# Find the name of the script
NAME=`basename $0`
if [ ${NAME:0:1} = "S" -o ${NAME:0:1} = "K" ]
then
	NAME=${NAME:3}
fi

# Set defaults for configuration variables
PGENGINE=/opt/rh/rh-postgresql95/root/usr/bin

# Only default system service has default PGDATA set.  This allows us to catch
# admin's mistake of not creating /etc/sysconfig/psql/$NAME configuration file
# and just hard/symlinking default init script.  That way we can avoid (inside
# postgresql-check-db-dir) runnnig "secondary" server against "default" data
# directory.
if test "rh-postgresql95-postgresql" = "$NAME"; then
    PGDATA=/opt/rh/rh-postgresql95/root/var/lib/pgsql/data
fi

PGLOG=/var/lib/pgsql/pgstartup-rh-postgresql95-postgresql.log

# Value to set as postmaster process's oom_adj
PG_OOM_ADJ=-17

# Override defaults from /etc/sysconfig/pgsql if file is present
[ -f /etc/sysconfig/pgsql/${NAME} ] && . /etc/sysconfig/pgsql/${NAME}

export PGDATA
export PGPORT
export PGSTARTTIMEOUT
export PGSCLS

lockfile="/var/lock/subsys/${NAME}"

# Ideally, we should use $PGDATA/postmaster.pid.  It apparently works, but to
# be honest I'm not sure about consequences.  Most probably 'service status'
# would not work for non-root/non-postgres users.  TODO?
pidfile="/var/run/${NAME}.pid"

script_result=0

start()
{
	[ -x "$PGENGINE/postgres" ] || exit 5

	PSQL_START=$"Starting ${NAME} service: "

	# Make sure startup-time log file is valid
	if [ ! -e "$PGLOG" -a ! -h "$PGLOG" ]
	then
		touch "$PGLOG" || exit 4
		chown postgres:postgres "$PGLOG"
		chmod go-rwx "$PGLOG"
		[ -x /sbin/restorecon ] && /sbin/restorecon "$PGLOG"
	fi

    /opt/rh/rh-postgresql95/root/usr/libexec/postgresql-check-db-dir "$NAME" || {
        echo_failure
        echo
        exit 1
    }

	echo -n "$PSQL_START"
	test x"$PG_OOM_ADJ" != x && echo "$PG_OOM_ADJ" > /proc/self/oom_adj

    # Note that this does not fail/exit the 'service start' if the postmaster
    # is already running.  We should probably 'status' first and start only if
    # postmaster is down.  This just unnecessarily wastes time and generates
    # too much (false) rush in $PGLOG.
    #
    # The maximum waiting time PGSTARTTIMEOUT is set to 30 second to not hold
    # the system too long.  See `man pg_ctl & -w option`.  This is not issue in
    # case of systemd.
    #
    # PGSTARTWAIT turns on waiting for server to become fully ready to accept
    # connection.

    # clean the variable if not set to 1
    test x1 != x"$PGSTARTWAIT" && PGSTARTWAIT=

    # success if already started (pg_ctl -w could fail later)
    status -p "$pidfile" postgres &>/dev/null && {
        success "$PSQL_START"
        echo
        exit 0
    }

    run_cmd_as_dbadmin "\
            PGSCLS=$(printf %q "$PGSCLS") \
            PGOPTS=$(printf %q "$PGOPTS") \
            PGPORT=$(printf %q "$PGPORT") \
            /opt/rh/rh-postgresql95/root/usr/libexec/postgresql-ctl start -D $(printf %q "$PGDATA") -s \
                ${PGSTARTWAIT:+-w -t ${PGSTARTTIMEOUT:-30}}" \
            "$PGLOG" "$PGLOG"

    if test $? -ne 0; then
        failure "$PSQL_START"
        echo
        script_result=1
        return
    fi

    # pg_ctl succeed, now recognize the pid number

    pid=
    if test x1 != x"$PGSTARTWAIT" ; then
        # We don't wait for the full postgresql server start.  In this case,
        # wait for pidfile creation only.  This should take _very_ short time in
        # most cases but on highly overloaded machines - several seconds may
        # not be enough.  See rhbz#800534 and rhbz#1188942 for more info.
        # Original waiting implementation by Jozef Mlích.

        decounter=${PGSTARTTIMEOUT:-30}
        while test "$decounter" -ge 0; do
            pid=$(head -n 1 "$PGDATA/postmaster.pid" 2>/dev/null)

            test "x$pid" != x && break

            # pidfile does not exist yet, wait a sec more
            decounter=$(( decounter - 1 ))
            sleep 1
        done
    else
        # pg_ctl -w succeed, pidfile must exist if everything is OK
        pid=$(head -n 1 "$PGDATA/postmaster.pid" 2>/dev/null)
    fi

    if test "x$pid" != x; then
        success "$PSQL_START"
        touch "$lockfile"
        echo "$pid" > "$pidfile"
        echo
    else
        failure "$PSQL_START"
        echo
        script_result=1
    fi
}

stop()
{
	echo -n $"Stopping ${NAME} service: "
	if [ -e "$lockfile" ]
	then
        run_cmd_as_dbadmin \
                "$PGENGINE/pg_ctl stop -D '$PGDATA' -s -m fast" \
                /dev/null /dev/null
	    ret=$?
	    if [ $ret -eq 0 ]
	    then
		echo_success
		rm -f "$pidfile"
		rm -f "$lockfile"
	    else
		echo_failure
		script_result=1
	    fi
	else
	    # not running; per LSB standards this is "ok"
	    echo_success
	fi
	echo
}

restart(){
    stop
    start
}

condrestart(){
    [ -e "$lockfile" ] && restart || :
}

reload()
{
    run_cmd_as_dbadmin "$PGENGINE/pg_ctl reload -D '$PGDATA' -s" \
            /dev/null /dev/null
}

__single_comand()
{
    local msg="$1"
    shift
    echo $"$msg ($@)"
    "$@" && success || failure || script_result=1
    echo
}


initdb()
{
    __single_comand $"Initializing database" \
        /opt/rh/rh-postgresql95/root/usr/bin/postgresql-setup --initdb --unit "$NAME" "$@"
}


upgrade()
{
    __single_comand $"Upgrading database" \
        /opt/rh/rh-postgresql95/root/usr/bin/postgresql-setup --upgrade --unit "$NAME" "$@"
}


# See how we were called.
case "$1" in
  start)
	start
	;;
  stop)
	stop
	;;
  status)
	status -p "$pidfile" postgres
	script_result=$?
	;;
  restart)
	restart
	;;
  condrestart|try-restart)
	condrestart
	;;
  reload)
	reload
	;;
  force-reload)
	restart
	;;
  initdb)
    shift
    initdb "$@"
    ;;
  upgrade)
    shift
    upgrade "$@"
    ;;
  *)
	echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|initdb|upgrade}"
	exit 2
esac

exit $script_result
