Opened 21 months ago
Closed 21 months ago
#2467 closed enhancement (wontfix)
In daemon mode nginx completes detaching before the service is ready
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-core | Version: | |
Keywords: | Cc: | ||
uname -a: | all platforms and operating systems | ||
nginx -V: | all versions |
Description
This affects all versions, and is a very common problem in daemons of all kinds.
This makes tests that start nginx racy, and the workaround is to loop over polling a health end-point, sleeping between polling. The workaround makes tests slower. Similar considerations can affect actual production services.
The bug is here: https://github.com/nginx/nginx/blob/a64190933e06758d50eea926e6a55974645096fd/src/os/unix/ngx_daemon.c#L26 where ngx_daemon() calls exit(0) immediately on the parent-side of fork(). Instead the parent should block waiting for the child to indicate that it has opened all the sockets it will listen on and called listen() on all of them.
Examples of how to implement this (prefix https to all of these -- I can't as otherwise my ticket gets rejected as spam!):
- github.com/heimdal/heimdal/blob/master/lib/roken/detach.c
- github.com/stefanberger/swtpm/blob/master/src/swtpm/daemonize.c
- src.illumos.org/source/search?full=&defs=daemonize*&refs=&path=&hist=&type=&xrd=&nn=1&si=defs&searchall=true&si=defs
- github.com/openvswitch/ovs/blob/master/lib/daemon-unix.c#L441
- fossies.org/linux/darkstat/conv.c#L225
- github.com/emikulic/darkhttpd/blob/master/darkhttpd.c#L2688
There are many many more to be found.
Change History (2)
comment:1 by , 21 months ago
comment:2 by , 21 months ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Type: | defect → enhancement |
This was discussed excessively in this thread (in Russian):
https://mailman.nginx.org/pipermail/nginx-ru/2017-November/060604.html
In particular, this message might be interesting, it contains some summary and a proof-of-concept patch:
https://mailman.nginx.org/pipermail/nginx-ru/2017-November/060628.html
In general, this is how most daemons are written in Unix for a long time, including how the daemon(3)
library function is expected to be used. While trying to implement synchronization and only exit from the parent process when the daemon is fully up and running might be beneficial, this is not what can be expected from normal daemons.
For nginx, the only difference is the PID file, which might not be already created when the parent process exits. It is, however, not expected to be used right after the nginx start in practical cases.
Considering the above, implementing synchronization during demonization is believed to be an overkill, and the patch referenced above is therefore not committed.
If the particular use case requires using nginx PID file immediately after nginx startup, waiting for it to appear is believed to be trivial. The same approach can and should be used for all daemons unless they are specifically known to create PID files before exiting.
Notice that the daemonization code in Heimdal is in a library that supports Windows and POSIX, and has a friendly license.
This pattern is very common nowadays, and on some systems it is absolutely necessary. For example, in SMF (Solaris, Illumos) the service should daemonize in this way so that dependent services don't start until after the dependency is ready rather than merely starting.