mirror of
https://github.com/systemd/systemd.git
synced 2024-11-27 12:13:33 +08:00
Merge pull request #32010 from bluca/reexec_rate_limit
core: serialize reload rate limit and apply ReloadLimit to reexec too
This commit is contained in:
commit
a7f2019055
@ -624,10 +624,12 @@
|
||||
<term><varname>ReloadLimitIntervalSec=</varname></term>
|
||||
<term><varname>ReloadLimitBurst=</varname></term>
|
||||
|
||||
<listitem><para>Rate limiting for daemon-reload requests. Default to unset, and any number of daemon-reload
|
||||
operations can be requested at any time. <varname>ReloadLimitIntervalSec=</varname> takes a value in seconds
|
||||
to configure the rate limit window, and <varname>ReloadLimitBurst=</varname> takes a positive integer to
|
||||
configure the maximum allowed number of reloads within the configured time window.</para>
|
||||
<listitem><para>Rate limiting for daemon-reload and (since v256) daemon-reexec requests. The setting
|
||||
applies to both operations, but the rate limits are tracked separately. Defaults to unset, and any
|
||||
number of operations can be requested at any time. <varname>ReloadLimitIntervalSec=</varname> takes
|
||||
a value in seconds to configure the rate limit window, and <varname>ReloadLimitBurst=</varname>
|
||||
takes a positive integer to configure the maximum allowed number of operations within the configured
|
||||
time window.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v253"/></listitem>
|
||||
</varlistentry>
|
||||
|
@ -1599,7 +1599,7 @@ static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *
|
||||
log_caller(message, m, "Reloading");
|
||||
|
||||
/* Check the rate limit after the authorization succeeds, to avoid denial-of-service issues. */
|
||||
if (!ratelimit_below(&m->reload_ratelimit)) {
|
||||
if (!ratelimit_below(&m->reload_reexec_ratelimit)) {
|
||||
log_warning("Reloading request rejected due to rate limit.");
|
||||
return sd_bus_error_setf(error,
|
||||
SD_BUS_ERROR_LIMITS_EXCEEDED,
|
||||
@ -1644,6 +1644,14 @@ static int method_reexecute(sd_bus_message *message, void *userdata, sd_bus_erro
|
||||
/* Write a log message noting the unit or process who requested the Reexecute() */
|
||||
log_caller(message, m, "Reexecuting");
|
||||
|
||||
/* Check the rate limit after the authorization succeeds, to avoid denial-of-service issues. */
|
||||
if (!ratelimit_below(&m->reload_reexec_ratelimit)) {
|
||||
log_warning("Reexecuting request rejected due to rate limit.");
|
||||
return sd_bus_error_setf(error,
|
||||
SD_BUS_ERROR_LIMITS_EXCEEDED,
|
||||
"Reexecute() request rejected due to rate limit.");
|
||||
}
|
||||
|
||||
/* We don't send a reply back here, the client should
|
||||
* just wait for us disconnecting. */
|
||||
|
||||
|
@ -810,8 +810,8 @@ static void set_manager_settings(Manager *m) {
|
||||
m->cad_burst_action = arg_cad_burst_action;
|
||||
/* Note that we don't do structured initialization here, otherwise it will reset the rate limit
|
||||
* counter on every daemon-reload. */
|
||||
m->reload_ratelimit.interval = arg_reload_limit_interval_sec;
|
||||
m->reload_ratelimit.burst = arg_reload_limit_burst;
|
||||
m->reload_reexec_ratelimit.interval = arg_reload_limit_interval_sec;
|
||||
m->reload_reexec_ratelimit.burst = arg_reload_limit_burst;
|
||||
|
||||
manager_set_watchdog(m, WATCHDOG_RUNTIME, arg_runtime_watchdog);
|
||||
manager_set_watchdog(m, WATCHDOG_REBOOT, arg_reboot_watchdog);
|
||||
|
@ -156,6 +156,7 @@ int manager_serialize(
|
||||
}
|
||||
|
||||
(void) serialize_ratelimit(f, "dump-ratelimit", &m->dump_ratelimit);
|
||||
(void) serialize_ratelimit(f, "reload-reexec-ratelimit", &m->reload_reexec_ratelimit);
|
||||
|
||||
bus_track_serialize(m->subscribed, f, "subscribed");
|
||||
|
||||
@ -519,6 +520,8 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||
(void) varlink_server_deserialize_one(m->varlink_server, val, fds);
|
||||
} else if ((val = startswith(l, "dump-ratelimit=")))
|
||||
deserialize_ratelimit(&m->dump_ratelimit, "dump-ratelimit", val);
|
||||
else if ((val = startswith(l, "reload-reexec-ratelimit=")))
|
||||
deserialize_ratelimit(&m->reload_reexec_ratelimit, "reload-reexec-ratelimit", val);
|
||||
else if ((val = startswith(l, "soft-reboots-count="))) {
|
||||
unsigned n;
|
||||
|
||||
|
@ -491,8 +491,8 @@ struct Manager {
|
||||
/* Reference to RestrictFileSystems= BPF program */
|
||||
struct restrict_fs_bpf *restrict_fs;
|
||||
|
||||
/* Allow users to configure a rate limit for Reload() operations */
|
||||
RateLimit reload_ratelimit;
|
||||
/* Allow users to configure a rate limit for Reload()/Reexecute() operations */
|
||||
RateLimit reload_reexec_ratelimit;
|
||||
/* Dump*() are slow, so always rate limit them to 10 per 10 minutes */
|
||||
RateLimit dump_ratelimit;
|
||||
|
||||
|
@ -104,6 +104,14 @@ sleep 10
|
||||
|
||||
systemctl daemon-reload
|
||||
|
||||
# Same test for reexec, but we wait here
|
||||
timeout 15 bash -c 'while systemctl daemon-reexec; do true; done'
|
||||
|
||||
# Rate limit should reset after 9s
|
||||
sleep 10
|
||||
|
||||
systemctl daemon-reexec
|
||||
|
||||
# Let's now test the notify-reload logic
|
||||
|
||||
cat >/run/notify-reload-test.sh <<EOF
|
||||
|
Loading…
Reference in New Issue
Block a user