core: enforce a ratelimiter when stopping units due to StopWhenUnneeded=1

Otherwise we might end up in an endless stop loop.

http://lists.freedesktop.org/archives/systemd-devel/2015-April/030224.html
This commit is contained in:
Lennart Poettering 2015-05-19 16:00:24 +02:00
parent f3b85044c8
commit bea355dac9
2 changed files with 13 additions and 0 deletions

View File

@ -91,6 +91,8 @@ Unit *unit_new(Manager *m, size_t size) {
u->unit_file_preset = -1;
u->on_failure_job_mode = JOB_REPLACE;
RATELIMIT_INIT(u->check_unneeded_ratelimit, 10 * USEC_PER_SEC, 16);
return u;
}
@ -1622,6 +1624,14 @@ static void unit_check_unneeded(Unit *u) {
if (unit_active_or_pending(other))
return;
/* If stopping a unit fails continously we might enter a stop
* loop here, hence stop acting on the service being
* unnecessary after a while. */
if (!ratelimit_test(&u->check_unneeded_ratelimit)) {
log_unit_warning(u, "Unit not needed anymore, but not stopping since we tried this too often recently.");
return;
}
log_unit_info(u, "Unit not needed anymore. Stopping.");
/* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */

View File

@ -175,6 +175,9 @@ struct Unit {
/* Error code when we didn't manage to load the unit (negative) */
int load_error;
/* Make sure we never enter endless loops with the check unneeded logic */
RateLimit check_unneeded_ratelimit;
/* Cached unit file state and preset */
UnitFileState unit_file_state;
int unit_file_preset;