File openvpn.init of Package openvpn

#! /bin/sh
# Copyright (c) 2003 SuSE Linux AG
# Copyright (c) 2004-2009 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# Author: Peter Poeml <poeml@suse.de>
#         Marius Tomaschewski <mt@suse.de>
#
# inspired by the init script contributed to the OpenVPN project by 
# Douglas Keller <doug@voidstar.dyndns.org>
#
# /etc/init.d/openvpn
#   and its symbolic link
# /usr/sbin/rcopenvpn
#
### BEGIN INIT INFO
# Provides:			openvpn
# Required-Start:		$local_fs $remote_fs $network
# Should-Start:			$syslog $time $named network-remotefs
# Required-Stop:		$local_fs $remote_fs $network
# Should-Stop:			$syslog $time $named network-remotefs
# Default-Start:		3 5
# Default-Stop:			0 1 2 6
# Short-Description:		OpenVPN tunnel
# Description:			Start OpenVPN tunnel
### END INIT INFO

test -s /etc/sysconfig/openvpn && \
      . /etc/sysconfig/openvpn

DAEMON="OpenVPN"
openvpn=/usr/sbin/openvpn
confdir=/etc/openvpn
piddir=/var/run/openvpn
test -d $piddir || mkdir $piddir

test -x $openvpn || {
	echo 1>&2 "$openvpn not installed"
	if test "$1" == "stop" ; then exit 0 ; else exit 5 ; fi
}

# 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><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.

shopt -s nullglob

action="$1" ; shift
config="$1" ; shift

systemd_cgroup_dir="/sys/fs/cgroup/systemd"
openvpn_cgroup_dir="${systemd_cgroup_dir}/system/openvpn.service"

join_openvpn_service_cgroup()
{
	local pid dummy

	# when the systemd cgroup mountpoint does not exists,
	# assume we run unter systemv init -> nothing to do.
	/bin/mountpoint -q "${systemd_cgroup_dir}" || return 0

	# create the openvpn.service cgroup when needed
	if test ! -d "${openvpn_cgroup_dir}" ; then
		/bin/mkdir -p "${openvpn_cgroup_dir}" || return 1
	fi

	# check if the openvpn.service cgroup task list exists
	if test -f "${openvpn_cgroup_dir}/tasks" ; then
		# when we're already a member, all is done
		while read pid dummy ; do
			test "$pid" = "$$" && return 0
		done < "${openvpn_cgroup_dir}/tasks"

		# otherwise join the openvpn.service cgroup
		echo "$$" > "${openvpn_cgroup_dir}/tasks" && return 0
	fi
	return 1
}

autostart_filter()
{
	test "x$config" != "x"           && return 0
	test "x$OPENVPN_AUTOSTART" = "x" && return 0
	for n in ${OPENVPN_AUTOSTART} ; do
		test "x$n" = "x$1" && return 0
	done
	return 1
}

