diff options
author | Tim Beale <timbeale@catalyst.net.nz> | 2018-11-22 10:35:01 +1300 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2018-11-23 11:40:49 +0100 |
commit | fabc3c9d3827fd30d7cec674105218c97c04e801 (patch) | |
tree | c9ff78debfa59d38ca6a7648b05ffa6bff673968 /source4/smbd | |
parent | 830a65020475886af6bd1edc347c0a2b96d14a38 (diff) | |
download | samba-fabc3c9d3827fd30d7cec674105218c97c04e801.tar.gz |
source4 smbd prefork: Add code comments
Add some comments to the prefork code explaining what's going on.
Signed-off-by: Tim Beale <timbeale@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Fri Nov 23 11:40:49 CET 2018 on sn-devel-144
Diffstat (limited to 'source4/smbd')
-rw-r--r-- | source4/smbd/process_prefork.c | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/source4/smbd/process_prefork.c b/source4/smbd/process_prefork.c index c62f08fbbfe..49446d23b5a 100644 --- a/source4/smbd/process_prefork.c +++ b/source4/smbd/process_prefork.c @@ -22,7 +22,16 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ - +/* + * The pre-fork process model distributes the server workload amongst several + * designated worker threads (e.g. 'prefork-worker-ldap-0', + * 'prefork-worker-ldap-1', etc). The number of worker threads is controlled + * by the 'prefork children' conf setting. The worker threads are controlled + * by a prefork master process (e.g. 'prefork-master-ldap'). The prefork master + * doesn't handle the server workload (i.e. processing messages) itself, but is + * responsible for restarting workers if they exit unexpectedly. The top-level + * samba process is responsible for restarting the master process if it exits. + */ #include "includes.h" #include <unistd.h> @@ -181,8 +190,10 @@ static void irpc_cleanup( } /* - handle EOF on the parent-to-all-children pipe in the child -*/ + * handle EOF on the parent-to-all-children pipe in the child, i.e. + * the parent has died and its end of the pipe has been closed. + * The child handles this by exiting as well. + */ static void prefork_pipe_handler(struct tevent_context *event_ctx, struct tevent_fd *fde, uint16_t flags, void *private_data) @@ -209,7 +220,7 @@ static void prefork_pipe_handler(struct tevent_context *event_ctx, /* - * called to create a new server task + * Called by the top-level samba process to create a new prefork master process */ static void prefork_fork_master( struct tevent_context *ev, @@ -354,6 +365,13 @@ static void prefork_fork_master( } DBG_NOTICE("Forking %d %s worker processes\n", num_children, service_name); + + /* + * the prefork master creates its own control pipe, so the prefork + * workers can detect if the master exits (in which case an EOF gets + * written). (Whereas from_parent_fd is the control pipe from the + * top-level process that the prefork master listens on) + */ { int ret; ret = pipe(control_pipe); @@ -386,8 +404,11 @@ static void prefork_fork_master( /* We need to keep ev2 until we're finished for the messaging to work */ TALLOC_FREE(ev2); exit(0); - } + +/* + * Restarts a child process if it exits unexpectedly + */ static void prefork_restart(struct tevent_context *ev, struct restart_context *rc) { @@ -396,6 +417,11 @@ static void prefork_restart(struct tevent_context *ev, unsigned restart_delay = rc->restart_delay; unsigned default_value = 0; + /* + * If the child process is constantly exiting, then restarting it can + * consume a lot of resources. In which case, we want to backoff a bit + * before respawning it + */ default_value = lpcfg_prefork_backoff_increment(rc->lp_ctx); backoff = lpcfg_parm_int(rc->lp_ctx, NULL, @@ -447,6 +473,7 @@ static void prefork_restart(struct tevent_context *ev, &pd); } } + /* handle EOF on the child pipe in the parent, so we know when a process terminates without using SIGCHLD or waiting on all possible pids. @@ -585,6 +612,9 @@ static void setup_handlers( } } +/* + * Called by the prefork master to create a new prefork worker process + */ static void prefork_fork_worker(struct task_server *task, struct tevent_context *ev, struct tevent_context *ev2, @@ -609,6 +639,10 @@ static void prefork_fork_worker(struct task_server *task, int fd = tfork_event_fd(w); struct restart_context *rc = NULL; + /* + * we're the parent (prefork master), so store enough info to + * restart the worker/child if it exits unexpectedly + */ rc = talloc_zero(ev, struct restart_context); if (rc == NULL) { smb_panic("OOM allocating restart context\n"); @@ -637,8 +671,15 @@ static void prefork_fork_worker(struct task_server *task, } tevent_fd_set_auto_close(fde); } else { + + /* + * we're the child (prefork-worker). We never write to the + * control pipe, but listen on the read end in case our parent + * (the pre-fork master) exits + */ close(control_pipe[1]); setup_handlers(ev2, lp_ctx, control_pipe[0]); + /* * tfork uses malloc */ |