Merge pull request #30024 from keszybz/one-doc-thingy

Serialize units ratelimits and document StartLimitIntervalSec=infinity
This commit is contained in:
Luca Boccassi 2023-11-22 17:42:51 +00:00 committed by GitHub
commit 31897753fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 72 additions and 39 deletions

View File

@ -1166,6 +1166,8 @@
<para><replaceable>interval</replaceable> is a time span with the default unit of seconds, but other
units may be specified, see
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
The special value <literal>infinity</literal> can be used to limit the total number of start
attempts, even if they happen at large time intervals.
Defaults to <varname>DefaultStartLimitIntervalSec=</varname> in manager configuration file, and may
be set to 0 to disable any kind of rate limiting. <replaceable>burst</replaceable> is a number and
defaults to <varname>DefaultStartLimitBurst=</varname> in manager configuration file.</para>

View File

@ -12,6 +12,8 @@ typedef struct RateLimit {
usec_t begin;
} RateLimit;
#define RATELIMIT_OFF (const RateLimit) { .interval = USEC_INFINITY, .burst = UINT_MAX }
static inline void ratelimit_reset(RateLimit *rl) {
rl->num = rl->begin = 0;
}

View File

@ -152,13 +152,7 @@ int manager_serialize(
(void) serialize_item_format(f, "user-lookup", "%i %i", copy0, copy1);
}
(void) serialize_item_format(f,
"dump-ratelimit",
USEC_FMT " " USEC_FMT " %u %u",
m->dump_ratelimit.begin,
m->dump_ratelimit.interval,
m->dump_ratelimit.num,
m->dump_ratelimit.burst);
(void) serialize_ratelimit(f, "dump-ratelimit", &m->dump_ratelimit);
bus_track_serialize(m->subscribed, f, "subscribed");
@ -519,22 +513,9 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
* remains set until all serialized contents are handled. */
if (deserialize_varlink_sockets)
(void) varlink_server_deserialize_one(m->varlink_server, val, fds);
} else if ((val = startswith(l, "dump-ratelimit="))) {
usec_t begin, interval;
unsigned num, burst;
if (sscanf(val, USEC_FMT " " USEC_FMT " %u %u", &begin, &interval, &num, &burst) != 4)
log_notice("Failed to parse dump ratelimit, ignoring: %s", val);
else {
/* If we changed the values across versions, flush the counter */
if (interval != m->dump_ratelimit.interval || burst != m->dump_ratelimit.burst)
m->dump_ratelimit.num = 0;
else
m->dump_ratelimit.num = num;
m->dump_ratelimit.begin = begin;
}
} else {
} else if ((val = startswith(l, "dump-ratelimit=")))
deserialize_ratelimit(&m->dump_ratelimit, "dump-ratelimit", val);
else {
ManagerTimestamp q;
for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {

View File

@ -892,10 +892,7 @@ int manager_new(RuntimeScope runtime_scope, ManagerTestRunFlags test_run_flags,
.first_boot = -1,
.test_run_flags = test_run_flags,
.dump_ratelimit = {
.interval = 10 * USEC_PER_MINUTE,
.burst = 10,
},
.dump_ratelimit = (const RateLimit) { .interval = 10 * USEC_PER_MINUTE, .burst = 10 },
.executor_fd = -EBADF,
};

View File

@ -279,8 +279,7 @@ static void path_init(Unit *u) {
p->directory_mode = 0755;
p->trigger_limit.interval = USEC_INFINITY;
p->trigger_limit.burst = UINT_MAX;
p->trigger_limit = RATELIMIT_OFF;
}
void path_free_specs(Path *p) {
@ -683,6 +682,8 @@ static int path_serialize(Unit *u, FILE *f, FDSet *fds) {
escaped);
}
(void) serialize_ratelimit(f, "trigger-ratelimit", &p->trigger_limit);
return 0;
}
@ -744,7 +745,10 @@ static int path_deserialize_item(Unit *u, const char *key, const char *value, FD
}
}
} else
} else if (streq(key, "trigger-ratelimit"))
deserialize_ratelimit(&p->trigger_limit, key, value);
else
log_unit_debug(u, "Unknown serialization key: %s", key);
return 0;

View File

@ -100,8 +100,7 @@ static void socket_init(Unit *u) {
s->control_pid = PIDREF_NULL;
s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
s->trigger_limit.interval = USEC_INFINITY;
s->trigger_limit.burst = UINT_MAX;
s->trigger_limit = RATELIMIT_OFF;
s->poll_limit_interval = USEC_INFINITY;
s->poll_limit_burst = UINT_MAX;
@ -2590,6 +2589,8 @@ static int socket_serialize(Unit *u, FILE *f, FDSet *fds) {
}
}
(void) serialize_ratelimit(f, "trigger-ratelimit", &s->trigger_limit);
return 0;
}
@ -2824,7 +2825,10 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
if (!found)
log_unit_debug(u, "No matching ffs socket found: %s", value);
} else
} else if (streq(key, "trigger-ratelimit"))
deserialize_ratelimit(&s->trigger_limit, key, value);
else
log_unit_debug(UNIT(s), "Unknown serialization key: %s", key);
return 0;

View File

