diff options
author | Gary Lockyer <gary@catalyst.net.nz> | 2018-09-07 07:04:48 +1200 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2018-11-30 11:42:44 +0100 |
commit | f90cf49970a0edf4dce5d145726a04e798530a2e (patch) | |
tree | ee9ffa2323291ab3cc73dc499959eb1773971b1e | |
parent | 2381b4ff6794ba514cca57d3995459bc2cef8352 (diff) | |
download | samba-f90cf49970a0edf4dce5d145726a04e798530a2e.tar.gz |
s4 smdb standard: Limit processes forked on accept.
Limit the number of processes started by the standard model on accept.
For those services that support fork on accept, the standard model forks
a new process for each new connection. This patch limits the number of
processes to the value specified in 'max smbd processes', a value of
zero indicates that there is no limit on the number of processes that
can be forked.
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-rw-r--r-- | docs-xml/smbdotconf/tuning/maxsmbdprocesses.xml | 7 | ||||
-rw-r--r-- | selftest/knownfail.d/process_limit | 1 | ||||
-rw-r--r-- | source4/smbd/process_standard.c | 33 |
3 files changed, 38 insertions, 3 deletions
diff --git a/docs-xml/smbdotconf/tuning/maxsmbdprocesses.xml b/docs-xml/smbdotconf/tuning/maxsmbdprocesses.xml index a194a26a13c..f5b1e4230be 100644 --- a/docs-xml/smbdotconf/tuning/maxsmbdprocesses.xml +++ b/docs-xml/smbdotconf/tuning/maxsmbdprocesses.xml @@ -10,6 +10,13 @@ conditions, each user will have an <citerefentry><refentrytitle>smbd</refentrytitle> <manvolnum>8</manvolnum></citerefentry> associated with him or her to handle connections to all shares from a given host.</para> + + <para>For a Samba ADDC running the standard process model this option + limits the number of processes forked to handle requests. + Currently new processes are only forked for ldap and netlogon + requests. + </para> + </description> <value type="default">0</value> diff --git a/selftest/knownfail.d/process_limit b/selftest/knownfail.d/process_limit deleted file mode 100644 index db34dae23ca..00000000000 --- a/selftest/knownfail.d/process_limit +++ /dev/null @@ -1 +0,0 @@ -^samba.tests.process_limits.samba.tests.process_limits.StandardModelProcessLimitTests.test_process_limits diff --git a/source4/smbd/process_standard.c b/source4/smbd/process_standard.c index b1cc7de155d..139339c92ec 100644 --- a/source4/smbd/process_standard.c +++ b/source4/smbd/process_standard.c @@ -32,6 +32,9 @@ #include "lib/util/debug.h" #include "source3/lib/messages_dgm.h" +static unsigned connections_active = 0; +static unsigned smbd_max_processes = 0; + struct standard_child_state { const char *name; pid_t pid; @@ -143,8 +146,7 @@ static void standard_child_pipe_handler(struct tevent_context *ev, if (errno == 0) { errno = ECHILD; } - TALLOC_FREE(state); - return; + goto done; } if (WIFEXITED(status)) { status = WEXITSTATUS(status); @@ -157,7 +159,17 @@ static void standard_child_pipe_handler(struct tevent_context *ev, DBG_ERR("Child %d (%s) terminated with signal %d\n", (int)state->pid, state->name, status); } +done: TALLOC_FREE(state); + if (smbd_max_processes > 0) { + if (connections_active < 1) { + DBG_ERR("Number of active connections " + "less than 1 (%d)\n", + connections_active); + connections_active = 1; + } + connections_active--; + } return; } @@ -282,6 +294,21 @@ static void standard_accept_connection( return; } + if (smbd_max_processes > 0) { + if (connections_active >= smbd_max_processes) { + DBG_ERR("(%d) connections already active, " + "maximum is (%d). Dropping request\n", + connections_active, + smbd_max_processes); + /* + * Drop the connection as we're overloaded at the moment + */ + talloc_free(sock2); + return; + } + connections_active++; + } + state = setup_standard_child_pipe(ev, NULL); if (state == NULL) { return; @@ -486,6 +513,8 @@ static void standard_new_task(struct tevent_context *ev, service_details->inhibit_fork_on_accept; proc_ctx->forked_on_accept = false; + smbd_max_processes = lpcfg_max_smbd_processes(lp_ctx); + /* setup this new task. Cluster ID is PID based for this process model */ task = new_task(ev, lp_ctx, cluster_id(pid, 0), private_data, proc_ctx); /* |