#! /bin/bash
#
# NOTE TO SYSTEM ADMINISTRATORS #
# To stop postgresql running, use the update-rc.d facility, or file-rc
# from the file-rc package.

export PATH=$PATH:/sbin:/usr/sbin:/bin:/usr/bin

PREFIX=/usr/lib/postgresql
POSTMASTER=$PREFIX/bin/postmaster
PG_CTL=$PREFIX/bin/pg_ctl
PG_AUTOVACUUM=$PREFIX/bin/pg_autovacuum
PG_STARTUP=$PREFIX/bin/postgresql-startup
PGPORT=$(grep -si '^port *=' /etc/postgresql/postgresql.conf | cut -f2 -d=)

# Make sure the log directory and file exist with the correct ownership
assert_logfile() {
    LOGFILE=${POSTGRES_LOG:-/var/log/postgresql/postgres.log}
    LOGDIR="`dirname \"$LOGFILE\"`"

    [ -d "$LOGDIR" ] || install -d -m 2775 -o root -g postgres "$LOGDIR"

    if [ ! -e "$LOGFILE" ]; then
        touch "$LOGFILE"
        chown postgres.postgres "$LOGFILE"
        chmod 640 "$LOGFILE"
    fi
}

# Make sure the socket directory exist with the correct ownership
assert_socketdir() {
    SOCKETDIR=/var/run/postgresql

    if [ ! -d "$SOCKETDIR" ]; then
	if [ ! -d /var/run ]; then
	    echo "Error: /var/run does not exist. Aborting." >&2
	    exit 1
	fi
	install -d -m 2775 -o postgres -g postgres "$SOCKETDIR"
    fi
}

startup () {
	echo -n " postmaster"
        assert_logfile
	assert_socketdir

        # execute startup checks that require root privileges and cannot be
        # done in postgresql-startup
        /usr/share/postgresql/startup-checks-root.sh

        ERRMSG=$(/sbin/start-stop-daemon --pidfile $PGDATA/postmaster.pid --oknodo --chuid postgres --startas $PG_STARTUP --start 2>&1)

	if [ $? != 0 ]; then
	    echo "(FAILED)"
	    [ "$ERRMSG" ] && echo "ERROR: $ERRMSG" >&2 || true
	    exit 1
	fi

        [ "$ERRMSG" ] && echo -n " ($ERRMSG)" >&2 || true

	autovacuum_start
}

stop () {
	autovacuum_stop
        echo -n " postmaster"
        start-stop-daemon -c postgres --start --exec $PG_CTL -- stop -s -w -m fast

	# try harder if "fast" mode does not work
	if [ -f "$PGDATA/postmaster.pid" ]; then
	    echo -n "(does not shutdown gracefully, now stopping immediately)"
            start-stop-daemon -c postgres --start --exec $PG_CTL -- stop -s -w -m immediate
	fi

	# if that still not helps, use the big hammer
	if [ -f "$PGDATA/postmaster.pid" ]; then
	    echo -n "(does not shutdown, killing the process)"
	    PID=`head -n 1 "$PGDATA/postmaster.pid"`
	    if [ "$PID" ]; then
		kill -9 "$PID" || true
		rm -f "$PGDATA/postmaster.pid"
	    fi
	fi
}

autovacuum_start() {
	# See if we should start autovacuuming
	if [ -x $PG_AUTOVACUUM ]
	then
	    case "$AUTOVACUUM" in yes | Yes | YES | y | Y | on | ON | True | true | TRUE | 1)
		OPTS="-D -p ${PGPORT:=5432}"
		if [ -n "$AVAC_DEBUG" ]
		then
			OPTS="$OPTS -d $AVAC_DEBUG"
		fi
		if [ -n "$AVAC_SLEEP_BASE" ]
		then
			OPTS="$OPTS -s $AVAC_SLEEP_BASE"
		fi
		if [ -n "$AVAC_SLEEP_SCALE" ]
		then
			OPTS="$OPTS -S $AVAC_SLEEP_SCALE"
		fi
		if [ -n "$AVAC_VAC_BASE" ]
		then
			OPTS="$OPTS -v $AVAC_VAC_BASE"
		fi
		if [ -n "$AVAC_VAC_SCALE" ]
		then
			OPTS="$OPTS -V $AVAC_VAC_SCALE"
		fi
		if [ -n "$AVAC_ANAL_BASE" ]
		then
			OPTS="$OPTS -a $AVAC_ANAL_BASE"
		fi
		if [ -n "$AVAC_ANAL_SCALE" ]
		then
			OPTS="$OPTS -A $AVAC_ANAL_SCALE"
		fi
		if [ -z "$AVAC_LOG" ]
		then
			AVAC_LOG=/var/log/postgresql/autovacuum_log
		fi
		OPTS="$OPTS -L $AVAC_LOG"
		echo -n " autovacuum"
		/sbin/start-stop-daemon --oknodo --chuid postgres --exec $PG_AUTOVACUUM --start -- $OPTS
		if [ $? != 0 ]; then
		    echo "(FAILED)"
		    exit 1
		fi
		;;
	    esac
	fi
}

autovacuum_stop() {
	if [ -f $PGDATA/autovacuum.pid ]
	then
		echo -n " autovacuum"
		start-stop-daemon --stop --user postgres --name pg_autovacuum
		rm $PGDATA/autovacuum.pid
	fi
}

if [ ! $EUID -eq 0 ]
then
	echo $0 needs to be run by root.
	exit 1
fi

[ -x $POSTMASTER ] || exit

if [ -r /etc/postgresql/postmaster.conf ]
then
	. /etc/postgresql/postmaster.conf
else
	echo "/etc/postgresql/postmaster.conf is missing; cannot start postgresql"
	exit 1
fi
PGDATA=${POSTGRES_DATA:-/var/lib/postgres/data}
export PGDATA

## Use of $PG_CTL to stop the postmaster:
## we use $PG_CTL stop -m fast, which will abort and roll back any current
## transactions.  Don't use -immediate, because it's equivalent to 
## kill -9.  Don't use -smart because it waits for people to disconnect
## and we want to force them off when we are shutting down or else the 
## system itself will do a kill -9 to get rid of us.

case "$1" in
    start)
        echo -n "Starting PostgreSQL database server:"
        startup
	echo "."
        ;;
    stop)
        echo -n "Stopping PostgreSQL database server:"
	stop
	echo "."
        ;;
    restart)
	$0 stop
	$0 start
        ;;
    autovac-restart)
	if [ -f $PGDATA/autovacuum.pid ]
	then
		autovacuum_stop
		echo " stopped"
	else
		echo pg_autovacuum not running
	fi
	autovacuum_start
	echo " started"
        ;;
    autovac-start)
	if [ -f $PGDATA/autovacuum.pid ]
	then
		echo pg_autovacuum is already running
	else
		autovacuum_start
		echo " started"
	fi
	;;
    autovac-stop)
	if [ -f $PGDATA/autovacuum.pid ]
	then
    		autovacuum_stop
		echo " stopped"
	else
		echo pg_autovacuum not running
	fi
	;;
    force-reload | reload)
        start-stop-daemon -c postgres --start --exec $PG_CTL -- reload -D ${PGDATA}
        ;;
    status)
	start-stop-daemon -c postgres --start --exec $PG_CTL -- status
	;;
    *)
        echo "Usage: /etc/init.d/postgresql {start|stop|autovac-start|autovac-stop|restart|autovac-restart|reload|force-reload|status}"
        exit 1
        ;;
esac

exit 0

