Subject: Re: take2...
To: None <tech-userlevel@netbsd.org>
From: Luke Mewburn <lukem@goanna.cs.rmit.edu.au>
List: tech-userlevel
Date: 12/02/1999 23:03:59
Darren Reed writes:
> Well, there's a lot of options there, and I'm not sure I want to choose
> one.  Instead, I'll offer my opinion on what I think is `best' :-)
> 
> 3. As for vendor scripts and numbering, etc, vendors are in the shit anyway
>    because the standard script used on Solaris (or linux) will not work on
>    NetBSD with the current implementation due to the "run_rc_command" method
>    being offered.  So if they need to do a custom script for us, they might
>    as well do it right and add the right dependencies.  I think you've
>    missed that difference when comparing what's being offered with what is
>    in place today.  That is unless you'd scrap the "run_rc_command" code
>    if "dumpstart" was no longer needed, etc.

[for the rest of my reply, assume we're talking about just supporting
 running then "for i in `rcorder /etc/init.d/*`; do $i start; done"
 method...]

Vendor scripts will work in the current implementation even if they
don't use run_rc_command. They just have to support start (& possibly
stop, or at least not barf if given stop). run_rc_command just allows
you to simplify your scripts.

Vendor scripts would have to be modified to have the appropriate
PROVIDE/REQUIRE/BEFORE lines if you wanted them to start at a
particular point. If not, they will be started sometime at the end,
with all the other scripts that are at the `end of the chain' (this
is part of rcorder(8), and that program could be tweaked to change
this behaviour).

See below regarding my reasons for retaining run_rc_command.


> 6. I really don't like the current design for rc scripts with "start_cmd=",
>    etc.  It unecessarily restricts an independant script on the contents of
>    that script.  Each script should be run, not define variables which get
>    executed.

run_rc_command was initially developed as a method of reducing
unnecessary code duplication in scripts (such as parsing command line
arguments, checking for running processes, etc), and it does this
well. You haven't explained very well what's wrong with run_rc_command
in its role of supporting start/stop/... type operations.

For example, my original work on this topic was a bunch of scripts for
Solaris (which get installed in /etc/{init,rc0,rc2,rc3}.d). Creating a
new script was tedious. When I first implemented run_rc_command it
didn't support `dumpstart' (et al), and was a bit simpler.

For comparison I've attached the script which starts dhcpd; the first
one uses run_rc_command (16 lines), the second one (from my Solaris
systems) does all the arg parsing/process checking internally (71 lines).
The first one also does a couple of extra checks, such as ensuring that
necessary config files exist.

You'd have to give me a really good reason for arguing for the
larger/messier version which doesn't use run_rc_command,
especially since the run_rc_command version is easier to read/debug.

--- cut here --- file: dhcpd (run_rc_command version)
#!/bin/sh
#
# $NetBSD$
#

# PROVIDE: dhcpd
# REQUIRE: daemon

. /etc/rc.subr

name="dhcpd"
command="/usr/sbin/${name}"
pidfile="/var/run/${name}.pid"
required_files="/etc/${name}.conf /var/db/dhcpd.leases"

run_rc_command "$1"
--- cut here ---


--- cut here --- file: /etc/init.d/dhcpd (do it all internally version)
#!/bin/sh
#
#	$Id: dhcpd,v 1.2 1998/02/28 23:15:57 lm Exp $
#
# dhcpd --
#	control dhcpd
#

if [ -f /etc/rc.subr ]; then
	. /etc/rc.subr
else
	echo "Can't read /etc/rc.subr; aborting."
	exit 1
fi

PIDFILE="/var/run/dhcpd.pid"
COMMAND="/usr/local/sbin/dhcpd"

case "$1" in
force*)
	set `echo $1 | sed -e 's/^force//'`
	dhcpd=YES
	;;
esac

case "$1" in
start)
	pid=`check_pidfile $PIDFILE $COMMAND`
	if [ -n "$pid" ]; then
		echo "dhcpd already running? (pid=$pid)"
		exit 1
	fi
	if checkyesno dhcpd && [ -x $COMMAND ]; then
		echo "Starting dhcpd."
		$COMMAND $dhcpd_flags &
	fi
	;;

stop|restart|reload)
	pid=`check_pidfile $PIDFILE $COMMAND`
	if [ -z "$pid" ]; then
		if checkyesno dhcpd; then
			echo "dhcpd not running? (check $PIDFILE)"
			exit 1
		fi
	else
		case "$1" in
		stop)
			echo "Stopping dhcpd."
			kill -TERM $pid
			;;
		*)
			echo "Restarting dhcpd."
			kill -TERM $pid
			sleep 2
			pid=`check_pidfile $PIDFILE $COMMAND`
			if [ -n "$pid" ]; then
				echo "(didn't die; trying SIGKILL)"
				kill -KILL $pid
			fi
			$COMMAND $dhcpd_flags &
			;;
		esac
	fi
	;;

*)
	echo "Usage: $0 { [force]start | [force]stop | [force]restart }"
	;;

esac
--- cut here ---

--
Luke Mewburn, <lukem@netbsd.org>