dovecot-2.0: master: Added process_min_avail setting for services.
dovecot at dovecot.org
dovecot at dovecot.org
Fri Sep 4 22:44:42 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/af7f0be02d3b
changeset: 9872:af7f0be02d3b
user: Timo Sirainen <tss at iki.fi>
date: Fri Sep 04 15:44:36 2009 -0400
description:
master: Added process_min_avail setting for services.
diffstat:
4 files changed, 75 insertions(+), 32 deletions(-)
src/master/master-settings.c | 59 ++++++++++++++++++++++++------------------
src/master/master-settings.h | 1
src/master/service-monitor.c | 43 ++++++++++++++++++++++++++----
src/master/service-process.c | 4 +-
diffs (216 lines):
diff -r 8a38b5b82a1d -r af7f0be02d3b src/master/master-settings.c
--- a/src/master/master-settings.c Fri Sep 04 15:00:37 2009 -0400
+++ b/src/master/master-settings.c Fri Sep 04 15:44:36 2009 -0400
@@ -100,6 +100,7 @@ static struct setting_define service_set
DEF(SET_BOOL, drop_priv_before_exec),
+ DEF(SET_UINT, process_min_avail),
DEF(SET_UINT, process_limit),
DEF(SET_UINT, client_limit),
DEF(SET_UINT, service_count),
@@ -131,6 +132,7 @@ static struct service_settings service_d
MEMBER(drop_priv_before_exec) FALSE,
+ MEMBER(process_min_avail) 0,
MEMBER(process_limit) (unsigned int)-1,
MEMBER(client_limit) 0,
MEMBER(service_count) 0,
@@ -285,52 +287,61 @@ master_settings_verify(void *_set, pool_
}
services = array_get(&set->services, &count);
for (i = 0; i < count; i++) {
- if (*services[i]->name == '\0') {
+ struct service_settings *service = services[i];
+
+ if (*service->name == '\0') {
*error_r = t_strdup_printf(
"Service #%d is missing name", i);
return FALSE;
}
- if (*services[i]->type != '\0' &&
- strcmp(services[i]->type, "log") != 0 &&
- strcmp(services[i]->type, "config") != 0 &&
- strcmp(services[i]->type, "anvil") != 0 &&
- strcmp(services[i]->type, "auth") != 0 &&
- strcmp(services[i]->type, "auth-source") != 0) {
+ if (*service->type != '\0' &&
+ strcmp(service->type, "log") != 0 &&
+ strcmp(service->type, "config") != 0 &&
+ strcmp(service->type, "anvil") != 0 &&
+ strcmp(service->type, "auth") != 0 &&
+ strcmp(service->type, "auth-source") != 0) {
*error_r = t_strconcat("Unknown service type: ",
- services[i]->type, NULL);
+ service->type, NULL);
return FALSE;
}
for (j = 0; j < i; j++) {
- if (strcmp(services[i]->name, services[j]->name) == 0) {
+ if (strcmp(service->name, services[j]->name) == 0) {
*error_r = t_strdup_printf(
"Duplicate service name: %s",
- services[i]->name);
+ service->name);
return FALSE;
}
}
}
for (i = 0; i < count; i++) {
- if (*services[i]->executable != '/') {
- services[i]->executable =
+ struct service_settings *service = services[i];
+
+ if (*service->executable != '/') {
+ service->executable =
p_strconcat(pool, set->libexec_dir, "/",
- services[i]->executable, NULL);
- }
- if (*services[i]->chroot != '/' &&
- *services[i]->chroot != '\0') {
- services[i]->chroot =
+ service->executable, NULL);
+ }
+ if (*service->chroot != '/' && *service->chroot != '\0') {
+ service->chroot =
p_strconcat(pool, set->base_dir, "/",
- services[i]->chroot, NULL);
- }
- if (services[i]->drop_priv_before_exec &&
- *services[i]->chroot != '\0') {
+ service->chroot, NULL);
+ }
+ if (service->drop_priv_before_exec &&
+ *service->chroot != '\0') {
*error_r = t_strdup_printf("service(%s): "
"drop_priv_before_exec=yes can't be "
- "used with chroot", services[i]->name);
+ "used with chroot", service->name);
return FALSE;
}
- fix_file_listener_paths(&services[i]->unix_listeners,
+ if (service->process_min_avail > service->process_limit) {
+ *error_r = t_strdup_printf("service(%s): "
+ "process_min_avail is higher than process_limit",
+ service->name);
+ return FALSE;
+ }
+ fix_file_listener_paths(&service->unix_listeners,
pool, set->base_dir);
- fix_file_listener_paths(&services[i]->fifo_listeners,
+ fix_file_listener_paths(&service->fifo_listeners,
pool, set->base_dir);
}
set->protocols_split = p_strsplit(pool, set->protocols, " ");
diff -r 8a38b5b82a1d -r af7f0be02d3b src/master/master-settings.h
--- a/src/master/master-settings.h Fri Sep 04 15:00:37 2009 -0400
+++ b/src/master/master-settings.h Fri Sep 04 15:44:36 2009 -0400
@@ -31,6 +31,7 @@ struct service_settings {
bool drop_priv_before_exec;
+ unsigned int process_min_avail;
unsigned int process_limit;
unsigned int client_limit;
unsigned int service_count;
diff -r 8a38b5b82a1d -r af7f0be02d3b src/master/service-monitor.c
--- a/src/master/service-monitor.c Fri Sep 04 15:00:37 2009 -0400
+++ b/src/master/service-monitor.c Fri Sep 04 15:44:36 2009 -0400
@@ -17,7 +17,7 @@
#define SERVICE_STARTUP_FAILURE_THROTTLE_SECS 60
-void service_monitor_stop(struct service *service);
+static void service_monitor_start_extra_avail(struct service *service);
static void service_status_input(struct service *service)
{
@@ -79,8 +79,10 @@ static void service_status_input(struct
process->available_count - status.available_count;
if (status.available_count == 0) {
i_assert(service->process_avail > 0);
- if (--service->process_avail == 0)
- service_monitor_listen_start(service);
+ service->process_avail--;
+
+ service_monitor_start_extra_avail(service);
+ service_monitor_listen_start(service);
}
process->idle_start = 0;
} else {
@@ -127,10 +129,36 @@ static void service_accept(struct servic
service_monitor_listen_stop(service);
}
+static void service_monitor_start_extra_avail(struct service *service)
+{
+ unsigned int i, count;
+
+ if (service->process_avail >= service->set->process_min_avail)
+ return;
+
+ count = service->set->process_min_avail - service->process_avail;
+ if (service->process_count + count > service->process_limit)
+ count = service->process_limit - service->process_count;
+
+ for (i = 0; i < count; i++) {
+ if (service_process_create(service, NULL, NULL) == NULL) {
+ service_monitor_throttle(service);
+ break;
+ }
+ }
+ if (i > 0 && service->listening) {
+ /* we created some processes, they'll do the listening now */
+ service_monitor_listen_stop(service);
+ }
+}
+
void service_monitor_listen_start(struct service *service)
{
struct service_listener *const *listeners;
unsigned int i, count;
+
+ if (service->process_avail > 0)
+ return;
service->listening = TRUE;
service->listen_pending = FALSE;
@@ -185,8 +213,10 @@ void services_monitor_start(struct servi
service_status_input, services[i]);
}
- if (services[i]->status_fd[0] != -1)
+ if (services[i]->status_fd[0] != -1) {
+ service_monitor_start_extra_avail(services[i]);
service_monitor_listen_start(services[i]);
+ }
}
if (service_process_create(service_list->log, NULL, NULL) != NULL)
@@ -265,8 +295,9 @@ void services_monitor_reap_children(void
service_process_failure(process, status);
}
service_process_destroy(process);
-
- if (service->process_avail == 0 && service->to_throttle == NULL)
+ service_monitor_start_extra_avail(service);
+
+ if (service->to_throttle == NULL)
service_monitor_listen_start(service);
}
}
diff -r 8a38b5b82a1d -r af7f0be02d3b src/master/service-process.c
--- a/src/master/service-process.c Fri Sep 04 15:00:37 2009 -0400
+++ b/src/master/service-process.c Fri Sep 04 15:44:36 2009 -0400
@@ -451,8 +451,8 @@ service_process_create(struct service *s
int fd[2];
pid_t pid;
- if (!service->listening) {
- /* probably throttling service, don't create new processes */
+ if (service->to_throttle != NULL) {
+ /* throttling service, don't create new processes */
return NULL;
}
if (service->process_count >= service->process_limit) {
More information about the dovecot-cvs
mailing list