If the nunc-stans listener is disabled, due to FDs being exhausted, the server will crash if it is stopped.
{{{ Program received signal SIGSEGV, Segmentation fault. 0x00007f28508547e3 in PR_Close () from /lib64/libnspr4.so (gdb) where
(gdb) up
1562 PR_Close( fdesp ); (gdb) p fdesp[0] $4 = {methods = 0x0, secret = 0x1b08480, lower = 0x0, higher = 0x0, dtor = 0x0, identity = -1} }}}
When the the nunc-stans listener is enabled we see:
{{{ (gdb) p *fdesp[0] $5 = {methods = 0x7fb873e7e060, secret = 0x15e5300, lower = 0x0, higher = 0x0, dtor = 0x0, identity = 0} }}}
Need to check that the identity is not set to -1 before closing the FD.
We should not have to check the internals of the prfd. Something odd is going on, like we are closing the prfd twice, so that the second closure causes the crash.
So does disabling a listener via ns_job_modify(listener->ns_job, NS_JOB_DISABLE_ONLY) close the listener fd? If so, where? If not, how do we close the disabled listener fd?
Replying to [comment:4 rmeggins]:
The FD is definitely being closed in nunc_stans. It appears to be happening here:
{{{ event_del(job->ns_event_fw_fd); --> this closes the FD ns_event_fw_io_event_remove (ns_event_fw_ctx=0x2aab240, job=0x2af40c0) at ns_event_fw_event.c:98
}}}
Typical PR_Close (before and after):
{{{ (gdb) p *fd $1 = {methods = 0x7fe1e2ac1060, secret = 0x11ef210, lower = 0x0, higher = 0x0, dtor = 0x0, identity = 0}
(gdb) p *fd $2 = {methods = 0x0, secret = 0x11ef210, lower = 0x0, higher = 0x0, dtor = 0x0, identity = -1} }}}
The later is exactly how the FD looks when the listener is disabled.
AFAICT, event_del does not close the fd - it just tells the event framework not to listen for events on this fd. I've looked at the source code for libevent - there is no call to close(ev->fd).
Okay, this is what is happening. The FD table gets full and we goto disable the listener:
{{{
This code path sets the job->job_type to 0
Then during the shutdown event we run into this code which closes that FD:
So in internal_ns_job_done(), since the job->job_type was set to 0, we close the FD when the listener is disabled. When the listener is enabled job type is not zero(it's 321). and its not closed.
The question is, should we stop internal_ns_job_done() from closing FDs? Or stick with my fix? Seems like we should leave internal_ns_job_done() as is.
Ah, ok. Looks like we should call this: {{{ ns_disable_listener(listener_info *listener) ... ns_job_modify(listener->ns_job, NS_JOB_DISABLE_ONLY|NS_JOB_PRESERVE_FD); ... }}} That should tell nunc-stans not to close the fd.
revision 0001-Ticket-48040-preserve-the-FD-when-disabling-a-listen.patch
Replying to [comment:8 rmeggins]:
I was just looking into those flags :-) Very good, new patch attached.
To git+ssh://git.engineering.redhat.com/srv/git/users/mareynol/ds.git 9bef065..14d8059 nunc-stans -> nunc-stans commit 14d80591be13c82ca63248f18dbd6a6c45379792
Metadata Update from @mreynolds: - Issue assigned to mreynolds - Issue set to the milestone: 1.3.4 backlog
389-ds-base is moving from Pagure to Github. This means that new issues and pull requests will be accepted only in 389-ds-base's github repository.
This issue has been cloned to Github and is available here: - https://github.com/389ds/389-ds-base/issues/1371
If you want to receive further updates on the issue, please navigate to the github issue and click on subscribe button.
subscribe
Thank you for understanding. We apologize for all inconvenience.
Metadata Update from @spichugi: - Issue close_status updated to: wontfix (was: Fixed)