From a4887e250b84c321c75d54b9d3adf6fcf7c27fed Mon Sep 17 00:00:00 2001 From: Marc VanHeyningen Date: Tue, 5 May 2009 21:18:50 +0000 Subject: s3: Allow child processes to exit gracefully if we are out of fds When we run out of file descriptors for some reason, every new connection forks a child that immediately panics causing smbd to coredump. This seems unnecessarily harsh; with this code change we now catch that error and merely log a message about it and exit without the core dump. Signed-off-by: Tim Prouty --- source3/smbd/server.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'source3/smbd/server.c') diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 67836f785b..685b26fa1a 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -356,6 +356,7 @@ static void smbd_accept_connection(struct tevent_context *ev, pid = sys_fork(); if (pid == 0) { + NTSTATUS status = NT_STATUS_OK; /* Child code ... */ am_parent = 0; @@ -374,10 +375,15 @@ static void smbd_accept_connection(struct tevent_context *ev, talloc_free(s->parent); s = NULL; - if (!reinit_after_fork( - smbd_messaging_context(), - smbd_event_context(), - true)) { + status = reinit_after_fork(smbd_messaging_context(), + smbd_event_context(), true); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, + NT_STATUS_TOO_MANY_OPENED_FILES)) { + DEBUG(0,("child process cannot initialize " + "because too many files are open\n")); + goto exit; + } DEBUG(0,("reinit_after_fork() failed\n")); smb_panic("reinit_after_fork() failed"); } @@ -386,6 +392,7 @@ static void smbd_accept_connection(struct tevent_context *ev, smbd_setup_sig_hup_handler(); smbd_process(); + exit: exit_server_cleanly("end of child"); return; } else if (pid < 0) { @@ -1122,8 +1129,8 @@ extern void build_options(bool screen); if (is_daemon) pidfile_create("smbd"); - if (!reinit_after_fork(smbd_messaging_context(), - smbd_event_context(), false)) { + if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(), + smbd_event_context(), false))) { DEBUG(0,("reinit_after_fork() failed\n")); exit(1); } -- cgit