Skip to content

Commit

Permalink
s4 smdb standard: Limit processes forked on accept.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Andrew Bartlett <[email protected]>
  • Loading branch information
GaryWL authored and abartlet committed Nov 30, 2018
1 parent 2381b4f commit f90cf49
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 3 deletions.
7 changes: 7 additions & 0 deletions docs-xml/smbdotconf/tuning/maxsmbdprocesses.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
1 change: 0 additions & 1 deletion selftest/knownfail.d/process_limit

This file was deleted.

33 changes: 31 additions & 2 deletions source4/smbd/process_standard.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
/*
Expand Down

0 comments on commit f90cf49

Please sign in to comment.