service-monitor.c revision 3b959c98e05e780de2a063a4a9d8d393dc61ed58
/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
#include "common.h"
#include "array.h"
#include "ioloop.h"
#include "fd-close-on-exec.h"
#include "hash.h"
#include "service.h"
#include "service-process.h"
#include "service-process-notify.h"
#include "service-log.h"
#include "service-monitor.h"
#include <unistd.h>
#include <syslog.h>
#define SERVICE_STARTUP_FAILURE_THROTTLE_SECS 60
{
struct master_status status;
struct service_process *process;
switch (ret) {
case 0:
return;
case -1:
return;
default:
return;
case sizeof(status):
break;
}
/* we've probably wait()ed it away already. ignore */
return;
}
/* a) Process was closed and another process was created with
the same PID, but we're still receiving status update from
the old process.
b) Some process is trying to corrupt our internal state by
trying to pretend to be someone else. We could use stronger
randomness here, but the worst they can do is DoS and there
are already more serious problems if someone is able to do
this.. */
return;
}
/* first status notification */
}
return;
/* process started servicing requests */
process->total_count +=
if (status.available_count == 0) {
service->process_avail--;
}
process->idle_start = 0;
} else {
/* process finished servicing requests */
if (process->available_count == 0) {
if (service->process_avail++ == 0)
}
}
}
{
return;
}
{
/* we've reached our limits, new connections will have to
wait until there are more processes available */
i_warning("service(%s): process_limit reached, "
return;
}
/* create a child process and let it accept() this connection */
else
}
{
unsigned int i, count;
return;
for (i = 0; i < count; i++) {
break;
}
}
/* we created some processes, they'll do the listening now */
}
}
{
struct service_listener *const *listeners;
unsigned int i, count;
if (service->process_avail > 0)
return;
for (i = 0; i < count; i++) {
}
}
}
{
struct service_listener *const *listeners;
unsigned int i, count;
for (i = 0; i < count; i++) {
struct service_listener *l = listeners[i];
}
}
{
unsigned int i, count;
for (i = 0; i < count; i++) {
/* we haven't yet created status pipe */
continue;
}
service_status_input, services[i]);
}
}
}
}
{
int i;
for (i = 0; i < 2; i++) {
"close(status fd) failed: %m");
}
}
}
}
{
unsigned int i, count;
for (i = 0; i < count; i++)
}
{
if (process->total_count == 0)
}
void services_monitor_reap_children(void)
{
struct service_process *process;
int status;
bool service_destroyed;
i_error("waitpid() returned unknown PID %s",
continue;
}
if (status == 0) {
/* success */
if (service->listen_pending)
} else {
}
if (!service_destroyed) {
}
}
}