@ -140,6 +140,9 @@ int unit_serialize_state(Unit *u, FILE *f, FDSet *fds, bool switching_root) {
(void) serialize_dual_timestamp(f, "condition-timestamp", &u->condition_timestamp);
(void) serialize_dual_timestamp(f, "assert-timestamp", &u->assert_timestamp);
(void) serialize_ratelimit(f, "start-ratelimit", &u->start_ratelimit);
(void) serialize_ratelimit(f, "auto-start-stop-ratelimit", &u->auto_start_stop_ratelimit);
if (dual_timestamp_is_set(&u->condition_timestamp))
(void) serialize_bool(f, "condition-result", u->condition_result);
@ -343,6 +346,13 @@ int unit_deserialize_state(Unit *u, FILE *f, FDSet *fds) {
(void) deserialize_dual_timestamp(v, &u->assert_timestamp);
continue;
} else if (streq(l, "start-ratelimit")) {
deserialize_ratelimit(&u->start_ratelimit, l, v);
continue;
} else if (streq(l, "auto-start-stop-ratelimit")) {
deserialize_ratelimit(&u->auto_start_stop_ratelimit, l, v);
continue;
} else if (MATCH_DESERIALIZE("condition-result", l, v, parse_boolean, u->condition_result))
continue;

View File

@ -132,15 +132,12 @@ Unit* unit_new(Manager *m, size_t size) {
u->last_section_private = -1;
u->start_ratelimit = (RateLimit) {
u->start_ratelimit = (const RateLimit) {
m->defaults.start_limit_interval,
m->defaults.start_limit_burst
m->defaults.start_limit_burst,
};
u->auto_start_stop_ratelimit = (const RateLimit) {
10 * USEC_PER_SEC,
16
};
u->auto_start_stop_ratelimit = (const RateLimit) { .interval = 10 * USEC_PER_SEC, .burst = 16 };
return u;
}

View File

@ -201,6 +201,17 @@ int serialize_pidref(FILE *f, FDSet *fds, const char *key, PidRef *pidref) {
return serialize_item_format(f, key, "@%i", copy);
}
int serialize_ratelimit(FILE *f, const char *key, const RateLimit *rl) {
assert(rl);
return serialize_item_format(f, key,
USEC_FMT " " USEC_FMT " %u %u",
rl->begin,
rl->interval,
rl->num,
rl->burst);
}
int serialize_item_hexmem(FILE *f, const char *key, const void *p, size_t l) {
_cleanup_free_ char *encoded = NULL;
int r;
@ -486,6 +497,22 @@ int deserialize_pidref(FDSet *fds, const char *value, PidRef *ret) {
return 0;
}
void deserialize_ratelimit(RateLimit *rl, const char *name, const char *value) {
usec_t begin, interval;
unsigned num, burst;
assert(rl);
assert(name);
assert(value);
if (sscanf(value, USEC_FMT " " USEC_FMT " %u %u", &begin, &interval, &num, &burst) != 4)
return log_notice("Failed to parse %s, ignoring: %s", name, value);
/* Preserve the counter only if the configuration didn't change. */
rl->num = (interval == rl->interval && burst == rl->burst) ? num : 0;
rl->begin = begin;
}
int open_serialization_fd(const char *ident) {
int fd;

View File

@ -7,6 +7,7 @@
#include "image-policy.h"
#include "macro.h"
#include "pidref.h"
#include "ratelimit.h"
#include "set.h"
#include "string-util.h"
#include "time-util.h"
@ -22,6 +23,7 @@ int serialize_usec(FILE *f, const char *key, usec_t usec);
int serialize_dual_timestamp(FILE *f, const char *key, const dual_timestamp *t);
int serialize_strv(FILE *f, const char *key, char **l);
int serialize_pidref(FILE *f, FDSet *fds, const char *key, PidRef *pidref);
int serialize_ratelimit(FILE *f, const char *key, const RateLimit *rl);
int serialize_string_set(FILE *f, const char *key, Set *s);
int serialize_image_policy(FILE *f, const char *key, const ImagePolicy *p);
@ -45,6 +47,7 @@ int deserialize_dual_timestamp(const char *value, dual_timestamp *ret);
int deserialize_environment(const char *value, char ***environment);
int deserialize_strv(const char *value, char ***l);
int deserialize_pidref(FDSet *fds, const char *value, PidRef *ret);
void deserialize_ratelimit(RateLimit *rl, const char *name, const char *value);
int open_serialization_fd(const char *ident);
int open_serialization_file(const char *ident, FILE **ret);

View File

@ -7,6 +7,9 @@ set -o pipefail
mkdir /run/systemd/system/systemd-journald.service.d
MACHINE_ID="$(</etc/machine-id)"
# Reset the start-limit counters, as we're going to restart journald a couple of times
systemctl reset-failed systemd-journald.service
for c in NONE XZ LZ4 ZSTD; do
cat >/run/systemd/system/systemd-journald.service.d/compress.conf <<EOF
[Service]
@ -35,4 +38,5 @@ done
rm /run/systemd/system/systemd-journald.service.d/compress.conf
systemctl daemon-reload
systemctl restart systemd-journald.service
systemctl reset-failed systemd-journald.service
journalctl --rotate

View File

@ -88,6 +88,8 @@ do
# Make sure we are in a consistent state, e.g. not already active before we start
systemctl stop systemd-integritysetup@"${DM_NAME}".service || exit 1
systemctl start systemd-integritysetup@"${DM_NAME}".service || exit 1
# Reset the start-limit counters, as we're going to restart the service a couple of times
systemctl reset-failed systemd-integritysetup@"${DM_NAME}".service
# Check the signature on the FS to ensure we can retrieve it and that is matches
if [ -e "${FULL_DM_DEV_NAME}" ]; then