Andreas Gustafsson
2014-01-28 17:56:31 UTC
Hi all,
As discussed in PR 48282, some daemons background themselves before
opening the sockets or registering the RPCs they receive requests on.
This leads to race conditions: if you try to use the service provided
by a daemon such as nfsd immediately after starting it, you get random
failures because it may not yet be ready to provide service.
In some cases, this can be fixed by moving the call to daemon(3)
later, to a point where the socket/RPC setup is complete. But this
won't work in daemons that use kqueues or threads, because kqueues and
threads are not inherited across a fork.
I think the right way to fix the problem is to split the daemonization
into two phases: the daemon should fork early, before creating threads
or kqueues, but the parent process should only exit when the child is
ready to accept requests for service.
A proof of concept implementation of such a scheme is already in
src/tests/lib/libc/net/h_dns_server.c, and I would now like to move
this code into a library so that it can be used by other daemons, too.
I propose to do this by adding the two functions daemon2_fork() and
daemon2_detach() to libc. A patch containing my proposed changes is
at:
http://www.gson.org/netbsd/patches/daemon2-v9.patch
The patch includes updates to the daemon(3) man page and test cases.
Initially, two daemons would be switched to the new scheme: nfsd and
rquotad (the ones involved in the test failures reported in PR 48282);
others can follow later.
Comments? Objections?
Thanks,
As discussed in PR 48282, some daemons background themselves before
opening the sockets or registering the RPCs they receive requests on.
This leads to race conditions: if you try to use the service provided
by a daemon such as nfsd immediately after starting it, you get random
failures because it may not yet be ready to provide service.
In some cases, this can be fixed by moving the call to daemon(3)
later, to a point where the socket/RPC setup is complete. But this
won't work in daemons that use kqueues or threads, because kqueues and
threads are not inherited across a fork.
I think the right way to fix the problem is to split the daemonization
into two phases: the daemon should fork early, before creating threads
or kqueues, but the parent process should only exit when the child is
ready to accept requests for service.
A proof of concept implementation of such a scheme is already in
src/tests/lib/libc/net/h_dns_server.c, and I would now like to move
this code into a library so that it can be used by other daemons, too.
I propose to do this by adding the two functions daemon2_fork() and
daemon2_detach() to libc. A patch containing my proposed changes is
at:
http://www.gson.org/netbsd/patches/daemon2-v9.patch
The patch includes updates to the daemon(3) man page and test cases.
Initially, two daemons would be switched to the new scheme: nfsd and
rquotad (the ones involved in the test failures reported in PR 48282);
others can follow later.
Comments? Objections?
Thanks,
--
Andreas Gustafsson, ***@NetBSD.org
Andreas Gustafsson, ***@NetBSD.org