On Fri, 22 Jan 2010, Ciaran McCreesh wrote:
> 2010/1/18 Benjamin R. Haskell <[email protected]>:
> > The problem is that 'distcc -j' with zeroconf fires off a daemon
> > (See http://lists.samba.org/archive/distcc/2004q4/002774.html for
> > the justification -- basically: the startup cost for collecting mDNS
> > information is worth avoiding in a build that calls distcc many
> > times.)
>
> Ebuilds aren't allowed to spawn processes that last longer than the
> ebuild itself. The same applies to anything you sneakily make ebuilds
> do.
I'm not sure what you mean by "aren't allowed to"... "are prohibited by
official policy"? So, an ebuild calling distcc -j would be
out-of-bounds? Or do you mean that the wait is supposed to be enforced
programmatically?
The 'distcc -j' isn't called in an ebuild -- I use it in my own
/etc/paludis/bashrc to set up my $MAKEARGS.
> > So, from the way 'outputwrapper' works, the problem is that
> > 'outputwrapper's fd's aren't in the set that get closed by 'distcc'
> > before daemonizing. And 'distcc' would thus sleep for 20 seconds
> > every time 'bashrc' got sourced, unless I happened to have run
> > 'distcc' outside of paludis (so that the daemon was already running
> > outside of outputwrapper).
>
> Are you really really sure that that's the issue? I strongly suspect
> that it's not in the least bit FD related, since we've been passing a
> 'spare' FD around (to avoid having to use sockets, which have
> permissions ick) for ages.
Not absolutely sure, no... but...
> I suspect the real problem is that the daemon doesn't fork itself
> twice, to make itself owned by init rather than the spawning process.
...the daemon spawned by distcc -j appears to not double-fork, but it
does setsid(). And, the attached program triggers the same behavior
w.r.t. outputwrapper, unless called with the with-closed-fds wrapper
from my initial email. (double-forked-simple.c just double forks,
closes fd's 0-2, setsid()s, and sleeps for 20 seconds.) But maybe I'm
missing something the 'distcc' code misses, too.
> > I'm going to suggest on the distcc list that the daemonization
> > process closes a larger set of fd's. (There is also a similar
> > problem with some leaked fd's in the LVM2 utilities -- I've not
> > corresponded w/ that community ever, but I'll try to find them,
> > too.) But, I just wanted to share the workaround if anyone else was
> > having trouble (seems unlikely).
>
> Closing a larger set of FDs also really isn't the solution... If it
> really is FD related, using dup2 rather than dup might be what's
> called for.
It appears output-wrapper.cc is using dup2 everywhere, so I assume you
mean in 'distcc'? The dup's in the daemonization code there are around
lines 586-595 of src/zeroconf.c:
http://code.google.com/p/distcc/source/browse/trunk/src/zeroconf.c#586
They use normal 'dup', and check for getting the desired fd num's via
asserts, but in my own testing, std{in,out,err} are correctly 0, 1, and
2 when run under outputwrapper.
--
Best,
Ben#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>
void daemonize() {
int fd, i;
for (i = 0; i < 3; i++) close(i);
fd = open("/dev/null", O_RDWR);
assert(fd==0);
fd = dup(0);
assert(fd==1);
fd = dup(0);
assert(fd==2);
setsid();
chdir("/");
}
int main(void) {
pid_t pid1,pid2;
pid1 = fork();
if (pid1 == -1) {
// error in fork1
_exit(1);
} else if (pid1) {
// parent
waitpid(pid1, NULL, 0);
} else {
// child
daemonize();
pid2 = fork();
if (pid2 == -1) {
// error in fork2
_exit(2);
} else if (pid2) {
// parent2
_exit(3);
} else {
sleep(20);
_exit(4);
}
}
return 5;
}
_______________________________________________
paludis-user mailing list
[email protected]
http://lists.pioto.org/mailman/listinfo/paludis-user