#!/bin/bash
# Copyright (c) 1995-2002 SuSE Linux AG Nuernberg, Germany.
#
# Author: Lenz Grimmer <feedback@suse.de>
#
# /etc/init.d/mysql
#
#   and its symbolic link
#
# /usr/sbin/rcmysql
#
### BEGIN INIT INFO
# Provides:       mysql
# Required-Start: $network $remote_fs
# Required-Stop:
# Default-Start:  2 3 5
# Default-Stop:
# Description:    Start the MySQL database server
### END INIT INFO

# Shell functions sourced from /etc/rc.status:
#      rc_check         check and set local and overall rc status
#      rc_status        check and set local and overall rc status
#      rc_status -v     ditto but be verbose in local rc status
#      rc_status -v -r  ditto and clear the local rc status
#      rc_failed        set local and overall rc status to failed
#      rc_failed <num>  set local and overall rc status to <num>
#      rc_reset         clear local rc status (overall remains)
#      rc_exit          exit appropriate to overall rc status
. /etc/rc.status

# First reset status of this service
rc_reset

# Return values acc. to LSB for all commands but status:
# 0 - success
# 1 - generic or unspecified error
# 2 - invalid or excess argument(s)
# 3 - unimplemented feature (e.g. "reload")
# 4 - insufficient privilege
# 5 - program is not installed
# 6 - program is not configured
# 7 - program is not running
# 
# Note that starting an already running service, stopping
# or restarting a not-running service as well as the restart
# with force-reload (in case signalling is not supported) are
# considered a success.

# Test, if mysqld or mysql-max actually exist
unset MYSQLD
# use mysqld-debug only if explicitly requested (TODO: sysconfig variable?)
if test "$MYSQLD_DEBUG" = yes -a -x /usr/sbin/mysqld-debug
then
	MYSQLD=/usr/sbin/mysqld-debug
elif test -x /usr/sbin/mysqld-max
then
        MYSQLD=/usr/sbin/mysqld-max
elif test -x /usr/sbin/mysqld
then
        MYSQLD=/usr/sbin/mysqld
fi
test "$MYSQLD" || { echo "Nor /usr/sbin/mysqld nor /usr/sbin/mysqld-max exists"; rc_failed 5; rc_status -v; rc_exit; }

# The following section has been taken from
# the original MySQL init script
basedir=/usr
datadir=/var/lib/mysql
mysql_daemon_user=mysql
mysql_daemon_group=mysql
pid_file=/var/lib/mysql/mysqld.pid
socket=/var/lib/mysql/mysql.sock
print_defaults=/usr/bin/my_print_defaults
export TMPDIR=/var/lib/mysql/.tmp

mode=$1 # start or stop

parse_arguments() {
  for arg do
    case "$arg" in
      --basedir=*)  basedir=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
      --datadir=*)  datadir=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
      --pid-file=*) pid_file=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
	  --socket=*)   socket=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
    esac
  done
}

wait_for_socket()
{
	local i
	for((i=0; i<50; i++)); do
		sleep 0.2
		test -S $1 && i='' && break
	done
	test -z "$i" || return 1
	return 0
}

# Don't run killproc -TERM, as it could send a SIGKILL as well, possibly
# resulting in database corruption. Run kill -TERM manually instead,  wait
# approximately 300 seconds and fail if mysql doesn't respond. This will at
# least prevent the SIGKILL when doing 'rcmysql stop' manually. During system
# shutdown, we are out of luck...
# See https://bugzilla.novell.com/show_bug.cgi?id=223209
kill_mysql ()
{
	local pid exe
	test -e "$pid_file" || return 7  # not running
	pid=`cat "$pid_file"` || return 4  # insufficient privileges
	if ! test -e /proc/version; then
		mount -n -t proc proc /proc
		test -e /proc/version || return 100
	fi
	test -L "/proc/$pid/exe" || return 7
	exe=`readlink "/proc/$pid/exe"` || return 4
	test "$exe" = "$MYSQLD" || return 7
	kill -STOP "$pid"
	kill -TERM "$pid" || return 4 # suboptimal
	kill -CONT "$pid"
	for i in `seq 3000`; do
		# mysqld removes its pid file
		test -e "$pid_file" || return 0
		LC_ALL=C sleep 0.1
	done
	test -e "$pid_file" || return 0
	return 1
}

parse_arguments `$print_defaults $defaults mysqld mysql_server`

# Safeguard (relative paths, core dumps..)
cd $basedir

