24
24
#define SERVICE_DROP_TIMEOUT_MSECS (10*1000)
25
25
#define MAX_DIE_WAIT_SECS 5
26
26
#define SERVICE_MAX_EXIT_FAILURES_IN_SEC 10
27
#define SERVICE_PREFORK_MAX_AT_ONCE 10
28
29
static void service_monitor_start_extra_avail(struct service *service);
29
30
static void service_status_more(struct service_process *process,
81
82
service->process_count == service->process_limit)
82
83
service_login_notify(service, TRUE);
84
/* we may need to start more */
85
/* we may need to start more */
85
86
service_monitor_start_extra_avail(service);
86
87
service_monitor_listen_start(service);
101
102
process->idle_start = ioloop_time;
102
103
if (service->process_avail > service->set->process_min_avail &&
103
104
process->to_idle == NULL &&
104
service->idle_kill != -1U) {
105
service->idle_kill != UINT_MAX) {
105
106
/* we have more processes than we really need.
106
107
add a bit of randomness so that we don't send the
107
108
signal to all of them at once */
123
124
struct service_process *process;
125
process = hash_table_lookup(service_pids, &status->pid);
126
process = hash_table_lookup(service_pids, POINTER_CAST(status->pid));
126
127
if (process == NULL) {
127
128
/* we've probably wait()ed it away already. ignore */
237
238
static void service_drop_connections(struct service_listener *l)
239
240
struct service *service = l->service;
241
const char *limit_name;
240
242
unsigned int limit;
243
245
if (service->last_drop_warning +
244
246
SERVICE_DROP_WARN_INTERVAL_SECS < ioloop_time) {
245
247
service->last_drop_warning = ioloop_time;
246
limit = service->process_limit > 1 ?
247
service->process_limit : service->client_limit;
248
if (service->process_limit > 1) {
249
limit_name = "process_limit";
250
limit = service->process_limit;
251
} else if (service->set->service_count == 1) {
252
i_assert(service->client_limit == 1);
253
limit_name = "client_limit/service_count";
256
limit_name = "client_limit";
257
limit = service->client_limit;
248
259
i_warning("service(%s): %s (%u) reached, "
249
260
"client connections are being dropped",
251
service->process_limit > 1 ?
252
"process_limit" : "client_limit", limit);
261
service->set->name, limit_name, limit);
255
264
if (service->type == SERVICE_TYPE_LOGIN) {
294
303
service_monitor_listen_stop(service);
297
static void service_monitor_start_extra_avail(struct service *service)
307
service_monitor_start_count(struct service *service, unsigned int limit)
299
309
unsigned int i, count;
301
if (service->process_avail >= service->set->process_min_avail ||
302
service->list->destroying)
311
i_assert(service->set->process_min_avail >= service->process_avail);
305
313
count = service->set->process_min_avail - service->process_avail;
306
314
if (service->process_count + count > service->process_limit)
307
315
count = service->process_limit - service->process_count;
309
319
for (i = 0; i < count; i++) {
310
320
if (service_process_create(service) == NULL) {
316
326
/* we created some processes, they'll do the listening now */
317
327
service_monitor_listen_stop(service);
332
static void service_monitor_prefork_timeout(struct service *service)
334
/* don't prefork more processes if other more important processes had
335
been forked while we were waiting for this timeout (= master seems
337
if (service->list->fork_counter != service->prefork_counter) {
338
service->prefork_counter = service->list->fork_counter;
341
if (service->process_avail < service->set->process_min_avail) {
342
if (service_monitor_start_count(service, SERVICE_PREFORK_MAX_AT_ONCE) &&
343
service->process_avail < service->set->process_min_avail)
346
timeout_remove(&service->to_prefork);
349
static void service_monitor_start_extra_avail(struct service *service)
351
if (service->process_avail >= service->set->process_min_avail ||
352
service->list->destroying)
355
if (service->process_avail == 0) {
356
/* quickly start one process now */
357
if (!service_monitor_start_count(service, 1))
359
if (service->process_avail >= service->set->process_min_avail)
362
if (service->to_prefork == NULL) {
363
/* ioloop handles timeouts before fds (= SIGCHLD callback),
364
so let the first timeout handler call simply update the fork
365
counter and the second one check if we're busy or not. */
366
service->to_prefork =
367
timeout_add_short(0, service_monitor_prefork_timeout, service);
321
371
static void service_monitor_listen_start_force(struct service *service)
483
534
if (service->to_throttle != NULL)
484
535
timeout_remove(&service->to_throttle);
536
if (service->to_prefork != NULL)
537
timeout_remove(&service->to_prefork);
487
540
static void services_monitor_wait(struct service_list *service_list)
565
618
bool service_stopped, throttle;
567
620
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
568
process = hash_table_lookup(service_pids, &pid);
621
process = hash_table_lookup(service_pids, POINTER_CAST(pid));
569
622
if (process == NULL) {
570
623
i_error("waitpid() returned unknown PID %s",
601
654
service_stopped = service->status_fd[0] == -1;
602
655
if (!service_stopped) {
603
656
service_monitor_start_extra_avail(service);
657
/* if there are no longer listening processes,
658
start listening for more */
604
659
if (service->to_throttle == NULL)
605
660
service_monitor_listen_start(service);