core: change default trigger limits for socket units

Let's lower the default values a bit, and pick different defaults for
Accept=yes and Accept=no sockets.

Fixes: #3167
This commit is contained in:
Lennart Poettering 2016-05-05 13:39:31 +02:00
parent 37818090c9
commit 1f15ce2846
2 changed files with 28 additions and 7 deletions

View file

@ -814,13 +814,14 @@
<listitem><para>Configures a limit on how often this socket unit my be activated within a specific time <listitem><para>Configures a limit on how often this socket unit my be activated within a specific time
interval. The <varname>TriggerLimitIntervalSec=</varname> may be used to configure the length of the time interval. The <varname>TriggerLimitIntervalSec=</varname> may be used to configure the length of the time
interval in the usual time units <literal>us</literal>, <literal>ms</literal>, <literal>s</literal>, interval in the usual time units <literal>us</literal>, <literal>ms</literal>, <literal>s</literal>,
<literal>min</literal>, <literal>h</literal>, … and defaults to 5s (See <literal>min</literal>, <literal>h</literal>, … and defaults to 2s (See
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details on <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details on
the various time units available). The <varname>TriggerLimitBurst=</varname> setting takes an integer value and the various time units understood). The <varname>TriggerLimitBurst=</varname> setting takes a positive integer
specifies the numer of permitted activations per time interval, and defaults to 2500 (thus by default value and specifies the number of permitted activations per time interval, and defaults to 200 for
permitting 2500 activations per 5s). Set either to 0 to disable any form of trigger rate limiting. If the limit <varname>Accept=yes</varname> sockets (thus by default permitting 200 activations per 2s), and 20 otherwise (20
is hit, the socket unit is placed into a failure mode, and will not be connectible anymore until activations per 2s). Set either to 0 to disable any form of trigger rate limiting. If the limit is hit, the
restarted. Note that this limit is enforced before the service activation is enqueued.</para></listitem> socket unit is placed into a failure mode, and will not be connectible anymore until restarted. Note that this
limit is enforced before the service activation is enqueued.</para></listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>

View file

@ -100,7 +100,8 @@ static void socket_init(Unit *u) {
s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID; s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
RATELIMIT_INIT(s->trigger_limit, 5*USEC_PER_SEC, 2500); s->trigger_limit.interval = USEC_INFINITY;
s->trigger_limit.burst = (unsigned) -1;
} }
static void socket_unwatch_control_pid(Socket *s) { static void socket_unwatch_control_pid(Socket *s) {
@ -328,6 +329,25 @@ static int socket_add_extras(Socket *s) {
assert(s); assert(s);
/* Pick defaults for the trigger limit, if nothing was explicitly configured. We pick a relatively high limit
* in Accept=yes mode, and a lower limit for Accept=no. Reason: in Accept=yes mode we are invoking accept()
* ourselves before the trigger limit can hit, thus incoming connections are taken off the socket queue quickly
* and reliably. This is different for Accept=no, where the spawned service has to take the incoming traffic
* off the queues, which it might not necessarily do. Moreover, while Accept=no services are supposed to
* process whatever is queued in one go, and thus should normally never have to be started frequently. This is
* different for Accept=yes where each connection is processed by a new service instance, and thus frequent
* service starts are typical. */
if (s->trigger_limit.interval == USEC_INFINITY)
s->trigger_limit.interval = 2 * USEC_PER_SEC;
if (s->trigger_limit.burst == (unsigned) -1) {
if (s->accept)
s->trigger_limit.burst = 200;
else
s->trigger_limit.burst = 20;
}
if (have_non_accept_socket(s)) { if (have_non_accept_socket(s)) {
if (!UNIT_DEREF(s->service)) { if (!UNIT_DEREF(s->service)) {