aboutsummaryrefslogtreecommitdiff
path: root/src/progman.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-11-24 18:34:29 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2009-11-24 18:34:29 +0200
commita7779d56bb758157e122a420a56f2d7b4475e554 (patch)
tree98241b97aa36b7713b2a76677b387cf214a1dbb7 /src/progman.c
parente6772c4d68849cfdb4547a59bc51cb6dd0acd2c6 (diff)
downloadpies-a7779d56bb758157e122a420a56f2d7b4475e554.tar.gz
pies-a7779d56bb758157e122a420a56f2d7b4475e554.tar.bz2
Implement inetd connection rate.
* src/pies.h (struct component): New member "max_rate". (default_max_rate): New extern. * src/progman.c (check_rate): New function. (check_spawn_rate, check_connection_rate): New functions. (prog_open_socket): New function. (prog_start): Rewrite using the above functions. (_prog_accept): Check connection rate. (progman_start): Special handling for inetd listeners. (progman_wake_sleeping): Likewise. * src/pies.c (default_max_rate): New global. (component_keywords): New keyword max-rate. (options): New option "rate". (parse_opt): Handle the new option. * src/inetd.c (inetd_conf_file): Set max_rate, instead of max_instances.
Diffstat (limited to 'src/progman.c')
-rw-r--r--src/progman.c178
1 files changed, 125 insertions, 53 deletions
diff --git a/src/progman.c b/src/progman.c
index 227b438..f0cc4c9 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -610,11 +610,92 @@ env_setup (char **env)
return new_env;
}
+static int
+check_rate (struct prog *prog, unsigned testtime, size_t max_count)
+{
+ time_t now;
+
+ time (&now);
+
+ if (prog->v.p.timestamp + testtime > now)
+ prog->v.p.failcount++;
+ else
+ {
+ prog->v.p.failcount = 0;
+ prog->v.p.timestamp = now;
+ }
+
+ if (prog->v.p.failcount > max_count)
+ {
+ prog->v.p.timestamp = now;
+ prog->v.p.status = status_sleeping;
+ recompute_alarm = 1;
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+check_spawn_rate (struct prog *prog)
+{
+ if (check_rate (prog, TESTTIME, MAXSPAWN))
+ {
+ logmsg (LOG_NOTICE,
+ ngettext ("%s is respawning too fast, disabled for %d minute",
+ "%s is respawning too fast, disabled for %d minutes",
+ SLEEPTIME / 60),
+ prog->tag, SLEEPTIME / 60);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+check_connection_rate (struct prog *prog)
+{
+ size_t max_rate = prog->v.p.comp->max_rate
+ ? prog->v.p.comp->max_rate : default_max_rate;
+ if (max_rate && check_rate (prog, 60, max_rate))
+ {
+ logmsg (LOG_NOTICE,
+ ngettext ("%s is starting too often, disabled for %d minute",
+ "%s is starting too often, disabled for %d minutes",
+ SLEEPTIME / 60),
+ prog->tag, SLEEPTIME / 60);
+ return 1;
+ }
+ return 0;
+}
+
+
+static int
+prog_open_socket (struct prog *prog)
+{
+ prog->v.p.socket = create_socket (prog->v.p.comp->socket_url,
+ prog->v.p.comp->socket_type,
+ prog->v.p.comp->privs.user,
+ prog->v.p.comp->umask);
+ if (prog->v.p.socket == -1)
+ {
+ prog->v.p.status = status_disabled;
+ return 1;
+ }
+ if (listen (prog->v.p.socket, 8))
+ {
+ logmsg (LOG_ERR, "listen: %s", strerror (errno));
+ close (prog->v.p.socket);
+ prog->v.p.socket = -1;
+ prog->v.p.status = status_disabled;
+ return 1;
+ }
+ return 0;
+}
+
static void
prog_start (struct prog *prog)
{
pid_t pid;
- time_t now;
int redir[2];
fd_set fdset;
@@ -629,35 +710,16 @@ prog_start (struct prog *prog)
if (prog_start_prerequisites (prog))
return;
- time (&now);
-
- if (prog->v.p.timestamp + TESTTIME > now)
- prog->v.p.failcount++;
- else
- {
- prog->v.p.failcount = 0;
- prog->v.p.timestamp = now;
- }
-
- if (prog->v.p.failcount > MAXSPAWN)
- {
- logmsg (LOG_NOTICE, ngettext (
- "%s is respawning too fast, disabled for %d minute",
- "%s is respawning too fast, disabled for %d minutes",
- SLEEPTIME / 60),
- prog->tag, SLEEPTIME / 60);
- prog->v.p.timestamp = now;
- prog->v.p.status = status_sleeping;
- recompute_alarm = 1;
- return;
- }
-
switch (prog->v.p.comp->mode)
{
case pies_comp_exec:
+ if (check_spawn_rate (prog))
+ return;
break;
case pies_comp_pass_fd:
+ if (check_spawn_rate (prog))
+ return;
debug (1, (_("unlinking %s"), prog->v.p.comp->pass_fd_socket));
if (unlink (prog->v.p.comp->pass_fd_socket) && errno != ENOENT)
{
@@ -666,26 +728,15 @@ prog_start (struct prog *prog)
strerror (errno));
return;
}
- /* fall through */
+ if (prog_open_socket (prog))
+ return;
+ break;
case pies_comp_accept:
- prog->v.p.socket = create_socket (prog->v.p.comp->socket_url,
- prog->v.p.comp->socket_type,
- prog->v.p.comp->privs.user,
- prog->v.p.comp->umask);
- if (prog->v.p.socket == -1)
- {
- prog->v.p.status = status_disabled;
- return;
- }
- if (listen (prog->v.p.socket, 8))
- {
- logmsg (LOG_ERR, "listen: %s", strerror (errno));
- close (prog->v.p.socket);
- prog->v.p.socket = -1;
- prog->v.p.status = status_disabled;
- return;
- }
+ if (check_spawn_rate (prog))
+ return;
+ if (prog_open_socket (prog))
+ return;
break;
case pies_comp_inetd:
@@ -897,6 +948,13 @@ _prog_accept (struct prog *p)
close (fd);
return 1;
}
+
+ if (check_connection_rate (p))
+ {
+ disable_socket (p->v.p.socket);
+ close (fd);
+ return 1;
+ }
pinst = register_prog0 (p->v.p.comp, -1);
pinst->v.p.socket = fd;
@@ -1192,10 +1250,17 @@ progman_start ()
recompute_alarm = 0;
debug (1, ("starting components"));
for (prog = proghead; prog; prog = prog->next)
- if (IS_COMPONENT (prog)
- && ((prog->v.p.status == status_enabled && prog->pid == 0)
- || prog->v.p.status == status_sleeping))
- prog_start (prog);
+ if (IS_COMPONENT (prog))
+ {
+ if (prog->v.p.comp->mode == pies_comp_inetd)
+ {
+ prog->v.p.status = status_listener;
+ enable_socket (prog->v.p.socket);
+ }
+ else if ((prog->v.p.status == status_enabled && prog->pid == 0)
+ || prog->v.p.status == status_sleeping)
+ prog_start (prog);
+ }
}
static void
@@ -1230,10 +1295,18 @@ progman_wake_sleeping (int onalrm)
case status_sleeping:
if (now - prog->v.p.timestamp >= SLEEPTIME)
{
- prog->v.p.status = status_enabled;
- prog->v.p.failcount = 0;
- prog->v.p.timestamp = 0;
- prog_start (prog);
+ if (prog->v.p.comp->mode == pies_comp_inetd)
+ {
+ prog->v.p.status = status_listener;
+ enable_socket (prog->v.p.socket);
+ }
+ else
+ {
+ prog->v.p.status = status_enabled;
+ prog->v.p.failcount = 0;
+ prog->v.p.timestamp = 0;
+ prog_start (prog);
+ }
}
/* If there is no alarm pending, recompute next alarm.
This allows to cope with eventual clock inaccuracies. */
@@ -1882,9 +1955,8 @@ progman_stop_component (const char *name)
default:
logmsg (LOG_INFO,
- _("stopping component `%s': "
- "component not started"),
- name);
+ _("stopping component `%s': component not started"),
+ name);
}
}
}

Return to:

Send suggestions and report system problems to the System administrator.