Subject: rc.sh (was: Re: run-level implementation for NetBSD)
To: Randy Terbush <randy@zyzzyva.com>
From: Simon J. Gerraty <sjg@zen.void.oz.au>
List: current-users
Date: 03/26/1996 21:58:17
> That topic peeked it's head out on the list today. Since the last

I haven't seen the relevant msg yet... which list?

>		... As I remember, and as CGD reminded me, you 
> have mentioned in the past that you have the makings of such a
> beast. Care to share where you are with it and what it can do?

While hoping not to start another drawn-out thread, I'll cc this to
current-users in case others are intersted.  I'll briefly ? describe
what I'm using and why, then point you to where you can get it.

[ok, for the patience impaired check out
ftp://ftp.quick.com.au/pub/unix/rc.*	rc.sh and man page
ftp://ftp.quick.com.au/pub/unix/config*	my host config tool and sample
					config tree]

[for the tolerance impaired, before flaming me, please keep in mind
that my goals are to manage networks of heterogeneous UNIX systems
with minimal pain.  Ie. NetBSD is just one of the platforms this lot
has to run on.]

Firstly, I have not implemented run-levels, they're cute but I can
live without them.  What I want is the *.d script stuff.

I have an rc.sh script which is a generic implementation of sysV's
rcN. Ie. it processes files in a directory starting with some prefix
(S is the default). Files ending in .sh are sourced - and therefor
affect rc.sh itself and subsequent scripts and others are run in a
sub-shell.  This provides a simple yet powerful building
block... (actually rc.sh could be _much_ simpler if it did not have to
cope with running on systems that may not yet have basename and
dirname available :-)

Eg.

ln -s /etc/rc.sh /configs/config.sh
/configs/config.sh

will look for /configs/config.d and (by default) run anything named S*
with an arg of start.  That is the basis for my host config tool (more
on that below).

Similarly /etc/rc.sh looks in /etc/rc.d, /etc/rc_local.sh looks to
/etc/rc_local.d etc.

On my NetBSD systems /etc/rc simply runs /etc/rc.sh with appropriate
args so that init does not need changing.  /etc/rc.d contains:

/etc/rc.d/S00setup.sh
/etc/rc.d/S20rc
/etc/rc.d/S99local@ -> ../rc_d/local

where S20rc is more or less the original /etc/rc.
I never really pursued splitting it up as unless core pick it up I
figured it would be a waste of time. S99local just runs
/etc/rc_local.sh

Ok, so far we haven't achieved much... but now we start to win. On ALL
systems (NetBSD,SunOS,Solaris,HP-UX etc) I have /etc/rc_local.d and on
systems that still have /etc/rc.local rather than /etc/rc.d,
/etc/rc_local.sh is just run at the end of /etc/rc.local so there is
no need to keep hacking on rc.local

Anyway, /etc/rc_local.sh (or /etc/rc_local) takes care of running all
the local startup scripts for various packages.  On this NetBSD system
my /etc/rc_local.d contains:

/etc/rc_local.d/S00os.sh@ -> ../rc_d/os.sh
/etc/rc_local.d/S01site.sh@ -> ../rc_d/site.sh
/etc/rc_local.d/S02zen.sh
/etc/rc_local.d/S20netbsd
/etc/rc_local.d/S30ldconf*
/etc/rc_local.d/S35ipfwall
/etc/rc_local.d/S40ppp@ -> ../rc_d/ppp
/etc/rc_local.d/S40runapc@ -> ../apc/runapc
/etc/rc_local.d/S50wait_if
/etc/rc_local.d/S60rdate@ -> ../rc_d/rdate
/etc/rc_local.d/S80chroot_www@ -> ../rc_d/chroot_www
/etc/rc_local.d/S80news@ -> ../rc_d/news
/etc/rc_local.d/S80ntp@ -> ../rc_d/ntp
/etc/rc_local.d/S80smapd@ -> ../rc_d/smapd
/etc/rc_local.d/S90news

again S20netbsd is more or less the original rc.local

ipfwall	configures my ipfirewall,
ppp	curiously enough brings up my internet link (after the filters
	are in place)
runapc	works out which of my UPS monitoring scripts to run - ie. is
	this system monitoring the UPS or receiving status from
	another... 
