Skip to content

Commit 3189775

Browse files
authored
Merge pull request #30024 from keszybz/one-doc-thingy
Serialize units ratelimits and document StartLimitIntervalSec=infinity
2 parents 9b85e90 + 51ad723 commit 3189775

File tree

12 files changed

+72
-39
lines changed

12 files changed

+72
-39
lines changed

man/systemd.unit.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,8 @@
11661166
<para><replaceable>interval</replaceable> is a time span with the default unit of seconds, but other
11671167
units may be specified, see
11681168
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
1169+
The special value <literal>infinity</literal> can be used to limit the total number of start
1170+
attempts, even if they happen at large time intervals.
11691171
Defaults to <varname>DefaultStartLimitIntervalSec=</varname> in manager configuration file, and may
11701172
be set to 0 to disable any kind of rate limiting. <replaceable>burst</replaceable> is a number and
11711173
defaults to <varname>DefaultStartLimitBurst=</varname> in manager configuration file.</para>

src/basic/ratelimit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ typedef struct RateLimit {
1212
usec_t begin;
1313
} RateLimit;
1414

15+
#define RATELIMIT_OFF (const RateLimit) { .interval = USEC_INFINITY, .burst = UINT_MAX }
16+
1517
static inline void ratelimit_reset(RateLimit *rl) {
1618
rl->num = rl->begin = 0;
1719
}

src/core/manager-serialize.c

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,7 @@ int manager_serialize(
152152
(void) serialize_item_format(f, "user-lookup", "%i %i", copy0, copy1);
153153
}
154154

155-
(void) serialize_item_format(f,
156-
"dump-ratelimit",
157-
USEC_FMT " " USEC_FMT " %u %u",
158-
m->dump_ratelimit.begin,
159-
m->dump_ratelimit.interval,
160-
m->dump_ratelimit.num,
161-
m->dump_ratelimit.burst);
155+
(void) serialize_ratelimit(f, "dump-ratelimit", &m->dump_ratelimit);
162156

163157
bus_track_serialize(m->subscribed, f, "subscribed");
164158

@@ -519,22 +513,9 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
519513
* remains set until all serialized contents are handled. */
520514
if (deserialize_varlink_sockets)
521515
(void) varlink_server_deserialize_one(m->varlink_server, val, fds);
522-
} else if ((val = startswith(l, "dump-ratelimit="))) {
523-
usec_t begin, interval;
524-
unsigned num, burst;
525-
526-
if (sscanf(val, USEC_FMT " " USEC_FMT " %u %u", &begin, &interval, &num, &burst) != 4)
527-
log_notice("Failed to parse dump ratelimit, ignoring: %s", val);
528-
else {
529-
/* If we changed the values across versions, flush the counter */
530-
if (interval != m->dump_ratelimit.interval || burst != m->dump_ratelimit.burst)
531-
m->dump_ratelimit.num = 0;
532-
else
533-
m->dump_ratelimit.num = num;
534-
m->dump_ratelimit.begin = begin;
535-
}
536-
537-
} else {
516+
} else if ((val = startswith(l, "dump-ratelimit=")))
517+
deserialize_ratelimit(&m->dump_ratelimit, "dump-ratelimit", val);
518+
else {
538519
ManagerTimestamp q;
539520

540521
for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {

src/core/manager.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -892,10 +892,7 @@ int manager_new(RuntimeScope runtime_scope, ManagerTestRunFlags test_run_flags,
892892
.first_boot = -1,
893893
.test_run_flags = test_run_flags,
894894

895-
.dump_ratelimit = {
896-
.interval = 10 * USEC_PER_MINUTE,
897-
.burst = 10,
898-
},
895+
.dump_ratelimit = (const RateLimit) { .interval = 10 * USEC_PER_MINUTE, .burst = 10 },
899896

900897
.executor_fd = -EBADF,
901898
};

src/core/path.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,7 @@ static void path_init(Unit *u) {
279279

280280
p->directory_mode = 0755;
281281

282-
p->trigger_limit.interval = USEC_INFINITY;
283-
p->trigger_limit.burst = UINT_MAX;
282+
p->trigger_limit = RATELIMIT_OFF;
284283
}
285284

286285
void path_free_specs(Path *p) {
@@ -683,6 +682,8 @@ static int path_serialize(Unit *u, FILE *f, FDSet *fds) {
683682
escaped);
684683
}
685684

685+
(void) serialize_ratelimit(f, "trigger-ratelimit", &p->trigger_limit);
686+
686687
return 0;
687688
}
688689

@@ -744,7 +745,10 @@ static int path_deserialize_item(Unit *u, const char *key, const char *value, FD
744745
}
745746
}
746747

747-
} else
748+
} else if (streq(key, "trigger-ratelimit"))
749+
deserialize_ratelimit(&p->trigger_limit, key, value);
750+
751+
else
748752
log_unit_debug(u, "Unknown serialization key: %s", key);
749753

750754
return 0;

src/core/socket.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ static void socket_init(Unit *u) {
100100
s->control_pid = PIDREF_NULL;
101101
s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
102102

103-
s->trigger_limit.interval = USEC_INFINITY;
104-
s->trigger_limit.burst = UINT_MAX;
103+
s->trigger_limit = RATELIMIT_OFF;
105104

106105
s->poll_limit_interval = USEC_INFINITY;
107106
s->poll_limit_burst = UINT_MAX;
@@ -2590,6 +2589,8 @@ static int socket_serialize(Unit *u, FILE *f, FDSet *fds) {
25902589
}
25912590
}
25922591

2592+
(void) serialize_ratelimit(f, "trigger-ratelimit", &s->trigger_limit);
2593+
25932594
return 0;
25942595
}
25952596

