--- Hi,
The idea is to reboot immediately when a service crashes or the watchdog triggers. This is useful in embedded scenarios when there is only one important service. There are use-cases where rebooting immediately instead of trying to restart the application first makes sense. The environment of the restarted application is not well defined. The watchdog is for unexpected failures. So making sure that the application behaves correctly can be difficult. When rebooting only takes a few seconds, doing so may be more robust than trying to recover from an undefined state. This is an RFC for now. Mostly because I think the configuration is rather awkward like this. Hooking into Restart/StartLimitAction was the easiest way to handle this in the code. But it doesn't feel natural to configure it like this. Any Ideas on how to express this in the unit file? Regards, Michael src/core/service.c | 23 ++++++++++++++++++----- src/core/service.h | 1 + 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/core/service.c b/src/core/service.c index 78a2e06..ef494ba 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1832,6 +1832,8 @@ static int cgroup_good(Service *s) { return !r; } +static int service_start_limit_execute(Service *s); + static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) { int r; assert(s); @@ -1843,6 +1845,10 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) if (allow_restart && !s->forbid_restart && + s->restart == SERVICE_RESTART_FAIL) { + service_start_limit_execute(s); + } else if (allow_restart && + !s->forbid_restart && (s->restart == SERVICE_RESTART_ALWAYS || (s->restart == SERVICE_RESTART_ON_SUCCESS && s->result == SERVICE_SUCCESS) || (s->restart == SERVICE_RESTART_ON_FAILURE && s->result != SERVICE_SUCCESS) || @@ -2363,12 +2369,9 @@ fail: service_enter_stop(s, SERVICE_FAILURE_RESOURCES); } -static int service_start_limit_test(Service *s) { +static int service_start_limit_execute(Service *s) { assert(s); - if (ratelimit_test(&s->start_limit)) - return 0; - switch (s->start_limit_action) { case SERVICE_START_LIMIT_NONE: @@ -2416,6 +2419,15 @@ static int service_start_limit_test(Service *s) { return -ECANCELED; } +static int service_start_limit_test(Service *s) { + assert(s); + + if (ratelimit_test(&s->start_limit)) + return 0; + + return service_start_limit_execute(s); +} + static int service_start(Unit *u) { Service *s = SERVICE(u); int r; @@ -3754,7 +3766,8 @@ static const char* const service_restart_table[_SERVICE_RESTART_MAX] = { [SERVICE_RESTART_ON_FAILURE] = "on-failure", [SERVICE_RESTART_ON_WATCHDOG] = "on-watchdog", [SERVICE_RESTART_ON_ABORT] = "on-abort", - [SERVICE_RESTART_ALWAYS] = "always" + [SERVICE_RESTART_ALWAYS] = "always", + [SERVICE_RESTART_FAIL] = "fail" }; DEFINE_STRING_TABLE_LOOKUP(service_restart, ServiceRestart); diff --git a/src/core/service.h b/src/core/service.h index 1992926..2cdc7ad 100644 --- a/src/core/service.h +++ b/src/core/service.h @@ -56,6 +56,7 @@ typedef enum ServiceRestart { SERVICE_RESTART_ON_WATCHDOG, SERVICE_RESTART_ON_ABORT, SERVICE_RESTART_ALWAYS, + SERVICE_RESTART_FAIL, _SERVICE_RESTART_MAX, _SERVICE_RESTART_INVALID = -1 } ServiceRestart; -- 1.9.1 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel