diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-10-29 07:00:14 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:05:00 -0500 |
commit | 0caeda53d37740d18b38e6d37d0ecef8c6336820 (patch) | |
tree | 52ca50fa644464ca50f1a6c14b83b8ce19b3d2d5 /source4/smbd | |
parent | bc24603e41804a1d54ff85f9114f0288a03483fa (diff) | |
download | samba-0caeda53d37740d18b38e6d37d0ecef8c6336820.tar.gz samba-0caeda53d37740d18b38e6d37d0ecef8c6336820.tar.bz2 samba-0caeda53d37740d18b38e6d37d0ecef8c6336820.zip |
r3356: in the standard process model we need to make sure we close all
listening sockets after the fork to prevent the child still listening
on incoming requests.
I have also added an optimisation where we use dup()/close() to lower
the file descriptor number of the new socket to the lowest possible
after closing our listening sockets. This keeps the max fd num passed
to select() low, which makes a difference to the speed of select().
(This used to be commit f2a9bbc317ba86ebe87c3ca27a3a0192de91014d)
Diffstat (limited to 'source4/smbd')
-rw-r--r-- | source4/smbd/process_standard.c | 9 | ||||
-rw-r--r-- | source4/smbd/service.c | 21 |
2 files changed, 28 insertions, 2 deletions
diff --git a/source4/smbd/process_standard.c b/source4/smbd/process_standard.c index 106be77925..9b5547ce54 100644 --- a/source4/smbd/process_standard.c +++ b/source4/smbd/process_standard.c @@ -34,7 +34,8 @@ static void standard_model_startup(void) /* called when a listening socket becomes readable */ -static void standard_accept_connection(struct event_context *ev, struct fd_event *srv_fde, time_t t, uint16_t flags) +static void standard_accept_connection(struct event_context *ev, struct fd_event *srv_fde, + time_t t, uint16_t flags) { NTSTATUS status; struct socket_context *sock; @@ -63,7 +64,11 @@ static void standard_accept_connection(struct event_context *ev, struct fd_event /* Child code ... */ /* close all the listening sockets */ - event_remove_fd_all_handler(ev, standard_accept_connection); + service_close_listening_sockets(server_socket->service->srv_ctx); + + /* we don't care if the dup fails, as its only a select() + speed optimisation */ + socket_dup(sock); /* tdb needs special fork handling */ if (tdb_reopen_all() == -1) { diff --git a/source4/smbd/service.c b/source4/smbd/service.c index ac46992261..ca5f5e7531 100644 --- a/source4/smbd/service.c +++ b/source4/smbd/service.c @@ -77,6 +77,8 @@ struct server_context *server_service_startup(const char *model) /* TODO: service_init() should return a result */ service->ops->service_init(service, model_ops); + + DLIST_ADD(srv_ctx->service_list, service); } return srv_ctx; @@ -328,3 +330,22 @@ BOOL server_service_init(void) DEBUG(3,("SERVER SERVICE subsystem version %d initialised\n", SERVER_SERVICE_VERSION)); return True; } + + +/* + close all listening sockets. This is called by process models that fork, to + ensure that the listen sockets from the parent are closed +*/ +void service_close_listening_sockets(struct server_context *srv_ctx) +{ + struct server_service *svc; + for (svc=srv_ctx->service_list;svc;svc=svc->next) { + struct server_socket *sock; + for (sock=svc->socket_list;sock;sock=sock->next) { + event_remove_fd(sock->event.ctx, sock->event.fde); + sock->event.fde = NULL; + socket_destroy(sock->socket); + sock->socket = NULL; + } + } +} |