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?