wait_if	simply waits up to 3 minutes for the PPP link to be
	established.
rdate	sets system clock (it kills cron first, then restarts it)
chroot_www
	starts my httpd proxy in a chrooted env (hard to guess :-)

the rest are pretty obvious...

Also, on all systems I have /etc/{hourly,daily,weekly,monthly}.d to
take care of a lot of regular mainentance. And of course
/etc/{hourly,daily,weekly,monthly}.sh are all just links to rc.sh

My /etc/hourl.d here contains:

/etc/hourly.d/S00os.sh@ -> ../rc_d/os.sh
/etc/hourly.d/S01site.sh@ -> ../rc_d/site.sh
/etc/hourly.d/S02redirect.sh@ -> ../rc_d/redirect.sh
/etc/hourly.d/S10df_watch@ -> ../rc_d/df_watch
/etc/hourly.d/S10newsyslog*
/etc/hourly.d/S50aliases
/etc/hourly.d/S80acct@ -> /local/acct/acct.hour
/etc/hourly.d/S80pppchk
/etc/hourly.d/S99mailrep.sh@ -> ../rc_d/mailrep.sh

I use redirect.sh and mailrep.sh to gather the stdout and stderr of
all the S* scripts and mail them off with a subject like:
"zen hourly output"

On my NetBSD notebook, /etc/neton and /etc/netoff use /etc/net.d to
handle configuring sendmail,dns,nfs mounts etc to suit the current
network.

I also use /etc/shutdown.d to handle things like shutting down
databases etc.

All of these facilities are built using that single rc.sh I can
reconfigure a machine by simple adding/removing an S* file from an
appropriate directory...

You will note that much of the *.d dirs simply contain links into
/etc/rc_d.  This allows /etc/rc_d/os.sh for example to be kept under
source control and new revs are not needed each time you want to
change the order things are run in.  Also os.sh is linked into just
about every *.d directory to set certain OS specific things.

Why /etc/rc_d ?  Good question.  The name sucks, I know.  Originally I
used rc.d but SysV (well Solaris at least) blindly executes everything
in rc.d so that was no good.  I know that /etc/init.d is the
traditional location for such things, but I wanted a directory that I
could create and populate on all boxes without fear of breaking vendor
support agreements (yes some customers care about such things :-)
Anyway I'm pretty sure no one else is using /etc/rc_d :-) 
And of course there is nothing stopping folk from 
ln -s /etc/rc_d /etc/init.d 
if they want.

For those intersted in looking further look in 
	ftp://ftp.quick.com.au/pub/unix/
the README file describes what is there and the MD5.OUT contains check
sums.  The bits relevant to this thread are:

config-sh-*.cpio.gz
                This is my super duper host config utility.
                A single config tree supports multiple operating
                systems, releases and hardware.
                Version 1.09 supports conditionals in install lists.
                Version 1.10, update_file supports -list foo.list
                see update_file(8).
                I've dropped the .tar files as I find cpio more useful.
                use gzcat file | cpio -icvdm to unpack
                                | cpio -itv to see content

configs-example-*.cpio.gz
                An example (actually a sub-set of my) configs tree.

cfg-slides.ps.gz
                Slides for my talk about configs.

rc.sh,rc.8      This is my generic rc script (ala SysV's rc2 etc), it
                is the heart of configs and several other useful
                tools.

Note that config-sh-*.cpio.gz includes rc.sh so you don't have to grab
both. 

Configs is totally cool.  I use it with a single config tree to
support NetBSD,SunOS,HP-UX,Ultrix,SGI etc systems with various OS
releases and hardware platforms.  The guts of it is a hierachical
config tree which contains both host or os/release/hardware specific
files as well as totally generic ones. It also looks for more specific
config.d's in the config tree.  Eg SunOS/5.X/config.d contains a
script to automagically install lists of patches on Solaris systems
(finds the patches on cd-rom or in the config tree itself).

It is much improved since I presented it at the local sage-au meeting
last year. Again, it is driven by rc.sh

configs-example-* contains only a sub-set of my configs tree, and I've
not updated the list of files in ages, so much recent magic may be
missing, but it should give you the idea.

Enjoy!

--sjg