1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

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 f2a9bbc317)
This commit is contained in:
Andrew Tridgell 2004-10-29 07:00:14 +00:00 committed by Gerald (Jerry) Carter
parent bc24603e41
commit 0caeda53d3
3 changed files with 50 additions and 2 deletions

View File

@ -260,6 +260,28 @@ int socket_get_fd(struct socket_context *sock)
return sock->ops->get_fd(sock);
}
/*
call dup() on a socket, and close the old fd. This is used to change
the fd to the lowest available number, to make select() more
efficient (select speed depends on the maxiumum fd number passed to
it)
*/
NTSTATUS socket_dup(struct socket_context *sock)
{
int fd;
if (sock->fd == -1) {
return NT_STATUS_INVALID_HANDLE;
}
fd = dup(sock->fd);
if (fd == -1) {
return map_nt_error_from_unix(errno);
}
close(sock->fd);
sock->fd = fd;
return NT_STATUS_OK;
}
const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type)
{
if (strcmp("ip", name) == 0 ||

View File

@ -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) {

View File

@ -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;
}
}
}