From 8b26cdbd2a949b02c0f4d94d0e157cdb9438d246 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 26 Apr 2016 20:26:15 +0200 Subject: core: introduce activation rate limiting for socket units This adds two new settings TriggerLimitIntervalSec= and TriggerLimitBurst= that define a rate limit for activation of socket units. When the limit is hit, the socket is is put into a failure mode. This is an alternative fix for #2467, since the original fix resulted in issue #2684. In a later commit the StartLimitInterval=/StartLimitBurst= rate limiter will be changed to be applied after any start conditions checks are made. This way, there are two separate rate limiters enforced: one at triggering time, before any jobs are queued with this patch, as well as the start limit that is moved again to be run immediately before the unit is activated. Condition checks are done in between the two, and thus no longer affect the start limit. --- man/systemd.socket.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'man') diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml index 2d6339680b..dc3fee5dfb 100644 --- a/man/systemd.socket.xml +++ b/man/systemd.socket.xml @@ -807,6 +807,22 @@ suffix. + + TriggerLimitIntervalSec= + TriggerLimitIntervalBurst= + + Configures a limit on how often this socket unit my be activated within a specific time + interval. The TriggerLimitIntervalSec= may be used to configure the length of the time + interval in the usual time units us, ms, s, + min, h, … and defaults to 5s (See + systemd.time7 for details on + the various time units available). The TriggerLimitBurst= setting takes an integer value and + specifies the numer of permitted activations per time interval, and defaults to 2500 (thus by default + permitting 2500 activations per 5s). Set either to 0 to disable any form of trigger rate limiting. If the limit + is hit, the 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. + + Check -- cgit v1.2.3-54-g00ecf From 7629ec4642b03517742d09b7303c204fddf82108 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 26 Apr 2016 20:34:33 +0200 Subject: core: move start ratelimiting check after condition checks With #2564 unit start rate limiting was moved from after the condition checks are to before they are made, in an attempt to fix #2467. This however resulted in #2684. However, with a previous commit a concept of per socket unit trigger rate limiting has been added, to fix #2467 more comprehensively, hence the start limit can be moved after the condition checks again, thus fixing #2684. Fixes: #2684 --- man/systemd.unit.xml | 3 ++- src/core/load-fragment-gperf.gperf.m4 | 1 + src/core/unit.c | 10 +++++----- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'man') diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 7993301167..9c869b9805 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -769,7 +769,8 @@ manually at a later point, from which point on, the restart logic is again activated. Note that systemctl reset-failed will cause the restart rate counter for a service to be flushed, which is useful if the administrator wants to manually start a unit and the start limit interferes with - that. + that. Note that this rate-limiting is enforced after any unit condition checks are executed, and hence unit + activations with failing conditions are not counted by this rate limiting. diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 32bb62fa63..5f4d66d64d 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -220,6 +220,7 @@ Service.TimeoutStartSec, config_parse_service_timeout, 0, Service.TimeoutStopSec, config_parse_service_timeout, 0, 0 Service.RuntimeMaxSec, config_parse_sec, 0, offsetof(Service, runtime_max_usec) Service.WatchdogSec, config_parse_sec, 0, offsetof(Service, watchdog_usec) +m4_dnl The following three only exist for compatibility, they moved into Unit, see above Service.StartLimitInterval, config_parse_sec, 0, offsetof(Unit, start_limit.interval) Service.StartLimitBurst, config_parse_unsigned, 0, offsetof(Unit, start_limit.burst) Service.StartLimitAction, config_parse_failure_action, 0, offsetof(Unit, start_limit_action) diff --git a/src/core/unit.c b/src/core/unit.c index cb79c7c6b1..6c0684225a 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1497,11 +1497,6 @@ int unit_start(Unit *u) { if (UNIT_IS_ACTIVE_OR_RELOADING(state)) return -EALREADY; - /* Make sure we don't enter a busy loop of some kind. */ - r = unit_start_limit_test(u); - if (r < 0) - return r; - /* Units that aren't loaded cannot be started */ if (u->load_state != UNIT_LOADED) return -EINVAL; @@ -1543,6 +1538,11 @@ int unit_start(Unit *u) { if (!UNIT_VTABLE(u)->start) return -EBADR; + /* Make sure we don't enter a busy loop of some kind. */ + r = unit_start_limit_test(u); + if (r < 0) + return r; + /* We don't suppress calls to ->start() here when we are * already starting, to allow this request to be used as a * "hurry up" call, for example when the unit is in some "auto -- cgit v1.2.3-54-g00ecf From f0367da7d1a61ad698a55d17b5c28ddce0dc265a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 26 Apr 2016 20:46:20 +0200 Subject: core: rename StartLimitInterval= to StartLimitIntervalSec= We generally follow the rule that for time settings we suffix the setting name with "Sec" to indicate the default unit if none is specified. The only exception was the rate limiting interval settings. Fix this, and keep the old names for compatibility. Do the same for journald's RateLimitInterval= setting --- catalog/systemd.be.catalog | 2 +- catalog/systemd.be@latin.catalog | 2 +- catalog/systemd.catalog | 2 +- catalog/systemd.da.catalog | 2 +- catalog/systemd.fr.catalog | 2 +- catalog/systemd.hu.catalog | 2 +- catalog/systemd.it.catalog | 2 +- catalog/systemd.ko.catalog | 2 +- catalog/systemd.pl.catalog | 2 +- catalog/systemd.pt_BR.catalog | 2 +- catalog/systemd.ru.catalog | 2 +- catalog/systemd.sr.catalog | 2 +- catalog/systemd.zh_CN.catalog | 2 +- catalog/systemd.zh_TW.catalog | 2 +- man/journald.conf.xml | 6 +++--- man/systemd-system.conf.xml | 6 +++--- man/systemd.unit.xml | 10 +++++----- src/core/dbus-manager.c | 3 ++- src/core/dbus-unit.c | 3 ++- src/core/load-fragment-gperf.gperf.m4 | 2 ++ src/core/main.c | 3 ++- src/core/system.conf | 2 +- src/core/user.conf | 2 +- src/journal/journald-gperf.gperf | 2 ++ src/journal/journald.conf | 2 +- 25 files changed, 38 insertions(+), 31 deletions(-) (limited to 'man') diff --git a/catalog/systemd.be.catalog b/catalog/systemd.be.catalog index be081d6efc..051f49492f 100644 --- a/catalog/systemd.be.catalog +++ b/catalog/systemd.be.catalog @@ -53,7 +53,7 @@ Documentation: man:journald.conf(5) Паведамленні іншых сэрвісаў засталіся. Мяжа, пасля якой паведамленні будуць адкінуты, наладжваецца з -дапамогай RateLimitInterval= і RateLimitBurst= у файле +дапамогай RateLimitIntervalSec= і RateLimitBurst= у файле /etc/systemd/journald.conf. Глядзіце journald.conf(5) для дэталей. -- e9bf28e6e834481bb6f48f548ad13606 diff --git a/catalog/systemd.be@latin.catalog b/catalog/systemd.be@latin.catalog index 382fdb8b04..6ab361aafb 100644 --- a/catalog/systemd.be@latin.catalog +++ b/catalog/systemd.be@latin.catalog @@ -53,7 +53,7 @@ Majcie na ŭvazie, što byli adkinuty paviedamliennia toĺki hetaha servisu. Paviedamlienni inšych servisaŭ zastalisia. Miaža, paslia jakoj paviedamlienni buduć adkinuty, naladžvajecca z -dapamohaj RateLimitInterval= i RateLimitBurst= u fajlie +dapamohaj RateLimitIntervalSec= i RateLimitBurst= u fajlie /etc/systemd/journald.conf. Hliadzicie journald.conf(5) dlia detaliej. -- e9bf28e6e834481bb6f48f548ad13606 diff --git a/catalog/systemd.catalog b/catalog/systemd.catalog index 077f182a5a..90929bca6d 100644 --- a/catalog/systemd.catalog +++ b/catalog/systemd.catalog @@ -66,7 +66,7 @@ Note that only messages from the service in question have been dropped, other services' messages are unaffected. The limits controlling when messages are dropped may be configured -with RateLimitInterval= and RateLimitBurst= in +with RateLimitIntervalSec= and RateLimitBurst= in /etc/systemd/journald.conf. See journald.conf(5) for details. -- e9bf28e6e834481bb6f48f548ad13606 diff --git a/catalog/systemd.da.catalog b/catalog/systemd.da.catalog index bd4d742d8a..093e8139da 100644 --- a/catalog/systemd.da.catalog +++ b/catalog/systemd.da.catalog @@ -52,7 +52,7 @@ Kun beskeder fra omtalte service er smidt væk. Beskeder fra andre services er ikke påvirket. Grænsen for hvornår beskeder bliver smidt væk kan konfigureres -med RateLimitInterval= og RateLimitBurst= i +med RateLimitIntervalSec= og RateLimitBurst= i /etc/systemd/journald.conf. Se journald.conf(5) for detaljer herom. -- e9bf28e6e834481bb6f48f548ad13606 diff --git a/catalog/systemd.fr.catalog b/catalog/systemd.fr.catalog index 03a457786f..d71c2902d7 100644 --- a/catalog/systemd.fr.catalog +++ b/catalog/systemd.fr.catalog @@ -51,7 +51,7 @@ Notez que seuls des messages de ce service ont été évincés, les messages des autres services ne sont pas affectés. Les limites définissant ce comportement peuvent être configurées avec les -paramètres RateLimitInterval= et RateLimitBurst= dans le fichier +paramètres RateLimitIntervalSec= et RateLimitBurst= dans le fichier /etc/systemd/journald.conf. Voir journald.conf(5) pour plus de détails. -- e9bf28e6e834481bb6f48f548ad13606 diff --git a/catalog/systemd.hu.catalog b/catalog/systemd.hu.catalog index 30d76916cc..68e8c2572e 100644 --- a/catalog/systemd.hu.catalog +++ b/catalog/systemd.hu.catalog @@ -51,7 +51,7 @@ Ne feledje, hogy csak a kérdéses szolgáltatás üzenetei kerültek eldobásra más szolgáltatások üzeneteit ez nem befolyásolja. Az üzenetek eldobását vezérlő korlátok az /etc/systemd/journald.conf -RateLimitInterval= és RateLimitBurst= beállításaival adhatók meg. +RateLimitIntervalSec= és RateLimitBurst= beállításaival adhatók meg. Részletekért lásd a journald.conf(5) man oldalt. -- e9bf28e6e834481bb6f48f548ad13606 diff --git a/catalog/systemd.it.catalog b/catalog/systemd.it.catalog index 861b92b74a..b6fca48221 100644 --- a/catalog/systemd.it.catalog +++ b/catalog/systemd.it.catalog @@ -46,7 +46,7 @@ Solo i messaggi del servizio indicato sono stati eliminati, i messaggi degli altri servizi rimangono invariati. I limiti oltre i quali i messaggi si eliminano si configurano -con RateLimitInterval= e RateLimitBurst= in +con RateLimitIntervalSec= e RateLimitBurst= in /etc/systemd/journald.conf. Vedi journald.conf(5) per maggiori informazioni. -- e9bf28e6e834481bb6f48f548ad13606 diff --git a/catalog/systemd.ko.catalog b/catalog/systemd.ko.catalog index 3c3535a94c..2fc6b60b1b 100644 --- a/catalog/systemd.ko.catalog +++ b/catalog/systemd.ko.catalog @@ -55,7 +55,7 @@ Documentation: man:journald.conf(5) 다른 서비스의 메시지에는 영향을 주지 않습니다. 메시지 거절 제어 제한 값은 /etc/systemd/journald.conf 의 -RateLimitInterval= 변수와 RateLimitBurst= 변수로 설정합니다. +RateLimitIntervalSec= 변수와 RateLimitBurst= 변수로 설정합니다. 자세한 내용은 ournald.conf(5)를 살펴보십시오. -- e9bf28e6e834481bb6f48f548ad13606 diff --git a/catalog/systemd.pl.catalog b/catalog/systemd.pl.catalog index 0d2e3d22cf..d8059e93cd 100644 --- a/catalog/systemd.pl.catalog +++ b/catalog/systemd.pl.catalog @@ -69,7 +69,7 @@ Proszę zauważyć, że tylko komunikaty z danej usługi zostały pominięte. Ni to wpływu na komunikaty innych usług. Ograniczenia kontrolujące pomijanie komunikatów mogą być konfigurowane -za pomocą opcji RateLimitInterval= i RateLimitBurst= w pliku +za pomocą opcji RateLimitIntervalSec= i RateLimitBurst= w pliku /etc/systemd/journald.conf. Strona journald.conf(5) zawiera więcej informacji. -- e9bf28e6e834481bb6f48f548ad13606 diff --git a/catalog/systemd.pt_BR.catalog b/catalog/systemd.pt_BR.catalog index d9716e30f7..8b856e8355 100644 --- a/catalog/systemd.pt_BR.catalog +++ b/catalog/systemd.pt_BR.catalog @@ -53,7 +53,7 @@ Note que apenas mensagens de um serviço em questão foram descartadas; outras mensagens dos serviços não foram afetadas. Os controles de limites de quando as mensagens são descartadas pode ser -configurado com RateLimitInterval= e RateLimitBurst= no +configurado com RateLimitIntervalSec= e RateLimitBurst= no /etc/systemd/journald.conf. Veja journald.conf(5) para detalhes. -- e9bf28e6e834481bb6f48f548ad13606 diff --git a/catalog/systemd.ru.catalog b/catalog/systemd.ru.catalog index eedbb8aa9c..e56dbe3acc 100644 --- a/catalog/systemd.ru.catalog +++ b/catalog/systemd.ru.catalog @@ -76,7 +76,7 @@ Documentation: man:journald.conf(5) сообщения других служб не затронуты. Предел, после которого служба журнала начинает игнорировать сообщения, -настраивается параметрами RateLimitInterval= и RateLimitBurst= в файле +настраивается параметрами RateLimitIntervalSec= и RateLimitBurst= в файле /etc/systemd/journald.conf. Подробности смотрите на странице руководства journald.conf(5). diff --git a/catalog/systemd.sr.catalog b/catalog/systemd.sr.catalog index cf700c477b..cc689b7956 100644 --- a/catalog/systemd.sr.catalog +++ b/catalog/systemd.sr.catalog @@ -52,7 +52,7 @@ Documentation: man:journald.conf(5) услуге нису захваћене овим. Ограничења која подешавају начин на који се поруке одбацују се могу подесити -помоћу „RateLimitInterval=“ и „RateLimitBurst=“ параметара унутар датотеке +помоћу „RateLimitIntervalSec=“ и „RateLimitBurst=“ параметара унутар датотеке /etc/systemd/journald.conf. Погледајте journald.conf(5) за појединости. -- e9bf28e6e834481bb6f48f548ad13606 diff --git a/catalog/systemd.zh_CN.catalog b/catalog/systemd.zh_CN.catalog index 38639109e4..ed59fc9250 100644 --- a/catalog/systemd.zh_CN.catalog +++ b/catalog/systemd.zh_CN.catalog @@ -50,7 +50,7 @@ Documentation: man:journald.conf(5) 请注意只有由有问题的服务传来的消息被丢弃, 其它服务的消息不受影响。 -可以在 /etc/systemd/journald.conf 中设定 RateLimitInterval= +可以在 /etc/systemd/journald.conf 中设定 RateLimitIntervalSec= 以及 RateLimitBurst = 的值以控制丢弃信息的限制。 请参见 journald.conf(5) 以了解详情。 diff --git a/catalog/systemd.zh_TW.catalog b/catalog/systemd.zh_TW.catalog index 027ffe44e5..aa5004db08 100644 --- a/catalog/systemd.zh_TW.catalog +++ b/catalog/systemd.zh_TW.catalog @@ -53,7 +53,7 @@ Documentation: man:journald.conf(5) 其他服務的訊息則不受影響。 可以在 /etc/systemd/journald.conf 中設定 -RateLimitInterval= 以及 RateLimitBurst= +RateLimitIntervalSec= 以及 RateLimitBurst= 來控制當訊息要開始被丟棄時的限制。參見 journald.conf(5) 以獲得更多資訊。 -- e9bf28e6e834481bb6f48f548ad13606 diff --git a/man/journald.conf.xml b/man/journald.conf.xml index a9690e8138..3964cd6bc5 100644 --- a/man/journald.conf.xml +++ b/man/journald.conf.xml @@ -148,12 +148,12 @@ - RateLimitInterval= + RateLimitIntervalSec= RateLimitBurst= Configures the rate limiting that is applied to all messages generated on the system. If, in the time - interval defined by RateLimitInterval=, + interval defined by RateLimitIntervalSec=, more messages than specified in RateLimitBurst= are logged by a service, all further messages within the interval are dropped until the @@ -162,7 +162,7 @@ per-service, so that two services which log do not interfere with each other's limits. Defaults to 1000 messages in 30s. The time specification for - RateLimitInterval= may be specified in the + RateLimitIntervalSec= may be specified in the following units: s, min, h, ms, us. To turn off any kind of rate limiting, diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index edc6df914a..8833e73c72 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -271,16 +271,16 @@ - DefaultStartLimitInterval= + DefaultStartLimitIntervalSec= DefaultStartLimitBurst= Configure the default unit start rate limiting, as configured per-service by - StartLimitInterval= and + StartLimitIntervalSec= and StartLimitBurst=. See systemd.service5 for details on the per-service settings. - DefaultStartLimitInterval= defaults to + DefaultStartLimitIntervalSec= defaults to 10s. DefaultStartLimitBurst= defaults to 5. diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 9c869b9805..f4b13a7a77 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -751,14 +751,14 @@ - StartLimitInterval= + StartLimitIntervalSec= StartLimitBurst= Configure unit start rate limiting. By default, units which are started more than 5 times within 10 seconds are not permitted to start any more times until the 10 second interval ends. With these two - options, this rate limiting may be modified. Use StartLimitInterval= to configure the - checking interval (defaults to DefaultStartLimitInterval= in manager configuration file, set - to 0 to disable any kind of rate limiting). Use StartLimitBurst= to configure how many + options, this rate limiting may be modified. Use StartLimitIntervalSec= to configure the + checking interval (defaults to DefaultStartLimitIntervalSec= in manager configuration file, + set to 0 to disable any kind of rate limiting). Use StartLimitBurst= to configure how many starts per interval are allowed (defaults to DefaultStartLimitBurst= in manager configuration file). These configuration options are particularly useful in conjunction with the service setting Restart= (see @@ -777,7 +777,7 @@ StartLimitAction= Configure the action to take if the rate limit configured with - StartLimitInterval= and StartLimitBurst= is hit. Takes one of + StartLimitIntervalSec= and StartLimitBurst= is hit. Takes one of , , , , , or . If is set, hitting the rate limit will trigger no diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 73c50766d1..d45f511489 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -2050,7 +2050,8 @@ const sd_bus_vtable bus_manager_vtable[] = { SD_BUS_PROPERTY("DefaultTimeoutStartUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultTimeoutStopUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultRestartUSec", "t", bus_property_get_usec, offsetof(Manager, default_restart_usec), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultStartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), /* obsolete alias name */ SD_BUS_PROPERTY("DefaultStartLimitBurst", "u", bus_property_get_unsigned, offsetof(Manager, default_start_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultCPUAccounting", "b", bus_property_get_bool, offsetof(Manager, default_cpu_accounting), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultBlockIOAccounting", "b", bus_property_get_bool, offsetof(Manager, default_blockio_accounting), SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index abe30413c3..e912fe2192 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -704,7 +704,8 @@ const sd_bus_vtable bus_unit_vtable[] = { SD_BUS_PROPERTY("Asserts", "a(sbbsi)", property_get_conditions, offsetof(Unit, asserts), 0), SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("StartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), /* obsolete alias name */ SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("StartLimitAction", "s", property_get_failure_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 5f4d66d64d..928b913c7b 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -164,6 +164,8 @@ Unit.IgnoreOnSnapshot, config_parse_warn_compat, DISABLED_LE Unit.JobTimeoutSec, config_parse_sec_fix_0, 0, offsetof(Unit, job_timeout) Unit.JobTimeoutAction, config_parse_failure_action, 0, offsetof(Unit, job_timeout_action) Unit.JobTimeoutRebootArgument, config_parse_string, 0, offsetof(Unit, job_timeout_reboot_arg) +Unit.StartLimitIntervalSec, config_parse_sec, 0, offsetof(Unit, start_limit.interval) +m4_dnl The following is a legacy alias name for compatibility Unit.StartLimitInterval, config_parse_sec, 0, offsetof(Unit, start_limit.interval) Unit.StartLimitBurst, config_parse_unsigned, 0, offsetof(Unit, start_limit.burst) Unit.StartLimitAction, config_parse_failure_action, 0, offsetof(Unit, start_limit_action) diff --git a/src/core/main.c b/src/core/main.c index 9fcd3fe1bd..ed4d42c8cc 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -670,7 +670,8 @@ static int parse_config_file(void) { { "Manager", "DefaultTimeoutStartSec", config_parse_sec, 0, &arg_default_timeout_start_usec }, { "Manager", "DefaultTimeoutStopSec", config_parse_sec, 0, &arg_default_timeout_stop_usec }, { "Manager", "DefaultRestartSec", config_parse_sec, 0, &arg_default_restart_usec }, - { "Manager", "DefaultStartLimitInterval", config_parse_sec, 0, &arg_default_start_limit_interval }, + { "Manager", "DefaultStartLimitInterval", config_parse_sec, 0, &arg_default_start_limit_interval }, /* obsolete alias */ + { "Manager", "DefaultStartLimitIntervalSec",config_parse_sec, 0, &arg_default_start_limit_interval }, { "Manager", "DefaultStartLimitBurst", config_parse_unsigned, 0, &arg_default_start_limit_burst }, { "Manager", "DefaultEnvironment", config_parse_environ, 0, &arg_default_environment }, { "Manager", "DefaultLimitCPU", config_parse_limit, RLIMIT_CPU, arg_default_rlimit }, diff --git a/src/core/system.conf b/src/core/system.conf index e2ded27333..eacd7ee282 100644 --- a/src/core/system.conf +++ b/src/core/system.conf @@ -34,7 +34,7 @@ #DefaultTimeoutStartSec=90s #DefaultTimeoutStopSec=90s #DefaultRestartSec=100ms -#DefaultStartLimitInterval=10s +#DefaultStartLimitIntervalSec=10s #DefaultStartLimitBurst=5 #DefaultEnvironment= #DefaultCPUAccounting=no diff --git a/src/core/user.conf b/src/core/user.conf index 87c8164378..b427f1ef6d 100644 --- a/src/core/user.conf +++ b/src/core/user.conf @@ -23,7 +23,7 @@ #DefaultTimeoutStartSec=90s #DefaultTimeoutStopSec=90s #DefaultRestartSec=100ms -#DefaultStartLimitInterval=10s +#DefaultStartLimitIntervalSec=10s #DefaultStartLimitBurst=5 #DefaultEnvironment= #DefaultLimitCPU= diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf index c154610c54..7fecd7a964 100644 --- a/src/journal/journald-gperf.gperf +++ b/src/journal/journald-gperf.gperf @@ -19,7 +19,9 @@ Journal.Storage, config_parse_storage, 0, offsetof(Server, storage Journal.Compress, config_parse_bool, 0, offsetof(Server, compress) Journal.Seal, config_parse_bool, 0, offsetof(Server, seal) Journal.SyncIntervalSec, config_parse_sec, 0, offsetof(Server, sync_interval_usec) +# The following is a legacy name for compatibility Journal.RateLimitInterval, config_parse_sec, 0, offsetof(Server, rate_limit_interval) +Journal.RateLimitIntervalSec,config_parse_sec, 0, offsetof(Server, rate_limit_interval) Journal.RateLimitBurst, config_parse_unsigned, 0, offsetof(Server, rate_limit_burst) Journal.SystemMaxUse, config_parse_iec_uint64, 0, offsetof(Server, system_metrics.max_use) Journal.SystemMaxFileSize, config_parse_iec_uint64, 0, offsetof(Server, system_metrics.max_size) diff --git a/src/journal/journald.conf b/src/journal/journald.conf index 7beb96c671..2541b949be 100644 --- a/src/journal/journald.conf +++ b/src/journal/journald.conf @@ -17,7 +17,7 @@ #Seal=yes #SplitMode=uid #SyncIntervalSec=5m -#RateLimitInterval=30s +#RateLimitIntervalSec=30s #RateLimitBurst=1000 #SystemMaxUse= #SystemKeepFree= -- cgit v1.2.3-54-g00ecf From 29857001854a02c292f1f3b324e7a66831e859c8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 28 Apr 2016 21:00:28 +0200 Subject: core: make parsing of RLIMIT_NICE aware of actual nice levels --- man/systemd.exec.xml | 38 +++++++++++++++------------------ src/basic/rlimit-util.c | 52 ++++++++++++++++++++++++++++++++++++++++++++- src/test/test-rlimit-util.c | 12 +++++++++++ 3 files changed, 80 insertions(+), 22 deletions(-) (limited to 'man') diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 2d0fb63f1d..2a93760428 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -629,27 +629,23 @@ LimitNICE= LimitRTPRIO= LimitRTTIME= - These settings set both soft and hard limits - of various resources for executed processes. See - setrlimit2 - for details. The resource limit is possible to specify in two formats, - to set soft and hard limits to the same value, - or to set both limits individually (e.g. LimitAS=4G:16G). - Use the string infinity to - configure no limit on a specific resource. The multiplicative - suffixes K (=1024), M (=1024*1024) and so on for G, T, P and E - may be used for resource limits measured in bytes - (e.g. LimitAS=16G). For the limits referring to time values, - the usual time units ms, s, min, h and so on may be used (see - systemd.time7 - for details). Note that if no time unit is specified for - LimitCPU= the default unit of seconds is - implied, while for LimitRTTIME= the default - unit of microseconds is implied. Also, note that the effective - granularity of the limits might influence their - enforcement. For example, time limits specified for - LimitCPU= will be rounded up implicitly to - multiples of 1s. + Set soft and hard limits on various resources for executed processes. See + setrlimit2 for details on + the resource limit concept. Resource limits may be specified in two formats: either as single value to set a + specific soft and hard limit to the same value, or as colon-separated pair to set + both limits individually (e.g. LimitAS=4G:16G). Use the string infinity + to configure no limit on a specific resource. The multiplicative suffixes K, M, G, T, P and E (to the base + 1024) may be used for resource limits measured in bytes (e.g. LimitAS=16G). For the limits referring to time + values, the usual time units ms, s, min, h and so on may be used (see + systemd.time7 for + details). Note that if no time unit is specified for LimitCPU= the default unit of seconds + is implied, while for LimitRTTIME= the default unit of microseconds is implied. Also, note + that the effective granularity of the limits might influence their enforcement. For example, time limits + specified for LimitCPU= will be rounded up implicitly to multiples of 1s. For + LimitNICE= the value may be specified in two syntaxes: if prefixed with + + or -, the value is understood as regular Linux nice value in the range -20..19. If not + prefixed like this the value is understood as raw resource limit parameter in the range 0..40 (with 0 being + equivalent to 1). Note that most process resource limits configured with these options are per-process, and processes may fork in order diff --git a/src/basic/rlimit-util.c b/src/basic/rlimit-util.c index 7540b43215..ee063720ed 100644 --- a/src/basic/rlimit-util.c +++ b/src/basic/rlimit-util.c @@ -153,6 +153,56 @@ static int rlimit_parse_usec(const char *val, rlim_t *ret) { return 0; } +static int rlimit_parse_nice(const char *val, rlim_t *ret) { + uint64_t rl; + int r; + + /* So, Linux is weird. The range for RLIMIT_NICE is 40..1, mapping to the nice levels -20..19. However, the + * RLIMIT_NICE limit defaults to 0 by the kernel, i.e. a value that maps to nice level 20, which of course is + * bogus and does not exist. In order to permit parsing the RLIMIT_NICE of 0 here we hence implement a slight + * asymmetry: when parsing as positive nice level we permit 0..19. When parsing as negative nice level, we + * permit -20..0. But when parsing as raw resource limit value then we also allow the special value 0. + * + * Yeah, Linux is quality engineering sometimes... */ + + if (val[0] == '+') { + + /* Prefixed with "+": Parse as positive user-friendly nice value */ + r = safe_atou64(val + 1, &rl); + if (r < 0) + return r; + + if (rl >= PRIO_MAX) + return -ERANGE; + + rl = 20 - rl; + + } else if (val[0] == '-') { + + /* Prefixed with "-": Parse as negative user-friendly nice value */ + r = safe_atou64(val + 1, &rl); + if (r < 0) + return r; + + if (rl > (uint64_t) (-PRIO_MIN)) + return -ERANGE; + + rl = 20 + rl; + } else { + + /* Not prefixed: parse as raw resource limit value */ + r = safe_atou64(val, &rl); + if (r < 0) + return r; + + if (rl > (uint64_t) (20 - PRIO_MIN)) + return -ERANGE; + } + + *ret = (rlim_t) rl; + return 0; +} + static int (*const rlimit_parse_table[_RLIMIT_MAX])(const char *val, rlim_t *ret) = { [RLIMIT_CPU] = rlimit_parse_sec, [RLIMIT_FSIZE] = rlimit_parse_size, @@ -167,7 +217,7 @@ static int (*const rlimit_parse_table[_RLIMIT_MAX])(const char *val, rlim_t *ret [RLIMIT_LOCKS] = rlimit_parse_u64, [RLIMIT_SIGPENDING] = rlimit_parse_u64, [RLIMIT_MSGQUEUE] = rlimit_parse_size, - [RLIMIT_NICE] = rlimit_parse_u64, + [RLIMIT_NICE] = rlimit_parse_nice, [RLIMIT_RTPRIO] = rlimit_parse_u64, [RLIMIT_RTTIME] = rlimit_parse_usec, }; diff --git a/src/test/test-rlimit-util.c b/src/test/test-rlimit-util.c index d9ac9368cd..62afd2de5e 100644 --- a/src/test/test-rlimit-util.c +++ b/src/test/test-rlimit-util.c @@ -99,6 +99,18 @@ int main(int argc, char *argv[]) { test_rlimit_parse_format(RLIMIT_NOFILE, "", 0, 0, -EINVAL, NULL); test_rlimit_parse_format(RLIMIT_NOFILE, "5:4", 0, 0, -EILSEQ, NULL); test_rlimit_parse_format(RLIMIT_NOFILE, "5:4:3", 0, 0, -EINVAL, NULL); + test_rlimit_parse_format(RLIMIT_NICE, "20", 20, 20, 0, "20"); + test_rlimit_parse_format(RLIMIT_NICE, "40", 40, 40, 0, "40"); + test_rlimit_parse_format(RLIMIT_NICE, "41", 41, 41, -ERANGE, "41"); + test_rlimit_parse_format(RLIMIT_NICE, "0", 0, 0, 0, "0"); + test_rlimit_parse_format(RLIMIT_NICE, "-7", 27, 27, 0, "27"); + test_rlimit_parse_format(RLIMIT_NICE, "-20", 40, 40, 0, "40"); + test_rlimit_parse_format(RLIMIT_NICE, "-21", 41, 41, -ERANGE, "41"); + test_rlimit_parse_format(RLIMIT_NICE, "-0", 20, 20, 0, "20"); + test_rlimit_parse_format(RLIMIT_NICE, "+7", 13, 13, 0, "13"); + test_rlimit_parse_format(RLIMIT_NICE, "+19", 1, 1, 0, "1"); + test_rlimit_parse_format(RLIMIT_NICE, "+20", 0, 0, -ERANGE, "0"); + test_rlimit_parse_format(RLIMIT_NICE, "+0", 20, 20, 0, "20"); return 0; } -- cgit v1.2.3-54-g00ecf