Mercurial > dovecot > original-hg > dovecot-1.2
changeset 4148:f60d73c96618 HEAD
If master process runs out of file descriptors, try to handle it more nicely
than getting into infinite loop.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 09 Apr 2006 17:36:03 +0300 |
parents | 674f328d5fdd |
children | b10fa8ba01ca |
files | src/master/auth-process.c src/master/login-process.c |
diffstat | 2 files changed, 73 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/master/auth-process.c Sun Apr 09 17:00:01 2006 +0300 +++ b/src/master/auth-process.c Sun Apr 09 17:36:03 2006 +0300 @@ -57,9 +57,11 @@ static struct timeout *to; static unsigned int auth_tag; static struct auth_process_group *process_groups; +static bool auth_stalled = FALSE; static void auth_process_destroy(struct auth_process *p); static int create_auth_worker(struct auth_process *process, int fd); +static void auth_processes_start_missing(void *context); void auth_process_request(struct auth_process *process, unsigned int login_pid, unsigned int login_id, void *context) @@ -720,6 +722,19 @@ } } +static void auth_processes_stall(void) +{ + if (auth_stalled) + return; + + i_error("Temporary failure in creating authentication processes, " + "slowing down for now"); + auth_stalled = TRUE; + + timeout_remove(&to); + to = timeout_add(60*1000, auth_processes_start_missing, NULL); +} + static void auth_processes_start_missing(void *context __attr_unused__) { @@ -733,8 +748,22 @@ for (group = process_groups; group != NULL; group = group->next) { count = group->process_count; - for (; count < group->set->count; count++) - (void)create_auth_process(group); + for (; count < group->set->count; count++) { + if (create_auth_process(group) < 0) { + auth_processes_stall(); + return; + } + } + } + + if (auth_stalled) { + /* processes were created successfully */ + i_info("Created authentication processes successfully, " + "unstalling"); + + auth_stalled = FALSE; + timeout_remove(&to); + to = timeout_add(1000, auth_processes_start_missing, NULL); } }
--- a/src/master/login-process.c Sun Apr 09 17:00:01 2006 +0300 +++ b/src/master/login-process.c Sun Apr 09 17:36:03 2006 +0300 @@ -46,6 +46,7 @@ static unsigned int auth_id_counter, login_pid_counter; static struct timeout *to; static struct io *io_listen; +static bool logins_stalled = FALSE; static struct hash_table *processes; static struct login_group *login_groups; @@ -53,6 +54,7 @@ static void login_process_destroy(struct login_process *p); static void login_process_unref(struct login_process *p); static bool login_process_init_group(struct login_process *p); +static void login_processes_start_missing(void *context); static void login_group_create(struct settings *set) { @@ -588,15 +590,17 @@ } } -static void login_group_start_missings(struct login_group *group) +static int login_group_start_missings(struct login_group *group) { if (!group->set->login_process_per_connection) { /* create max. one process every second, that way if it keeps dying all the time we don't eat all cpu with fork()ing. */ if (group->listening_processes < - group->set->login_processes_count) - (void)create_login_process(group); - return; + group->set->login_processes_count) { + if (create_login_process(group) < 0) + return -1; + } + return 0; } /* we want to respond fast when multiple clients are connecting @@ -621,10 +625,27 @@ group->set->login_max_processes_count; } - while (group->listening_processes < group->wanted_processes_count) - (void)create_login_process(group); + while (group->listening_processes < group->wanted_processes_count) { + if (create_login_process(group) < 0) + return -1; + } + return 0; } +static void login_processes_stall(void) +{ + if (logins_stalled) + return; + + i_error("Temporary failure in creating login processes, " + "slowing down for now"); + logins_stalled = TRUE; + + timeout_remove(&to); + to = timeout_add(60*1000, login_processes_start_missing, NULL); +} + + static void login_processes_start_missing(void *context __attr_unused__) { @@ -633,8 +654,21 @@ if (login_groups == NULL) login_process_groups_create(); - for (group = login_groups; group != NULL; group = group->next) - login_group_start_missings(group); + for (group = login_groups; group != NULL; group = group->next) { + if (login_group_start_missings(group) < 0) { + login_processes_stall(); + return; + } + } + + if (logins_stalled) { + /* processes were created successfully */ + i_info("Created login processes successfully, unstalling"); + + logins_stalled = FALSE; + timeout_remove(&to); + to = timeout_add(1000, login_processes_start_missing, NULL); + } } static int login_process_send_env(struct login_process *p)