mirror of
https://github.com/systemd/systemd.git
synced 2025-03-28 02:50:16 +03:00
Merge pull request #3148 from poettering/trigger
core: introduce activation rate limit and parse nice levels and close sockets properly
This commit is contained in:
commit
1c5ed0e2b4
10
TODO
10
TODO
@ -40,8 +40,6 @@ Features:
|
||||
* rework fopen_temporary() to make use of open_tmpfile_linkable() (problem: the
|
||||
kernel doesn't support linkat() that replaces existing files, currently)
|
||||
|
||||
* journalctl -f --no-tail fails for Lennart
|
||||
|
||||
* check if DeviceAllow= should split first, resolve specifiers later
|
||||
|
||||
* transient units: don't bother with actually setting unit properties, we
|
||||
@ -78,11 +76,9 @@ Features:
|
||||
* PID1: find a way how we can reload unit file configuration for
|
||||
specific units only, without reloading the whole of systemd
|
||||
|
||||
* add an explicit parser for LimitNICE= and LimitRTPRIO= that verifies
|
||||
* add an explicit parser for LimitRTPRIO= that verifies
|
||||
the specified range and generates sane error messages for incorrect
|
||||
specifications. Also, for LimitNICE= maybe introduce a syntax such
|
||||
as "+5" or "-7" in order to make the limits more readable as they
|
||||
are otherwise shifted by 20.
|
||||
specifications.
|
||||
|
||||
* do something about "/control" subcgroups in the unified cgroup hierarchy
|
||||
|
||||
@ -249,7 +245,7 @@ Features:
|
||||
CAP_NET_ADMIN is set, more than the loopback device is defined, even
|
||||
when it is otherwise off
|
||||
|
||||
* MessageQueueMessageSize= should use parse_iec_size().
|
||||
* MessageQueueMessageSize= (and suchlike) should use parse_iec_size().
|
||||
|
||||
* "busctl status" works only as root on dbus1, since we cannot read
|
||||
/proc/$PID/exe
|
||||
|
@ -53,7 +53,7 @@ Documentation: man:journald.conf(5)
|
||||
Паведамленні іншых сэрвісаў засталіся.
|
||||
|
||||
Мяжа, пасля якой паведамленні будуць адкінуты, наладжваецца з
|
||||
дапамогай RateLimitInterval= і RateLimitBurst= у файле
|
||||
дапамогай RateLimitIntervalSec= і RateLimitBurst= у файле
|
||||
/etc/systemd/journald.conf. Глядзіце journald.conf(5) для дэталей.
|
||||
|
||||
-- e9bf28e6e834481bb6f48f548ad13606
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -55,7 +55,7 @@ Documentation: man:journald.conf(5)
|
||||
다른 서비스의 메시지에는 영향을 주지 않습니다.
|
||||
|
||||
메시지 거절 제어 제한 값은 /etc/systemd/journald.conf 의
|
||||
RateLimitInterval= 변수와 RateLimitBurst= 변수로 설정합니다.
|
||||
RateLimitIntervalSec= 변수와 RateLimitBurst= 변수로 설정합니다.
|
||||
자세한 내용은 ournald.conf(5)를 살펴보십시오.
|
||||
|
||||
-- e9bf28e6e834481bb6f48f548ad13606
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -76,7 +76,7 @@ Documentation: man:journald.conf(5)
|
||||
сообщения других служб не затронуты.
|
||||
|
||||
Предел, после которого служба журнала начинает игнорировать сообщения,
|
||||
настраивается параметрами RateLimitInterval= и RateLimitBurst= в файле
|
||||
настраивается параметрами RateLimitIntervalSec= и RateLimitBurst= в файле
|
||||
/etc/systemd/journald.conf. Подробности смотрите на странице руководства
|
||||
journald.conf(5).
|
||||
|
||||
|
@ -52,7 +52,7 @@ Documentation: man:journald.conf(5)
|
||||
услуге нису захваћене овим.
|
||||
|
||||
Ограничења која подешавају начин на који се поруке одбацују се могу подесити
|
||||
помоћу „RateLimitInterval=“ и „RateLimitBurst=“ параметара унутар датотеке
|
||||
помоћу „RateLimitIntervalSec=“ и „RateLimitBurst=“ параметара унутар датотеке
|
||||
/etc/systemd/journald.conf. Погледајте journald.conf(5) за појединости.
|
||||
|
||||
-- e9bf28e6e834481bb6f48f548ad13606
|
||||
|
@ -50,7 +50,7 @@ Documentation: man:journald.conf(5)
|
||||
请注意只有由有问题的服务传来的消息被丢弃,
|
||||
其它服务的消息不受影响。
|
||||
|
||||
可以在 /etc/systemd/journald.conf 中设定 RateLimitInterval=
|
||||
可以在 /etc/systemd/journald.conf 中设定 RateLimitIntervalSec=
|
||||
以及 RateLimitBurst = 的值以控制丢弃信息的限制。
|
||||
请参见 journald.conf(5) 以了解详情。
|
||||
|
||||
|
@ -53,7 +53,7 @@ Documentation: man:journald.conf(5)
|
||||
其他服務的訊息則不受影響。
|
||||
|
||||
可以在 /etc/systemd/journald.conf 中設定
|
||||
RateLimitInterval= 以及 RateLimitBurst=
|
||||
RateLimitIntervalSec= 以及 RateLimitBurst=
|
||||
來控制當訊息要開始被丟棄時的限制。參見 journald.conf(5) 以獲得更多資訊。
|
||||
|
||||
-- e9bf28e6e834481bb6f48f548ad13606
|
||||
|
@ -336,7 +336,7 @@ AC_CHECK_DECLS([IFLA_INET6_ADDR_GEN_MODE,
|
||||
IFLA_BRIDGE_VLAN_INFO,
|
||||
IFLA_BRPORT_PROXYARP,
|
||||
IFLA_BRPORT_LEARNING_SYNC,
|
||||
IFLA_BR_PRIORITY,
|
||||
IFLA_BR_VLAN_DEFAULT_PVID,
|
||||
NDA_IFINDEX,
|
||||
IFA_FLAGS],
|
||||
[], [], [[
|
||||
|
@ -495,6 +495,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHP*ProBook*4*:pvr*
|
||||
# HP ZBook
|
||||
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPZBook*:pvr*
|
||||
KEYBOARD_KEY_81=f20 # Fn+F8; Microphone mute button, should be micmute
|
||||
|
||||
# HP Folio 1040g2
|
||||
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPEliteBookFolio1040G2:pvr*
|
||||
KEYBOARD_KEY_81=f20 # Fn+F8; Microphone mute button, should be micmute
|
||||
|
@ -148,12 +148,12 @@
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>RateLimitInterval=</varname></term>
|
||||
<term><varname>RateLimitIntervalSec=</varname></term>
|
||||
<term><varname>RateLimitBurst=</varname></term>
|
||||
|
||||
<listitem><para>Configures the rate limiting that is applied
|
||||
to all messages generated on the system. If, in the time
|
||||
interval defined by <varname>RateLimitInterval=</varname>,
|
||||
interval defined by <varname>RateLimitIntervalSec=</varname>,
|
||||
more messages than specified in
|
||||
<varname>RateLimitBurst=</varname> 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
|
||||
<varname>RateLimitInterval=</varname> may be specified in the
|
||||
<varname>RateLimitIntervalSec=</varname> may be specified in the
|
||||
following units: <literal>s</literal>, <literal>min</literal>,
|
||||
<literal>h</literal>, <literal>ms</literal>,
|
||||
<literal>us</literal>. To turn off any kind of rate limiting,
|
||||
|
@ -271,16 +271,16 @@
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>DefaultStartLimitInterval=</varname></term>
|
||||
<term><varname>DefaultStartLimitIntervalSec=</varname></term>
|
||||
<term><varname>DefaultStartLimitBurst=</varname></term>
|
||||
|
||||
<listitem><para>Configure the default unit start rate
|
||||
limiting, as configured per-service by
|
||||
<varname>StartLimitInterval=</varname> and
|
||||
<varname>StartLimitIntervalSec=</varname> and
|
||||
<varname>StartLimitBurst=</varname>. See
|
||||
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for details on the per-service settings.
|
||||
<varname>DefaultStartLimitInterval=</varname> defaults to
|
||||
<varname>DefaultStartLimitIntervalSec=</varname> defaults to
|
||||
10s. <varname>DefaultStartLimitBurst=</varname> defaults to
|
||||
5.</para></listitem>
|
||||
</varlistentry>
|
||||
|
@ -629,27 +629,23 @@
|
||||
<term><varname>LimitNICE=</varname></term>
|
||||
<term><varname>LimitRTPRIO=</varname></term>
|
||||
<term><varname>LimitRTTIME=</varname></term>
|
||||
<listitem><para>These settings set both soft and hard limits
|
||||
of various resources for executed processes. See
|
||||
<citerefentry><refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||
for details. The resource limit is possible to specify in two formats,
|
||||
<option>value</option> to set soft and hard limits to the same value,
|
||||
or <option>soft:hard</option> to set both limits individually (e.g. LimitAS=4G:16G).
|
||||
Use the string <varname>infinity</varname> 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
|
||||
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||
for details). Note that if no time unit is specified for
|
||||
<varname>LimitCPU=</varname> the default unit of seconds is
|
||||
implied, while for <varname>LimitRTTIME=</varname> 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
|
||||
<varname>LimitCPU=</varname> will be rounded up implicitly to
|
||||
multiples of 1s.</para>
|
||||
<listitem><para>Set soft and hard limits on various resources for executed processes. See
|
||||
<citerefentry><refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry> 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 <option>soft:hard</option> to set
|
||||
both limits individually (e.g. <literal>LimitAS=4G:16G</literal>). Use the string <varname>infinity</varname>
|
||||
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
|
||||
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
|
||||
details). Note that if no time unit is specified for <varname>LimitCPU=</varname> the default unit of seconds
|
||||
is implied, while for <varname>LimitRTTIME=</varname> 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 <varname>LimitCPU=</varname> will be rounded up implicitly to multiples of 1s. For
|
||||
<varname>LimitNICE=</varname> the value may be specified in two syntaxes: if prefixed with <literal>+</literal>
|
||||
or <literal>-</literal>, 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).</para>
|
||||
|
||||
<para>Note that most process resource limits configured with
|
||||
these options are per-process, and processes may fork in order
|
||||
|
@ -807,6 +807,22 @@
|
||||
suffix.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>TriggerLimitIntervalSec=</varname></term>
|
||||
<term><varname>TriggerLimitIntervalBurst=</varname></term>
|
||||
|
||||
<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 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
|
||||
<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
|
||||
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.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>Check
|
||||
|
@ -751,14 +751,14 @@
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>StartLimitInterval=</varname></term>
|
||||
<term><varname>StartLimitIntervalSec=</varname></term>
|
||||
<term><varname>StartLimitBurst=</varname></term>
|
||||
|
||||
<listitem><para>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 <varname>StartLimitInterval=</varname> to configure the
|
||||
checking interval (defaults to <varname>DefaultStartLimitInterval=</varname> in manager configuration file, set
|
||||
to 0 to disable any kind of rate limiting). Use <varname>StartLimitBurst=</varname> to configure how many
|
||||
options, this rate limiting may be modified. Use <varname>StartLimitIntervalSec=</varname> to configure the
|
||||
checking interval (defaults to <varname>DefaultStartLimitIntervalSec=</varname> in manager configuration file,
|
||||
set to 0 to disable any kind of rate limiting). Use <varname>StartLimitBurst=</varname> to configure how many
|
||||
starts per interval are allowed (defaults to <varname>DefaultStartLimitBurst=</varname> in manager
|
||||
configuration file). These configuration options are particularly useful in conjunction with the service
|
||||
setting <varname>Restart=</varname> (see
|
||||
@ -769,14 +769,15 @@
|
||||
manually at a later point, from which point on, the restart logic is again activated. Note that
|
||||
<command>systemctl reset-failed</command> 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.</para></listitem>
|
||||
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.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>StartLimitAction=</varname></term>
|
||||
|
||||
<listitem><para>Configure the action to take if the rate limit configured with
|
||||
<varname>StartLimitInterval=</varname> and <varname>StartLimitBurst=</varname> is hit. Takes one of
|
||||
<varname>StartLimitIntervalSec=</varname> and <varname>StartLimitBurst=</varname> is hit. Takes one of
|
||||
<option>none</option>, <option>reboot</option>, <option>reboot-force</option>,
|
||||
<option>reboot-immediate</option>, <option>poweroff</option>, <option>poweroff-force</option> or
|
||||
<option>poweroff-immediate</option>. If <option>none</option> is set, hitting the rate limit will trigger no
|
||||
|
@ -557,7 +557,7 @@ struct btrfs_ioctl_quota_ctl_args {
|
||||
#define IFLA_INET6_ADDR_GEN_MODE 8
|
||||
#define __IFLA_INET6_MAX 9
|
||||
|
||||
#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
|
||||
#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
|
||||
|
||||
#define IN6_ADDR_GEN_MODE_EUI64 0
|
||||
#define IN6_ADDR_GEN_MODE_NONE 1
|
||||
@ -742,7 +742,7 @@ struct btrfs_ioctl_quota_ctl_args {
|
||||
#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_IFLA_BR_PRIORITY
|
||||
#if !HAVE_DECL_IFLA_BR_VLAN_DEFAULT_PVID
|
||||
#define IFLA_BR_UNSPEC 0
|
||||
#define IFLA_BR_FORWARD_DELAY 1
|
||||
#define IFLA_BR_HELLO_TIME 2
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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),
|
||||
|
@ -149,6 +149,8 @@ const sd_bus_vtable bus_socket_vtable[] = {
|
||||
SD_BUS_PROPERTY("NAccepted", "u", bus_property_get_unsigned, offsetof(Socket, n_accepted), 0),
|
||||
SD_BUS_PROPERTY("FileDescriptorName", "s", property_get_fdname, 0, 0),
|
||||
SD_BUS_PROPERTY("SocketProtocol", "i", bus_property_get_int, offsetof(Socket, socket_protocol), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("TriggerLimitIntervalSec", "t", bus_property_get_usec, offsetof(Socket, trigger_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("TriggerLimitBurst", "u", bus_property_get_unsigned, offsetof(Socket, trigger_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Socket, exec_command[SOCKET_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
||||
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPost", offsetof(Socket, exec_command[SOCKET_EXEC_START_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
||||
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStopPre", offsetof(Socket, exec_command[SOCKET_EXEC_STOP_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
||||
|
@ -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),
|
||||
|
@ -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)
|
||||
@ -220,6 +222,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)
|
||||
@ -297,6 +300,8 @@ Socket.RemoveOnStop, config_parse_bool, 0,
|
||||
Socket.Symlinks, config_parse_unit_path_strv_printf, 0, offsetof(Socket, symlinks)
|
||||
Socket.FileDescriptorName, config_parse_fdname, 0, 0
|
||||
Socket.Service, config_parse_socket_service, 0, 0
|
||||
Socket.TriggerLimitIntervalSec, config_parse_sec, 0, offsetof(Socket, trigger_limit.interval)
|
||||
Socket.TriggerLimitBurst, config_parse_unsigned, 0, offsetof(Socket, trigger_limit.burst)
|
||||
m4_ifdef(`HAVE_SMACK',
|
||||
`Socket.SmackLabel, config_parse_string, 0, offsetof(Socket, smack)
|
||||
Socket.SmackLabelIPIn, config_parse_string, 0, offsetof(Socket, smack_ip_in)
|
||||
|
@ -289,6 +289,7 @@ static int parse_crash_chvt(const char *value) {
|
||||
}
|
||||
|
||||
static int set_machine_id(const char *m) {
|
||||
assert(m);
|
||||
|
||||
if (sd_id128_from_string(m, &arg_machine_id) < 0)
|
||||
return -EINVAL;
|
||||
@ -669,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 },
|
||||
|
@ -180,20 +180,17 @@ static int service_set_main_pid(Service *s, pid_t pid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void service_close_socket_fd(Service *s) {
|
||||
void service_close_socket_fd(Service *s) {
|
||||
assert(s);
|
||||
|
||||
/* Undo the effect of service_set_socket_fd(). */
|
||||
|
||||
s->socket_fd = asynchronous_close(s->socket_fd);
|
||||
}
|
||||
|
||||
static void service_connection_unref(Service *s) {
|
||||
assert(s);
|
||||
|
||||
if (!UNIT_ISSET(s->accept_socket))
|
||||
return;
|
||||
|
||||
socket_connection_unref(SOCKET(UNIT_DEREF(s->accept_socket)));
|
||||
unit_ref_unset(&s->accept_socket);
|
||||
if (UNIT_ISSET(s->accept_socket)) {
|
||||
socket_connection_unref(SOCKET(UNIT_DEREF(s->accept_socket)));
|
||||
unit_ref_unset(&s->accept_socket);
|
||||
}
|
||||
}
|
||||
|
||||
static void service_stop_watchdog(Service *s) {
|
||||
@ -321,7 +318,6 @@ static void service_done(Unit *u) {
|
||||
s->bus_name_owner = mfree(s->bus_name_owner);
|
||||
|
||||
service_close_socket_fd(s);
|
||||
service_connection_unref(s);
|
||||
|
||||
unit_ref_unset(&s->accept_socket);
|
||||
|
||||
@ -910,10 +906,8 @@ static void service_set_state(Service *s, ServiceState state) {
|
||||
SERVICE_RUNNING, SERVICE_RELOAD,
|
||||
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
|
||||
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL) &&
|
||||
!(state == SERVICE_DEAD && UNIT(s)->job)) {
|
||||
!(state == SERVICE_DEAD && UNIT(s)->job))
|
||||
service_close_socket_fd(s);
|
||||
service_connection_unref(s);
|
||||
}
|
||||
|
||||
if (!IN_SET(state, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD))
|
||||
service_stop_watchdog(s);
|
||||
@ -3139,9 +3133,8 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock, bool selinux_context
|
||||
assert(s);
|
||||
assert(fd >= 0);
|
||||
|
||||
/* This is called by the socket code when instantiating a new
|
||||
* service for a stream socket and the socket needs to be
|
||||
* configured. */
|
||||
/* This is called by the socket code when instantiating a new service for a stream socket and the socket needs
|
||||
* to be configured. We take ownership of the passed fd on success. */
|
||||
|
||||
if (UNIT(s)->load_state != UNIT_LOADED)
|
||||
return -EINVAL;
|
||||
@ -3169,12 +3162,15 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock, bool selinux_context
|
||||
return r;
|
||||
}
|
||||
|
||||
r = unit_add_two_dependencies(UNIT(sock), UNIT_BEFORE, UNIT_TRIGGERS, UNIT(s), false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
s->socket_fd = fd;
|
||||
s->socket_fd_selinux_context_net = selinux_context_net;
|
||||
|
||||
unit_ref_set(&s->accept_socket, UNIT(sock));
|
||||
|
||||
return unit_add_two_dependencies(UNIT(sock), UNIT_BEFORE, UNIT_TRIGGERS, UNIT(s), false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void service_reset_failed(Unit *u) {
|
||||
|
@ -198,6 +198,7 @@ struct Service {
|
||||
extern const UnitVTable service_vtable;
|
||||
|
||||
int service_set_socket_fd(Service *s, int fd, struct Socket *socket, bool selinux_context_net);
|
||||
void service_close_socket_fd(Service *s);
|
||||
|
||||
const char* service_restart_to_string(ServiceRestart i) _const_;
|
||||
ServiceRestart service_restart_from_string(const char *s) _pure_;
|
||||
|
@ -99,6 +99,8 @@ static void socket_init(Unit *u) {
|
||||
s->exec_context.std_error = u->manager->default_std_error;
|
||||
|
||||
s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
|
||||
|
||||
RATELIMIT_INIT(s->trigger_limit, 5*USEC_PER_SEC, 2500);
|
||||
}
|
||||
|
||||
static void socket_unwatch_control_pid(Socket *s) {
|
||||
@ -227,7 +229,6 @@ int socket_instantiate_service(Socket *s) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
u->no_gc = true;
|
||||
unit_ref_set(&s->service, u);
|
||||
|
||||
return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false);
|
||||
@ -792,47 +793,45 @@ static void socket_close_fds(Socket *s) {
|
||||
assert(s);
|
||||
|
||||
LIST_FOREACH(port, p, s->ports) {
|
||||
bool was_open;
|
||||
|
||||
was_open = p->fd >= 0;
|
||||
|
||||
p->event_source = sd_event_source_unref(p->event_source);
|
||||
|
||||
if (p->fd < 0)
|
||||
continue;
|
||||
|
||||
p->fd = safe_close(p->fd);
|
||||
socket_cleanup_fd_list(p);
|
||||
|
||||
/* One little note: we should normally not delete any
|
||||
* sockets in the file system here! After all some
|
||||
* other process we spawned might still have a
|
||||
* reference of this fd and wants to continue to use
|
||||
* it. Therefore we delete sockets in the file system
|
||||
* before we create a new one, not after we stopped
|
||||
* using one! */
|
||||
/* One little note: we should normally not delete any sockets in the file system here! After all some
|
||||
* other process we spawned might still have a reference of this fd and wants to continue to use
|
||||
* it. Therefore we normally delete sockets in the file system before we create a new one, not after we
|
||||
* stopped using one! That all said, if the user explicitly requested this, we'll delete them here
|
||||
* anyway, but only then. */
|
||||
|
||||
if (s->remove_on_stop) {
|
||||
switch (p->type) {
|
||||
if (!was_open || !s->remove_on_stop)
|
||||
continue;
|
||||
|
||||
case SOCKET_FIFO:
|
||||
unlink(p->path);
|
||||
break;
|
||||
switch (p->type) {
|
||||
|
||||
case SOCKET_MQUEUE:
|
||||
mq_unlink(p->path);
|
||||
break;
|
||||
case SOCKET_FIFO:
|
||||
(void) unlink(p->path);
|
||||
break;
|
||||
|
||||
case SOCKET_SOCKET:
|
||||
socket_address_unlink(&p->address);
|
||||
break;
|
||||
case SOCKET_MQUEUE:
|
||||
(void) mq_unlink(p->path);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case SOCKET_SOCKET:
|
||||
(void) socket_address_unlink(&p->address);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (s->remove_on_stop)
|
||||
STRV_FOREACH(i, s->symlinks)
|
||||
unlink(*i);
|
||||
(void) unlink(*i);
|
||||
}
|
||||
|
||||
static void socket_apply_socket_options(Socket *s, int fd) {
|
||||
@ -1887,6 +1886,9 @@ static void socket_enter_running(Socket *s, int cfd) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int r;
|
||||
|
||||
/* Note that this call takes possession of the connection fd passed. It either has to assign it somewhere or
|
||||
* close it. */
|
||||
|
||||
assert(s);
|
||||
|
||||
/* We don't take connections anymore if we are supposed to
|
||||
@ -1896,7 +1898,7 @@ static void socket_enter_running(Socket *s, int cfd) {
|
||||
log_unit_debug(UNIT(s), "Suppressing connection request since unit stop is scheduled.");
|
||||
|
||||
if (cfd >= 0)
|
||||
safe_close(cfd);
|
||||
cfd = safe_close(cfd);
|
||||
else {
|
||||
/* Flush all sockets by closing and reopening them */
|
||||
socket_close_fds(s);
|
||||
@ -1918,6 +1920,13 @@ static void socket_enter_running(Socket *s, int cfd) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ratelimit_test(&s->trigger_limit)) {
|
||||
safe_close(cfd);
|
||||
log_unit_warning(UNIT(s), "Trigger limit hit, refusing further activation.");
|
||||
socket_enter_stop_pre(s, SOCKET_FAILURE_TRIGGER_LIMIT_HIT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cfd < 0) {
|
||||
Iterator i;
|
||||
Unit *other;
|
||||
@ -1949,7 +1958,7 @@ static void socket_enter_running(Socket *s, int cfd) {
|
||||
Service *service;
|
||||
|
||||
if (s->n_connections >= s->max_connections) {
|
||||
log_unit_warning(UNIT(s), "Too many incoming connections (%u)", s->n_connections);
|
||||
log_unit_warning(UNIT(s), "Too many incoming connections (%u), refusing connection attempt.", s->n_connections);
|
||||
safe_close(cfd);
|
||||
return;
|
||||
}
|
||||
@ -1965,6 +1974,7 @@ static void socket_enter_running(Socket *s, int cfd) {
|
||||
|
||||
/* ENOTCONN is legitimate if TCP RST was received.
|
||||
* This connection is over, but the socket unit lives on. */
|
||||
log_unit_debug(UNIT(s), "Got ENOTCONN on incoming socket, assuming aborted connection attempt, ignoring.");
|
||||
safe_close(cfd);
|
||||
return;
|
||||
}
|
||||
@ -1983,22 +1993,24 @@ static void socket_enter_running(Socket *s, int cfd) {
|
||||
|
||||
service = SERVICE(UNIT_DEREF(s->service));
|
||||
unit_ref_unset(&s->service);
|
||||
|
||||
s->n_accepted++;
|
||||
|
||||
UNIT(service)->no_gc = false;
|
||||
|
||||
unit_choose_id(UNIT(service), name);
|
||||
|
||||
r = service_set_socket_fd(service, cfd, s, s->selinux_context_from_net);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
cfd = -1;
|
||||
cfd = -1; /* We passed ownership of the fd to the service now. Forget it here. */
|
||||
s->n_connections++;
|
||||
|
||||
r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(service), JOB_REPLACE, &error, NULL);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
/* We failed to activate the new service, but it still exists. Let's make sure the service
|
||||
* closes and forgets the connection fd again, immediately. */
|
||||
service_close_socket_fd(service);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Notify clients about changed counters */
|
||||
unit_add_to_dbus_queue(UNIT(s));
|
||||
@ -2806,6 +2818,7 @@ static const char* const socket_result_table[_SOCKET_RESULT_MAX] = {
|
||||
[SOCKET_FAILURE_EXIT_CODE] = "exit-code",
|
||||
[SOCKET_FAILURE_SIGNAL] = "signal",
|
||||
[SOCKET_FAILURE_CORE_DUMP] = "core-dump",
|
||||
[SOCKET_FAILURE_TRIGGER_LIMIT_HIT] = "trigger-limit-hit",
|
||||
[SOCKET_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit"
|
||||
};
|
||||
|
||||
|
@ -52,6 +52,7 @@ typedef enum SocketResult {
|
||||
SOCKET_FAILURE_EXIT_CODE,
|
||||
SOCKET_FAILURE_SIGNAL,
|
||||
SOCKET_FAILURE_CORE_DUMP,
|
||||
SOCKET_FAILURE_TRIGGER_LIMIT_HIT,
|
||||
SOCKET_FAILURE_SERVICE_START_LIMIT_HIT,
|
||||
_SOCKET_RESULT_MAX,
|
||||
_SOCKET_RESULT_INVALID = -1
|
||||
@ -156,6 +157,8 @@ struct Socket {
|
||||
bool reset_cpu_usage:1;
|
||||
|
||||
char *fdname;
|
||||
|
||||
RateLimit trigger_limit;
|
||||
};
|
||||
|
||||
/* Called from the service code when collecting fds */
|
||||
|
@ -34,7 +34,7 @@
|
||||
#DefaultTimeoutStartSec=90s
|
||||
#DefaultTimeoutStopSec=90s
|
||||
#DefaultRestartSec=100ms
|
||||
#DefaultStartLimitInterval=10s
|
||||
#DefaultStartLimitIntervalSec=10s
|
||||
#DefaultStartLimitBurst=5
|
||||
#DefaultEnvironment=
|
||||
#DefaultCPUAccounting=no
|
||||
|
@ -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
|
||||
@ -3222,6 +3222,10 @@ void unit_ref_unset(UnitRef *ref) {
|
||||
if (!ref->unit)
|
||||
return;
|
||||
|
||||
/* We are about to drop a reference to the unit, make sure the garbage collection has a look at it as it might
|
||||
* be unreferenced now. */
|
||||
unit_add_to_gc_queue(ref->unit);
|
||||
|
||||
LIST_REMOVE(refs, ref->unit->refs, ref);
|
||||
ref->unit = NULL;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#DefaultTimeoutStartSec=90s
|
||||
#DefaultTimeoutStopSec=90s
|
||||
#DefaultRestartSec=100ms
|
||||
#DefaultStartLimitInterval=10s
|
||||
#DefaultStartLimitIntervalSec=10s
|
||||
#DefaultStartLimitBurst=5
|
||||
#DefaultEnvironment=
|
||||
#DefaultLimitCPU=
|
||||
|
@ -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)
|
||||
|
@ -17,7 +17,7 @@
|
||||
#Seal=yes
|
||||
#SplitMode=uid
|
||||
#SyncIntervalSec=5m
|
||||
#RateLimitInterval=30s
|
||||
#RateLimitIntervalSec=30s
|
||||
#RateLimitBurst=1000
|
||||
#SystemMaxUse=
|
||||
#SystemKeepFree=
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user