[comp.sys.3b1] daemons

dt@yenta.alb.nm.us (David B. Thomas) (03/21/91)

picano@en.ecn.purdue.edu (Silvio Picano) writes:

>How do I make a process run in the 'background' on a 3b1?  

This brings up some deep and provocative issues, which I'd like to
get into:  the fine points of installing daemons on a 3b1, and the
use of run levels.

I've been wrestling with this stuff for a while, and I'd like to know
how to do things better.

First of all, daemons....

method 1:  /etc/inittab

I have tried using /etc/inittab to start daemons.  init will faithfully
spawn the process, but you have to watch out.  Some problems are:

	1. If the process knows it wants to be a daemon, it may spawn
	   a child and terminate.  Init will think that there is no
	   longer a process running for that inittab entry.  In that
	   case, respawn will use up all available process slots.
	   cron is an example of such a program.  So, you don't have to
	   respawn, but then if it does die, init can't restart it for
	   you.  Also, init can't kill it if you switch to a runlevel
	   that requires that daemon not to be running.  cron, the
	   archetypal daemon, is hard for init to manage!

	2. No environment.  Anything using dates will use the wrong
	   timezone, and so on.  Plus some things just DON'T work
	   and I haven't tracked down the trouble yet.  For example,
	   errord (from osu-cis) will run but will not actually do
	   its job and write to /usr/adm/errfile, if started from
	   inittab.  It works fine if started from rc.  ??  Another
	   daemon I wrote which uses the getutent() function library
	   actually wiped out /etc/utmp, when started from inittab.
	   I only used the library functions, which are all read-only!


method 2:  /etc/daemons

You can put an executable file in /etc/daemons, and it will be started
by the stock /etc/rc script.  However, there are possible problems with
the i/o channels.  Processes started here are associated with window w1,
and this can get in your way if you don't make sure that the daemons
never touch their standard input and output.

I have also experienced strange behavior where a daemon in /etc/daemons
will not get started, even though it is present and executable, every
few boots.  I eventually removed /etc/daemons.


method 3: /etc/rc

Adding a line to rc works very well, but this is only good for daemons
that you want to start at boot, and that you can assume will keep running.
If you want to kill it or restart it, you have to do it yourself.  No big
deal, but I prefer to use init to do that dirty work for me, where
possible.


RUN LEVELS

Here's part of my inittab:

# run these once at bootup and never again
 obm::boot:/usr/local/bin/obminit -l0 -md -ut
 t0i::boot:/etc/hfc_ctl +/dev/tty000
 t1i::boot:/etc/hfc_ctl +/dev/tty001
 t2i::boot:/etc/hfc_ctl +/dev/tty002

# these terminals should work in both
# run level 2 (normal) and 3 (maint)
 vid:23:respawn:/etc/getty window 9600
:001:23:respawn:/etc/getty tty001 9600
 002:23:respawn:/etc/getty tty002 9600

# these only work in run level 2
:ph0:2:respawn:/etc/getty ph0 1200
:ph1:2:respawn:/etc/getty ph1 1200
 000:2:respawn:/usr/lib/uucp/modem # Telebit Trailblazer uugetty

# nn newsreader database manager
 nnn:2:respawn:nice -40 /etc/start /usr/lib/nn/nnmaster -l -r -f -C -h -Q

# cron start and kill
 crn:2:once:/etc/start /etc/cron
 kil:3:once:/etc/killname cron

The first :boot: entries are run just once at boot time.  They used to
be installed in /etc/daemons, but this seems more maintainable, and
is probably quicker too.

I have two run-levels (2 and 3) that I can toggle between at will, and it
will move the system from normal multiuser mode to a maintenence mode.
In run level 3, cron is dead, nnmaster is not running, and no outside logins
are allowed.

nnmaster does not spawn a child (the -f option sees to that), so init
can keep track of it, and respawn it if necessary.  It can also kill it
when I switch to runlevel 3.  Neet!

cron, on the other hand, does spawn a child, so init can't keep track of it.
As you can see, I have it start once on entry to level 2, and killed once
on entering level 3.  If it should die, tuff!

/etc/start and /etc/killname are pretty obvious: start sets up some
environment (TZ variable) and execs its arglist.  killname does a ps,
greps for the name, and kills that process.  Hokey, I know.


How have others tackled daemons?  Are these ways I could have done
this stuff better?

					little david
-- 
Bottom of stack = 0x40000
Stack pointer   = 0x3fffe
Don't push it!

john@chance.UUCP (John R. MacMillan) (03/22/91)

|How have others tackled daemons?  Are these ways I could have done
|this stuff better?

I got sick of the way the 3B1 handled this stuff (note that the stock
shutdown does a killall, and THEN runs things in /etc/shutdaemons) so
I changed to be rather like SysVr3, with and /etc/rc0 and /etc/rc2,
and daemon startup and shutdown scripts in /etc/rc0.d and /etc/rc2.d
directories.  I also mutilated, I mean, reworked /etc/shutdown, and
the basic startup (now in /etc/bcheckrc) doesn't look much like it
used to; it verifies that the time is correct (my battery died and I'm
too lazy or cheap to replace it), and asks if you want to go single or
multi-user.

That brings me to an aside.  Both those prompts time out, and when I
was doing these changes I remembered there had been a discussion about
programs to do that.  I didn't have any of them on hand, so I just did
it in the script.  Did I miss something about the advantages of using
a separate command?