summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--man/systemd.service.xml33
-rw-r--r--src/service.c10
-rw-r--r--src/service.h2
4 files changed, 31 insertions, 16 deletions
diff --git a/TODO b/TODO
index 0a7efa111a..3828a11326 100644
--- a/TODO
+++ b/TODO
@@ -84,8 +84,6 @@
* enable syslog.socket by default, activating our kmsg bridge
-* Restart=on-failure and Restart=on-abort
-
* when processes remain in a service even though the start command failed enter active
* fix plymouth socket, when plymouth started to use a clean one
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 66806f1bd2..c9cd51f739 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -426,19 +426,28 @@
<varlistentry>
<term><varname>Restart=</varname></term>
<listitem><para>Configures whether the
- main service process shall be restarted when
- it exists. Takes one of
+ main service process shall be
+ restarted when it exists. Takes one of
<option>no</option>,
- <option>on-success</option> or
- <option>always</option>. If
- set to <option>no</option> (the
- default) the service will not be
- restarted when it exits. If set to
- <option>on-success</option> it
- will be restarted only when it exited
- cleanly, i.e. terminated with an exit
- code of 0. If set to
- <option>always</option> the
+ <option>on-success</option>,
+ <option>on-failure</option>,
+ <option>on-abort</option> or
+ <option>always</option>. If set to
+ <option>no</option> (the default) the
+ service will not be restarted when it
+ exits. If set to
+ <option>on-success</option> it will be
+ restarted only when it exited cleanly,
+ i.e. terminated with an exit code of
+ 0. If set to
+ <option>on-failure</option> it will be
+ restared only when it exited with an
+ exit code not equalling 0, or when
+ terminated by a signal. If set to
+ <option>on-abort</option> it will be
+ restarted only if it exits due to
+ reception of an uncaught signal. If
+ set to <option>always</option> the
service will be restarted regardless
whether it exited cleanly or not, or
got terminated abnormally by a
diff --git a/src/service.c b/src/service.c
index 04496a2dd2..d3852c76a1 100644
--- a/src/service.c
+++ b/src/service.c
@@ -1627,7 +1627,11 @@ static void service_enter_dead(Service *s, bool success, bool allow_restart) {
if (allow_restart &&
!s->forbid_restart &&
(s->restart == SERVICE_RESTART_ALWAYS ||
- (s->restart == SERVICE_RESTART_ON_SUCCESS && !s->failure))) {
+ (s->restart == SERVICE_RESTART_ON_SUCCESS && !s->failure) ||
+ (s->restart == SERVICE_RESTART_ON_FAILURE && s->failure) ||
+ (s->restart == SERVICE_RESTART_ON_ABORT && s->failure &&
+ (s->main_exec_status.code == CLD_KILLED ||
+ s->main_exec_status.code == CLD_DUMPED)))) {
if ((r = unit_watch_timer(UNIT(s), s->restart_usec, &s->timer_watch)) < 0)
goto fail;
@@ -3115,7 +3119,9 @@ DEFINE_STRING_TABLE_LOOKUP(service_state, ServiceState);
static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
[SERVICE_RESTART_NO] = "no",
[SERVICE_RESTART_ON_SUCCESS] = "on-success",
- [SERVICE_RESTART_ALWAYS] = "always",
+ [SERVICE_RESTART_ON_FAILURE] = "on-failure",
+ [SERVICE_RESTART_ON_ABORT] = "on-abort",
+ [SERVICE_RESTART_ALWAYS] = "always"
};
DEFINE_STRING_TABLE_LOOKUP(service_restart, ServiceRestart);
diff --git a/src/service.h b/src/service.h
index f47346702f..eb44a43895 100644
--- a/src/service.h
+++ b/src/service.h
@@ -50,6 +50,8 @@ typedef enum ServiceState {
typedef enum ServiceRestart {
SERVICE_RESTART_NO,
SERVICE_RESTART_ON_SUCCESS,
+ SERVICE_RESTART_ON_FAILURE,
+ SERVICE_RESTART_ON_ABORT,
SERVICE_RESTART_ALWAYS,
_SERVICE_RESTART_MAX,
_SERVICE_RESTART_INVALID = -1