xdaemon() (was Re: zcip: pidfile support?)

Rob Landley rob at landley.net
Wed Sep 13 20:50:20 UTC 2006


On Wednesday 13 September 2006 3:56 am, Steven Scholz wrote:
> Hi all,
> 
> how about pidfile support for the zcip applet?
> I need to keep track of running zcip daemons for different interfaces.
> 
> And in general how about adding pidfile support for the xdaemon() function?
> Maybe generating a new function
> 
> 	xdaemon_with_pidfile(int nochdir, int noclose, const char *pidfile);

I'm pondering how to support nommu with xdaemon() properly.

Back when Vladimir was block copying other projects' code into the tree he 
added libbb/vfork_daemon_rexec.c on the assumption that every caller should 
stick an #ifdef around their daemonize testing whether or not they had nommu.  
(I like to think that the general taste and sanity level of the busybox 
development community has gone up since he left.)

Now, in a sane world xdaemon() worries about whether or not we have an mmu, 
and the callers are insulated from this.  The problem is, daemonize wants to 
fork() so we can detach from our controlling tty (and fork again so that when 
the first fork exits, it gets reparented to init).  On a nommu system we only 
have vfork(), which freezes its parent until the child calls _exit() or 
exec().

I _think_ that the double vfork() should still work: the first vfork waits 
until the second vfork() finishes.  The second one calls exec() and the first 
one calls _exit().  However, in order to exec we have to know what program 
we're running.

Now there are two places in busybox where we know what argv[] is from every 
applet, and that's in applets/busybox.c and applets/applets.c.  So if we hook 
either busybox_main() or run_applet_by_name() to copy argc and argv to global 
variables, we could then use those global variables in xdaemon() to re-exec 
ourselves with some kind of "we're daemonized, don't do it again" flag that 
could also be parsed and removed by busybox_main().  (Making this work for 
scripts/individual is my problem, I'm learning how to declare weak symbols 
for the linker to handle this sort of thing.)

Anyway, that should handle giving xdaemon() the info it needs to handle the 
nommu case without extra setup on the part of its callers.  (There is the 
caveat that in the nommu case it'll restart the app, which we should document 
but shouldn't cause a major problem.)

The other fallout is that it might be good to yank argc and argv from the 
various applet_main() files if we go down this road (to save two arguments, 
just use the globals; optind is already global anyway) and on top of that, 
bb_getopt_ulflags() could lose its first two arguments and just use the 
globals as well, so that's extra savings.  But when I started looking into 
it, I looked closely at bb_getopt_ulflags() (more of Vladimir's code) and 
went "ew, needs a rewrite, and it's now such a thick wrapper around getopt() 
that it's probably smaller not to use getopt() at all anymore and just parse 
it ourselves without modifying argv[]).

Which raises the possibility of allocating a new argv[] and moving the global 
pointer to point to the new one, so we don't modify the part of our 
environment that "ps" looks at...

Anyway...  Todo item. :)

Rob
-- 
Never bet against the cheap plastic solution.



More information about the busybox mailing list