]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
master: If an idling process seems stuck, log an error and disable it.
authorTimo Sirainen <tss@iki.fi>
Wed, 9 Jun 2010 20:09:34 +0000 (21:09 +0100)
committerTimo Sirainen <tss@iki.fi>
Wed, 9 Jun 2010 20:09:34 +0000 (21:09 +0100)
--HG--
branch : HEAD

src/master/service-monitor.c
src/master/service-process.h

index 9f4773ded549e5951fa916aaeecb926e36a03c3f..abd11123289035e4ae015e3a1b4f716b13b2ba04 100644 (file)
 #define SERVICE_DROP_WARN_INTERVAL_SECS 60
 
 static void service_monitor_start_extra_avail(struct service *service);
+static void service_status_more(struct service_process *process,
+                               const struct master_status *status);
 
 static void service_process_kill_idle(struct service_process *process)
 {
        struct service *service = process->service;
+       struct master_status status;
+
+       i_assert(process->available_count == service->client_limit);
 
        if (service->process_avail <= service->set->process_min_avail) {
                /* we don't have any extra idling processes anymore. */
                timeout_remove(&process->to_idle);
+       } else if (process->last_kill_sent > process->last_status_update+1) {
+               service_error(service, "Process %s is ignoring idle SIGINT",
+                             dec2str(process->pid));
+
+               /* assume this process is busy */
+               memset(&status, 0, sizeof(status));
+               service_status_more(process, &status);
+               process->available_count = 0;
        } else {
                if (kill(process->pid, SIGINT) < 0 && errno != ESRCH) {
                        service_error(service, "kill(%s, SIGINT) failed: %m",
                                      dec2str(process->pid));
                }
+               process->last_kill_sent = ioloop_time;
        }
 }
 
@@ -126,6 +140,7 @@ service_status_input_one(struct service *service,
                              "(UID=%u)", dec2str(status->pid), status->uid);
                return;
        }
+       process->last_status_update = ioloop_time;
 
        if (process->to_status != NULL) {
                /* first status notification */
index 4eefe65a02f4ec1b58b53aac82647fa9ea8ff175..04c3a6f33d7e1e87ac0b237fd8d476dd19bf5e2b 100644 (file)
@@ -20,6 +20,11 @@ struct service_process {
        /* kill process if it hits idle timeout */
        struct timeout *to_idle;
 
+       /* time when we last received a status update */
+       time_t last_status_update;
+       /* time when we last sent SIGINT to process */
+       time_t last_kill_sent;
+
        /* kill the process if it doesn't send initial status notification */
        struct timeout *to_status;