case "$action" in
    start)
	join_openvpn_service_cgroup

	/sbin/modprobe tun &>/dev/null

	name=""
	for conf in $confdir/${config:-*}.conf ; do
		test -f "$conf" || continue
		name=$(basename "${conf%%.conf}")
		autostart_filter "$name" || continue
		pidfile="$piddir/${name}.pid"

		echo -n "Starting $DAEMON [$name] "

		if [ -f "$pidfile" ]; then
		    killproc -p "$pidfile" -USR2 $openvpn
		    ret=$?
		    case $ret in
		      7) # not running, remove pid and start
		         echo -n "(removed stale pid file) "      ;
		         rm -f "$pidfile"                         ;;
		      0) # running - no an error, skip start
		         rc_failed 0 ; rc_status -v    ; continue ;;
		      *) # another error, set it and continue
		         rc_failed 1 ; rc_status -v    ; continue ;;
		    esac
		fi
		# openvpn may ask for auth ...
		echo ""

		$openvpn --daemon \
			--writepid "$pidfile" \
			--config "$conf" \
			--cd $confdir || \
		{
			rc_status -v1
			if [ ! -w "$piddir" ]; then
				# this is one possible reason, but common to
				# all instances and better than nothing ...
				echo "  Can not write $pidfile"
				rc_exit
			fi
			echo "  See /var/log/messages for the failure reason"
			rc_failed 1
			continue
		}
		# write the status one line up
		rc_status -v1
	done
	test -n "$name" || {
		echo -n "Starting $DAEMON${config:+ [$config]} -- not configured"
		rc_failed 6
		rc_status -v
	}

	;;
    stop)

	## Stop daemon with killproc(8) and if this fails
	## set echo the echo return value.

	name=""
	for pidfile in $piddir/${config:-*}.pid; do
		test -f "$pidfile" || continue
		name=$(basename "${pidfile%%.pid}")

		echo -n "Shutting down $DAEMON [$name] "
		killproc -p "$pidfile" $openvpn
		rc_status -v
		rm -f "$pidfile"
	done
	test -n "$name" || {
		echo -n "Shutting down $DAEMON${config:+ [$config]} -- not running"
		rc_status -v
	}

	;;
    try-restart)
        ## Do a restart only if the service was active before.
        ## Note: try-restart is now part of LSB (as of 1.9).
        ## RH has a similar command named condrestart.
        $0 status ${config:+"$config"}
        if test $? = 0; then
                $0 restart ${config:+"$config"}
        else
                rc_reset        # Not running is not a failure.
        fi
        # Remember status and be quiet
        rc_status
        ;;
    restart)
	## Stop the service and regardless of whether it was
	## running or not, start it again.

	# When nothing is running, start specified config or
	# the defult (autostart) set. Otherwise we stop the
	# specified one or all that are currently running.
	# Then start specified one or all that were running
	# before and have a config. Makes sense? :-)
	name=""
	list=($config)
	for pidfile in $piddir/${config:-*}.pid; do
		test -f "$pidfile" || continue
		name=$(basename "${pidfile%%.pid}")
		$0 stop "$name"
		rc_status
		test "x$name" = "x$config" && continue # in list
		test -f "$confdir/${name}.conf" && list+=("$name")
	done

	test "x$name" = x || sleep 3 # for what was this needed?

	$0 start "${list[@]}"
	# Remember status and be quiet
	rc_status
	;;
    reload|force-reload)
	for pidfile in $piddir/${config:-*}.pid; do
		test -f "$pidfile" || continue
		name=$(basename "${pidfile%%.pid}")

		echo -n "Reload service $DAEMON [$name] "
		killproc -p "$pidfile" -HUP  $openvpn
		rc_status -v
	done
	rc_status
	;;
    reopen)
	for pidfile in $piddir/${config:-*}.pid; do
		test -f "$pidfile" || continue
		name=$(basename "${pidfile%%.pid}")

		echo -n "Reopen service $DAEMON [$name] "
		killproc -p "$pidfile" -USR1 $openvpn
		rc_status -v
	done
	rc_status
	;;
    status)
	name=""
	for pidfile in $piddir/${config:-*}.pid; do
		test -f "$pidfile" || continue
		name=$(basename "${pidfile%%.pid}")

		echo -n "Checking for $DAEMON [$name] "
		killproc -p "$pidfile" -USR2 $openvpn
		rc_status -v
	done
	if test -n "$name" ; then
		echo "$DAEMON status written to /var/log/messages"
	else
		echo -n "Checking for $DAEMON "
		rc_failed 3
		rc_status -v
	fi
	;;
    probe)
	## Optional: Probe for the necessity of a reload, print out the
	## argument to this init script which is required for a reload.
	## Note: probe is not (yet) part of LSB (as of 1.9)
	result=""
	for conf in $confdir/${config:-*}.conf ; do
		test -f "$conf" || continue
		name=$(basename "${conf%%.conf}")
		autostart_filter "$name" || continue
		pidfile="$piddir/${name}.pid"

		if test ! -f "$pidfile" ; then
			result="restart"
		elif test "$conf" -nt "$pidfile" ; then
			test "$result" = "restart" || \
			result="reload"
		fi
	done
	for pidfile in $piddir/${config:-*}.pid; do
		test -f "$pidfile" || continue
		name=$(basename "${pidfile%%.pid}")
		conf="$confdir/${name}.conf"

		test -f "$conf" && result="restart"
	done
	test -n "$result" && echo "$result"
	;;
    *)
	echo "Usage: $0 {start|stop|status|try-restart|restart|reload|reopen|probe}"
	exit 1
esac
rc_exit