@@ -2824,7 +2825,10 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
28242825
if (!found)
28252826
log_unit_debug(u, "No matching ffs socket found: %s", value);
28262827

2827-
} else
2828+
} else if (streq(key, "trigger-ratelimit"))
2829+
deserialize_ratelimit(&s->trigger_limit, key, value);
2830+
2831+
else
28282832
log_unit_debug(UNIT(s), "Unknown serialization key: %s", key);
28292833

28302834
return 0;

src/core/unit-serialize.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ int unit_serialize_state(Unit *u, FILE *f, FDSet *fds, bool switching_root) {
140140
(void) serialize_dual_timestamp(f, "condition-timestamp", &u->condition_timestamp);
141141
(void) serialize_dual_timestamp(f, "assert-timestamp", &u->assert_timestamp);
142142

143+
(void) serialize_ratelimit(f, "start-ratelimit", &u->start_ratelimit);
144+
(void) serialize_ratelimit(f, "auto-start-stop-ratelimit", &u->auto_start_stop_ratelimit);
145+
143146
if (dual_timestamp_is_set(&u->condition_timestamp))
144147
(void) serialize_bool(f, "condition-result", u->condition_result);
145148

@@ -343,6 +346,13 @@ int unit_deserialize_state(Unit *u, FILE *f, FDSet *fds) {
343346
(void) deserialize_dual_timestamp(v, &u->assert_timestamp);
344347
continue;
345348

349+
} else if (streq(l, "start-ratelimit")) {
350+
deserialize_ratelimit(&u->start_ratelimit, l, v);
351+
continue;
352+
} else if (streq(l, "auto-start-stop-ratelimit")) {
353+
deserialize_ratelimit(&u->auto_start_stop_ratelimit, l, v);
354+
continue;
355+
346356
} else if (MATCH_DESERIALIZE("condition-result", l, v, parse_boolean, u->condition_result))
347357
continue;
348358

src/core/unit.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,12 @@ Unit* unit_new(Manager *m, size_t size) {
132132

133133
u->last_section_private = -1;
134134

135-
u->start_ratelimit = (RateLimit) {
135+
u->start_ratelimit = (const RateLimit) {
136136
m->defaults.start_limit_interval,
137-
m->defaults.start_limit_burst
137+
m->defaults.start_limit_burst,
138138
};
139139

140-
u->auto_start_stop_ratelimit = (const RateLimit) {
141-
10 * USEC_PER_SEC,
142-
16
143-
};
140+
u->auto_start_stop_ratelimit = (const RateLimit) { .interval = 10 * USEC_PER_SEC, .burst = 16 };
144141

145142
return u;
146143
}

src/shared/serialize.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,17 @@ int serialize_pidref(FILE *f, FDSet *fds, const char *key, PidRef *pidref) {
201201
return serialize_item_format(f, key, "@%i", copy);
202202
}
203203

204+
int serialize_ratelimit(FILE *f, const char *key, const RateLimit *rl) {
205+
assert(rl);
206+
207+
return serialize_item_format(f, key,
208+
USEC_FMT " " USEC_FMT " %u %u",
209+
rl->begin,
210+
rl->interval,
211+
rl->num,
212+
rl->burst);
213+
}
214+
204215
int serialize_item_hexmem(FILE *f, const char *key, const void *p, size_t l) {
205216
_cleanup_free_ char *encoded = NULL;
206217
int r;
@@ -486,6 +497,22 @@ int deserialize_pidref(FDSet *fds, const char *value, PidRef *ret) {
486497
return 0;
487498
}
488499

500+
void deserialize_ratelimit(RateLimit *rl, const char *name, const char *value) {
501+
usec_t begin, interval;
502+
unsigned num, burst;
503+
504+
assert(rl);
505+
assert(name);
506+
assert(value);
507+
508+
if (sscanf(value, USEC_FMT " " USEC_FMT " %u %u", &begin, &interval, &num, &burst) != 4)
509+
return log_notice("Failed to parse %s, ignoring: %s", name, value);
510+
511+
/* Preserve the counter only if the configuration didn't change. */
512+
rl->num = (interval == rl->interval && burst == rl->burst) ? num : 0;
513+
rl->begin = begin;
514+
}
515+
489516
int open_serialization_fd(const char *ident) {
490517
int fd;
491518

src/shared/serialize.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "image-policy.h"
88
#include "macro.h"
99
#include "pidref.h"
10+
#include "ratelimit.h"
1011
#include "set.h"
1112
#include "string-util.h"
1213
#include "time-util.h"
@@ -22,6 +23,7 @@ int serialize_usec(FILE *f, const char *key, usec_t usec);
2223
int serialize_dual_timestamp(FILE *f, const char *key, const dual_timestamp *t);
2324
int serialize_strv(FILE *f, const char *key, char **l);
2425
int serialize_pidref(FILE *f, FDSet *fds, const char *key, PidRef *pidref);
26+
int serialize_ratelimit(FILE *f, const char *key, const RateLimit *rl);
2527
int serialize_string_set(FILE *f, const char *key, Set *s);
2628
int serialize_image_policy(FILE *f, const char *key, const ImagePolicy *p);
2729

@@ -45,6 +47,7 @@ int deserialize_dual_timestamp(const char *value, dual_timestamp *ret);
4547
int deserialize_environment(const char *value, char ***environment);
4648
int deserialize_strv(const char *value, char ***l);
4749
int deserialize_pidref(FDSet *fds, const char *value, PidRef *ret);
50+
void deserialize_ratelimit(RateLimit *rl, const char *name, const char *value);
4851

4952
int open_serialization_fd(const char *ident);
5053
int open_serialization_file(const char *ident, FILE **ret);

0 commit comments

Comments
 (0)