From 67bfdc9771ce9d67b6ecff9982d2ecb89bdb2f6b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 19 May 2015 16:23:14 +0200 Subject: core: also enforce ratelimiter if we stop a unit due to BindsTo= This extends on bea355dac94e82697aa98e25d80ee4248263bf92, and extends the ratelimiter to not only be used for StopWhenUnneeded=1 units but also for units that have BindsTo= on a unit that is dead. http://lists.freedesktop.org/archives/systemd-devel/2015-April/030224.html --- src/core/unit.c | 17 ++++++++++++++--- src/core/unit.h | 4 ++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/core/unit.c b/src/core/unit.c index 956711d500..2da2565503 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -91,7 +91,7 @@ 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); + RATELIMIT_INIT(u->auto_stop_ratelimit, 10 * USEC_PER_SEC, 16); return u; } @@ -1627,7 +1627,7 @@ static void unit_check_unneeded(Unit *u) { /* 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)) { + if (!ratelimit_test(&u->auto_stop_ratelimit)) { log_unit_warning(u, "Unit not needed anymore, but not stopping since we tried this too often recently."); return; } @@ -1644,6 +1644,7 @@ static void unit_check_binds_to(Unit *u) { bool stop = false; Unit *other; Iterator i; + int r; assert(u); @@ -1667,11 +1668,21 @@ static void unit_check_binds_to(Unit *u) { if (!stop) 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->auto_stop_ratelimit)) { + log_unit_warning(u, "Unit is bound to inactive unit %s, but not stopping since we tried this too often recently.", other->id); + return; + } + assert(other); log_unit_info(u, "Unit is bound to inactive unit %s. Stopping, too.", other->id); /* A unit we need to run is gone. Sniff. Let's stop this. */ - manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL); + r = manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL); + if (r < 0) + log_unit_warning_errno(u, r, "Failed to enqueue stop job, ignoring: %m"); } static void retroactively_start_dependencies(Unit *u) { diff --git a/src/core/unit.h b/src/core/unit.h index 3c9a64f898..7ef970e9b8 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -175,8 +175,8 @@ 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; + /* Make sure we never enter endless loops with the check unneeded logic, or the BindsTo= logic */ + RateLimit auto_stop_ratelimit; /* Cached unit file state and preset */ UnitFileState unit_file_state; -- cgit v1.2.3-54-g00ecf