Skip to content

Commit

Permalink
Issue 6010 - 389 ds ignores nsslapd-maxdescriptors (#6027)
Browse files Browse the repository at this point in the history
Bug description: During server startup the connection table size is assumed
to be lower than or equal to the number of configured reserve file descriptors.
This prevents the server from starting whem the number of reserve descriptors
is high.

Fix description: Change the check to make sure the connection table size is
not greater than (max descriptors - reserve descriptors).

Also, the number of reserve descriptors is used to determine if the server can
accept a new connection. This has been changed to compare the connection table
size against the current number of connections.

Relates: #6010

Reviewed by: @progier389, @droideck, @tbordaz (Thank you)
  • Loading branch information
jchapma authored Feb 7, 2024
1 parent 060f3eb commit f415611
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 5 deletions.
37 changes: 36 additions & 1 deletion dirsrvtests/tests/suites/resource_limits/fdlimits_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def test_fd_limits(topology_st):
def test_reserve_descriptor_validation(topology_st):
"""Test the reserve descriptor self check
:id: TODO
:id: 9bacdbcc-7754-4955-8a56-1d8c82bce274
:setup: Standalone Instance
:steps:
1. Set attr nsslapd-reservedescriptors to a low value of RESRV_DESC_VAL (10)
Expand Down Expand Up @@ -121,6 +121,41 @@ def test_reserve_descriptor_validation(topology_st):

log.info("test_reserve_descriptor_validation PASSED")

@pytest.mark.skipif(ds_is_older("1.4.1.2"), reason="Not implemented")
def test_reserve_descriptors_high(topology_st):
"""Test setting reserve descriptor value to higher than average.
:id: 19c8991b-ef78-485e-bdf9-a0977fcbcd04
:setup: Standalone Instance
:steps:
1. Set attr nsslapd-maxdescriptors to systemd LimitNOFILE value
2. Verify value has been set
3. Set attr nsslapd-reservedescriptors to 2 less than nsslapd-maxdescriptors
4. Verify value has been set
5. Restart instance
:expectedresults:
1. Success
2. Value of SYSTEMD_LIMIT is returned
3. Success
4. Values of SYSTEMD_LIMIT -2 is returned
5. Instance starts correctly
"""

# Set nsslapd-maxdescriptors to a custom value
topology_st.standalone.config.set(FD_ATTR, SYSTEMD_LIMIT)
max_fd = topology_st.standalone.config.get_attr_val_utf8(FD_ATTR)
assert max_fd == SYSTEMD_LIMIT

# Set nsslapd-reservedescriptors to 2 less than custom value
topology_st.standalone.config.set(RESRV_FD_ATTR, str(int(SYSTEMD_LIMIT) - 2))
resrv_fd = topology_st.standalone.config.get_attr_val_utf8(RESRV_FD_ATTR)
assert resrv_fd == str(int(SYSTEMD_LIMIT) - 2)

# Verify instance restart
topology_st.standalone.restart()
assert (topology_st.standalone.status())

log.info("test_reserve_descriptors_high PASSED")

if __name__ == '__main__':
# Run isolated
Expand Down
3 changes: 2 additions & 1 deletion ldap/servers/slapd/conntable.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ connection_table_new(int table_size)
ct->list_num = config_get_num_listeners();
ct->num_active = (int *)slapi_ch_calloc(1, ct->list_num * sizeof(int));
ct->size = table_size - (table_size % ct->list_num);
ct->list_size = ct->size/ct->list_num;
/* Account for first slot of each list being used as head (c_next). */
ct->list_size = (ct->size/ct->list_num)+1;
ct->c = (Connection **)slapi_ch_calloc(1, ct->size * sizeof(Connection *));
ct->fd = (struct POLL_STRUCT **)slapi_ch_calloc(1, ct->list_num * sizeof(struct POLL_STRUCT*));
ct->table_mutex = PR_NewLock();
Expand Down
5 changes: 2 additions & 3 deletions ldap/servers/slapd/daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,6 @@ accept_thread(void *vports)
PRErrorCode prerr;
int last_accept_new_connections = -1;
PRIntervalTime pr_timeout = PR_MillisecondsToInterval(slapd_accept_wakeup_timer);
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
PRFileDesc **n_tcps = NULL;
PRFileDesc **s_tcps = NULL;
PRFileDesc **i_unix = NULL;
Expand All @@ -831,7 +830,7 @@ accept_thread(void *vports)

while (!g_get_shutdown()) {
/* Do we need to accept new connections? */
int accept_new_connections = ((ct->size - g_get_current_conn_count()) > slapdFrontendConfig->reservedescriptors);
int accept_new_connections = (ct->size > ct->conn_next_offset);
if (!accept_new_connections) {
if (last_accept_new_connections) {
slapi_log_err(SLAPI_LOG_ERR, "accept_thread",
Expand Down Expand Up @@ -2083,7 +2082,7 @@ unfurl_banners(Connection_Table *ct, daemon_ports_t *ports, PRFileDesc **n_tcps,
char addrbuf[256];
int isfirsttime = 1;

if (ct->size <= slapdFrontendConfig->reservedescriptors) {
if (ct->size > (slapdFrontendConfig->maxdescriptors - slapdFrontendConfig->reservedescriptors)) {
slapi_log_err(SLAPI_LOG_ERR, "slapd_daemon",
"Not enough descriptors to accept any connections. "
"This may be because the maxdescriptors configuration "
Expand Down

0 comments on commit f415611

Please sign in to comment.