#!/bin/sh
#
# init.d script with LSB support.
#
# Copyright (c) 2007 Javier Fernandez-Sanguino <jfs@debian.org>
#
# This is free software; you may redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2,
# or (at your option) any later version.
#
# This is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License with
# the Debian operating system, in /usr/share/common-licenses/GPL;  if
# not, write to the Free Software Foundation, Inc., 59 Temple Place,
# Suite 330, Boston, MA 02111-1307 USA
#
### BEGIN INIT INFO
# Provides:          mongod
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $network $local_fs $remote_fs
# Should-Start:      $named
# Should-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: An object/document-oriented database
# Description:       Percona Server for MongoDB is a high-performance, open source,
#                    schema-free document-oriented data store that's easy to deploy,
#                    manage and use. It's network accessible, written in C++ and offers
#                    the following features:
#
#                       * Collection oriented storage - easy storage of object-
#                         style data
#                       * Full index support, including on inner objects
#                       * Query profiling
#                       * Replication and fail-over support
#                       * Efficient storage of binary data including large
#                         objects (e.g. videos)
#                       * Automatic partitioning for cloud-level scalability
#
#                    High performance, scalability, and reasonable depth of
#                    functionality are the goals for the project.
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/mongod
DESC=database

NAME=mongod
# Defaults.  Can be overridden by the /etc/default/$NAME
# Other configuration options are located in $CONF file. See here for more:
# http://dochub.mongodb.org/core/configurationoptions
CONF=/etc/mongod.conf
PIDFILEPATH=/var/run/$NAME.pid
PIDDIR=$(dirname $PIDFILEPATH)
ENABLE_MONGOD=yes
MONGO_USER=${MONGO_USER:-mongod}
MONGO_GROUP=${MONGO_GROUP:-mongod}
STARTTIME=1
DIETIME=10
# Time to wait for the server to die, in seconds
# If this value is set too low you might not
# let some servers to die gracefully and
# 'restart' will not work

get_defaults() {
# Include mongodb defaults if available
  if [ -f "/etc/default/$NAME" ] ; then
    . "/etc/default/$NAME"
  fi
}

get_defaults
if test ! -x $DAEMON; then
  echo "Could not find $DAEMON"
  exit 0
fi

if test "x$ENABLE_MONGOD" != "xyes"; then
  exit 0
fi

. /lib/lsb/init-functions

set -e

running_pid() {
# Check if a given process pid's cmdline matches a given name
  pid=$1
  name=$2
  [ -z "$pid" ] && return 1
  [ ! -d /proc/$pid ] &&  return 1
  cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"|head -n 1 |cut -d : -f 1`
# Is this the expected server
  [ "$cmd" != "$name" ] &&  return 1
  return 0
}

running() {
# Check if the process is running looking at /proc
# (works for all users)

# No pidfile, probably no daemon present
  [ ! -f "$PIDFILEPATH" ] && return 1
  pid=`cat $PIDFILEPATH`
  running_pid $pid $DAEMON || return 1
  return 0
}

start_server() {
# Recommended ulimit values for mongod or mongos
# See http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings
#
  ulimit -f unlimited
  ulimit -t unlimited
  ulimit -v unlimited
  ulimit -n 64000
  ulimit -m unlimited

# In dash, ulimit takes -p for maximum user processes
# In bash, it's -u
  if readlink /proc/$$/exe | grep -q dash
  then
    ulimit -p 64000
  else
    ulimit -u 64000
  fi

  /usr/bin/percona-server-mongodb-helper.sh
  get_defaults
# Start the process using the wrapper
  if [ -z "${NUMACTL}" -o ! -f /usr/bin/numactl ]; then
    start-stop-daemon --background --start --quiet --pidfile $PIDFILEPATH \
      --make-pidfile --chuid ${MONGO_USER} \
      --exec ${DAEMON} -- ${OPTIONS} > ${STDOUT} 2> ${STDERR}
    errcode=$?
    return $errcode
  else
    $NUMACTL -- start-stop-daemon --background --start --quiet --pidfile $PIDFILEPATH \
      --make-pidfile --chuid ${MONGO_USER} \
      --exec ${DAEMON} -- ${OPTIONS} > ${STDOUT} 2> ${STDERR}
    errcode=$?
    return $errcode
  fi
}

stop_server() {
# Stop the process using the wrapper
  start-stop-daemon --stop --quiet --pidfile $PIDFILEPATH \
  --retry 300 --user $MONGO_USER
  errcode=$?
	return $errcode
}

force_stop() {
# Force the process to die killing it manually
	[ ! -e "$PIDFILEPATH" ] && return
	if running ; then
		kill -15 $pid
	# Is it really dead?
		sleep "$DIETIME"s
		if running ; then
			kill -9 $pid
			sleep "$DIETIME"s
			if running ; then
				echo "Cannot kill $NAME (pid=$pid)!"
				exit 1
			fi
		fi
	fi
	rm -f $PIDFILEPATH
}


case "$1" in
  start)
    log_daemon_msg "Starting $DESC" "$NAME"
# Check if it's running first
    if running ;  then
      log_progress_msg "apparently already running"
      log_end_msg 0
      exit 0
    fi

    if start_server ; then
# NOTE: Some servers might die some time after they start,
# this code will detect this issue if STARTTIME is set
# to a reasonable value
      [ -n "$STARTTIME" ] && sleep $STARTTIME # Wait some time
      if  running ;  then
# It's ok, the server started and is running
        log_end_msg 0
      else
# It is not running after we did start
        log_end_msg 1
      fi
    else
# Either we could not start it
      log_end_msg 1
    fi
	;;
  stop)
    log_daemon_msg "Stopping $DESC" "$NAME"
      if running ; then
# Only stop the server if we see it running
        errcode=0
        stop_server || errcode=$?
        log_end_msg $errcode
      else
# If it's not running don't do anything
        log_progress_msg "apparently not running"
        log_end_msg 0
        exit 0
      fi
        ;;
  force-stop)
# First try to stop gracefully the program
    $0 stop
    if running; then
# If it's still running try to kill it more forcefully
      log_daemon_msg "Stopping (force) $DESC" "$NAME"
			errcode=0
      force_stop || errcode=$?
      log_end_msg $errcode
    fi
	;;
  restart|force-reload)
    log_daemon_msg "Restarting $DESC" "$NAME"
		errcode=0
    stop_server || errcode=$?
# Wait some sensible amount, some server need this
    [ -n "$DIETIME" ] && sleep $DIETIME
    start_server || errcode=$?
    [ -n "$STARTTIME" ] && sleep $STARTTIME
    running || errcode=$?
    log_end_msg $errcode
	;;
  status)
  log_daemon_msg "Checking status of $DESC" "$NAME"
  if running ;  then
    log_end_msg 0
    log_daemon_msg "mongod service is running"
  else
    log_end_msg 0
    log_daemon_msg "mongod service is apparently not running"
    exit 1
  fi
  ;;
  # MongoDB can't reload its configuration.
  reload)
    log_warning_msg "Reloading $NAME daemon: not implemented, as the daemon"
    log_warning_msg "cannot re-read the config file (use restart)."
  ;;
  *)
	echo "Usage: $NAME {start|stop|force-stop|restart|force-reload|status}" >&2
	exit 1
	;;
esac

exit 0
