summaryrefslogtreecommitdiff
path: root/src/core/service.c
diff options
context:
space:
mode:
authorLukas Nykryn <lnykryn@redhat.com>2012-08-13 13:58:01 +0200
committerLennart Poettering <lennart@poettering.net>2012-08-14 14:46:03 +0200
commit96342de68d0d6de71a062d984dafd2a0905ed9fe (patch)
treeadbeb686c6c3c2bfd5a1c8768555575acb4850a2 /src/core/service.c
parentd98cc1f29fbf31ccc500d6e20c29b636b9af7e0f (diff)
service: add options RestartPreventExitStatus and SuccessExitStatus
In some cases, like wrong configuration, restarting after error does not help, so administrator can specify statuses by RestartPreventExitStatus which will not cause restart of a service. Sometimes you have non-standart exit status, so this can be specified by SuccessfulExitStatus.
Diffstat (limited to 'src/core/service.c')
-rw-r--r--src/core/service.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/core/service.c b/src/core/service.c
index e74da54eac..f540752b61 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -294,6 +294,16 @@ static void service_done(Unit *u) {
s->control_command = NULL;
s->main_command = NULL;
+ set_free(s->restart_ignore_status.code);
+ s->restart_ignore_status.code = NULL;
+ set_free(s->restart_ignore_status.signal);
+ s->restart_ignore_status.signal = NULL;
+
+ set_free(s->success_status.code);
+ s->success_status.code = NULL;
+ set_free(s->success_status.signal);
+ s->success_status.signal = NULL;
+
/* This will leak a process, but at least no memory or any of
* our resources */
service_unwatch_main_pid(s);
@@ -1902,7 +1912,12 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
(s->restart == SERVICE_RESTART_ON_SUCCESS && s->result == SERVICE_SUCCESS) ||
(s->restart == SERVICE_RESTART_ON_FAILURE && s->result != SERVICE_SUCCESS) ||
(s->restart == SERVICE_RESTART_ON_ABORT && (s->result == SERVICE_FAILURE_SIGNAL ||
- s->result == SERVICE_FAILURE_CORE_DUMP)))) {
+ s->result == SERVICE_FAILURE_CORE_DUMP))) &&
+ (s->result != SERVICE_FAILURE_EXIT_CODE ||
+ !set_contains(s->restart_ignore_status.code, INT_TO_PTR(s->main_exec_status.status))) &&
+ (s->result != SERVICE_FAILURE_SIGNAL ||
+ !set_contains(s->restart_ignore_status.signal, INT_TO_PTR(s->main_exec_status.status)))
+ ) {
r = unit_watch_timer(UNIT(s), s->restart_usec, &s->timer_watch);
if (r < 0)
@@ -2874,7 +2889,8 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
assert(s);
assert(pid >= 0);
- if (UNIT(s)->fragment_path ? is_clean_exit(code, status) : is_clean_exit_lsb(code, status))
+ if (UNIT(s)->fragment_path ? is_clean_exit(code, status, &s->success_status) :
+ is_clean_exit_lsb(code, status, &s->success_status))
f = SERVICE_SUCCESS;
else if (code == CLD_EXITED)
f = SERVICE_FAILURE_EXIT_CODE;