service-monitor.c revision d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76
/* 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-log.h"
#include "service-monitor.h"
#include <unistd.h>
#include <syslog.h>
{
struct master_status status;
struct service_process *process;
switch (ret) {
case 0:
return;
case -1:
return;
default:
i_error("service(%s): child %s sent partial status update "
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.. */
i_error("service(%s): Ignoring invalid update from child %s "
return;
}
/* first status notification */
}
return;
/* process started servicing requests */
process->total_count +=
if (status.available_count == 0) {
if (--service->process_avail == 0)
}
process->idle_start = 0;
} else {
/* process finished servicing requests */
if (process->available_count == 0) {
if (service->process_avail++ == 0)
}
}
}
{
}
{
return;
i_error("service(%s): command startup failed, throttling",
}
{
/* we've reached our limits, new connections will have to
wait until there are more processes available */
return;
}
/* create a child process and let it accept() this connection */
else
}
{
struct service_listener *const *listeners;
unsigned int i, count;
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 */
i_error("service(%s): pipe() failed: %m",
continue;
}
service_status_input, services[i]);
}
}
}
{
int i;
for (i = 0; i < 2; i++) {
i_error("service(%s): close(%d) failed: %m",
}
}
}
}
{
unsigned int i, count;
for (i = 0; i < count; i++)
}
{
struct service_process *process;
int status;
i_error("waitpid() returned unknown PID %s",
continue;
}
if (status == 0) {
/* success */
if (service->listen_pending)
} else {
/* failure */
if (process->total_count == 0)
}
}
}