From: Gary Lockyer Date: Thu, 6 Sep 2018 19:04:48 +0000 (+1200) Subject: s4 smdb standard: Limit processes forked on accept. X-Git-Url: http://git.samba.org/?a=commitdiff_plain;h=f90cf49970a0edf4dce5d145726a04e798530a2e;p=metze%2Fsamba%2Fwip.git 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 Reviewed-by: Andrew Bartlett --- diff --git a/docs-xml/smbdotconf/tuning/maxsmbdprocesses.xml b/docs-xml/smbdotconf/tuning/maxsmbdprocesses.xml index a194a26a13c3..f5b1e4230be6 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 smbd 8 associated with him or her to handle connections to all shares from a given host. + + 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. + + 0 diff --git a/selftest/knownfail.d/process_limit b/selftest/knownfail.d/process_limit deleted file mode 100644 index db34dae23caf..000000000000 --- 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 b1cc7de155d0..139339c92ec2 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); /*