case "$1" in
    start)
	# exit gracefully, if we are already running
	$0 status >/dev/null && echo -n "Starting service MySQL " && \
	rc_status -v && rc_exit

	# Test, if safe_mysqld actually exists
	SAFE_MYSQLD=/usr/bin/mysqld_safe
	test -x $SAFE_MYSQLD || { echo "$SAFE_MYSQLD does not exist "; rc_failed 5; rc_status -v; rc_exit; }
	debug_flags=""
	if test "$MYSQLD_DEBUG" = yes; then
		# add --log, --core-file and --debug
		# but only if not already set in my.cnf
		if ! $print_defaults mysqld | \
			grep -q -e '--log$' -e '--log[[:blank:]=]'
		then
			debug_flags="--log=$datadir/mysqld-query.log"
		fi
		if ! $print_defaults mysqld | grep -q -e '^--debug\>' &&
			test "$MYSQLD" = /usr/sbin/mysqld-debug
		then
			debug_flags="$debug_flags --debug=d:t:F:L:o,$datadir/mysqld.trace"
		fi
		if ! $print_defaults mysqld | grep -q -e '^--core-file\>'
		then
			debug_flags="$debug_flags --core-file"
		fi
	fi

	# check for ISAM tables
	tables=`find $datadir -name '*.ISM' | sed "s@$datadir/*@@; s@.ISM@@; s@/@.@;"`
	if test "$tables" ; then
		echo
		echo "Some tables still use ISAM format, which is NO LONGER SUPPORTED"
		echo "since mysql 5.0. To use these tables, you would need to open them"
		echo "from an older mysql server and convert to something better (eg. MyISAM)."
		echo
		echo "Tables using ISAM are: "
		echo "  $tables "
		echo
	fi

	# We assume a fresh install if the directory $datadir/mysql
	# does not exist and create the privilege database
	if ! test -d $datadir/mysql; then
		echo "Creating MySQL privilege database... "
		mysql_install_db --user=$mysql_daemon_user --datadir=$datadir || rc_failed
	fi
	# Run mysql_upgrade on every package install/upgrade. Not allways
	# necessary, but doesn't do any harm.
	if test -f $datadir/.run-mysql_upgrade ; then
		echo "Updating MySQL privilege database... "
		# instead of running mysqld --bootstrap, which wouldn't allow
		# us to run mysql_upgrade, we start a full-featured server with
		# --skip-grant-tables and restict access to it by unix
		# permissions of the named socket
		protected=$datadir/.protected
		chown $mysql_daemon_user:$mysql_daemon_group $protected
		chmod 700 $protected
		$SAFE_MYSQLD \
			--mysqld=${MYSQLD#/usr/sbin/} \
			$debug_flags \
			--skip-grant-tables \
			--skip-networking \
			--user=$mysql_daemon_user \
			--pid-file=$protected/mysqld.pid \
			--socket=$protected/mysql.sock \
			--group=$mysql_daemon_group &>/dev/null &
		wait_for_socket $protected/mysql.sock || rc_failed
		/usr/bin/mysql_upgrade \
			--basedir=$basedir \
			--socket=$protected/mysql.sock ||\
			rc_failed
		killproc -p $protected/mysqld.pid -TERM $MYSQLD
		# Fix ownerships and permissions for $datadir
		chmod 755 $datadir
		chown -R $mysql_daemon_user:$mysql_daemon_group $datadir
		rm -f $datadir/.run-mysql_upgrade \
		$datadir/{update-stamp-*,mysql/stamp-4.1} # used in the past
	if test -f $datadir/mysql/stamp-4.1 ; then
		rm $datadir/mysql/stamp-4.1
	fi

	fi

	echo -n "Starting service MySQL "

	$SAFE_MYSQLD \
		--mysqld=${MYSQLD#/usr/sbin/} \
		$debug_flags \
		--user=$mysql_daemon_user \
		--pid-file=$pid_file \
		--socket=$socket \
		--datadir=$datadir &>/dev/null &

	wait_for_socket $socket || rc_failed

	# Rmember status and be verbose
	rc_status -v
	;;

    stop)
	echo -n "Shutting down service MySQL "
	kill_mysql

	# Remember status and be verbose
	rc_status -v
	;;

    try-restart)
	## Stop the service and if this succeeds (i.e. the 
	## service was running before), start it again.
	## Note: try-restart is not (yet) part of LSB (as of 0.7.5)
	$0 status >/dev/null &&  $0 restart

	# Remember status and be quiet
	rc_status
	;;

    restart|force-reload)
	echo "Restarting service MySQL "
	$0 stop
	$0 start

	rc_status
	;;

	reload)
	echo -n "Reloading service MySQL "
	killproc -p $pid_file -HUP $MYSQLD
	touch $pid_file
	rc_status -v
	;;
	
    check|status)
	echo -n "Checking for service MySQL: "
	# NOTE: not using checkproc, because it wrongly returns success when
	# the pid file does not exist (fixed in 10.3 and newer)
	if ! [ -f $pid_file ]; then
		# not running
		rc_failed 3
	elif [ -s $pid_file -a -d /proc/$(<$pid_file) ]; then
		# running
		:
	else
		# stale pid file
		rc_failed 1
		#rm -f $pid_file
	fi
	rc_status -v
	;;

    *)
	echo "Usage: $0 {start|stop|status|reload|restart|try-restart|force-reload}"
	exit 1
	;;
esac
rc_exit

# vim: ft=sh
