[systemd-devel] [PATCH 1/2] service: add FailureAction= option
Michael Olbrich
m.olbrich at pengutronix.de
Mon Apr 14 23:26:59 PDT 2014
It has the same possible values as StartLimitAction= and is executed
immediately if a service fails.
---
man/systemd.service.xml | 11 +++++++++++
src/core/dbus-service.c | 1 +
src/core/load-fragment-gperf.gperf.m4 | 1 +
src/core/service.c | 35 +++++++++++++++++++++++------------
src/core/service.h | 2 ++
5 files changed, 38 insertions(+), 12 deletions(-)
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 5b3afb8..0eb02bc 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -1017,6 +1017,17 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
<option>none</option>.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>FailureAction=</varname></term>
+ <listitem><para>Configure the action
+ to take when the service enters a failed
+ state. Takes the same values as
+ <varname>StartLimitAction=</varname>
+ and executes the same actions.
+ Defaults to <option>none</option>.
+ </para></listitem>
+ </varlistentry>
+
</variablelist>
<para>Check
diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
index 0451790..1e710e3 100644
--- a/src/core/dbus-service.c
+++ b/src/core/dbus-service.c
@@ -50,6 +50,7 @@ const sd_bus_vtable bus_service_vtable[] = {
SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Service, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Service, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("StartLimitAction", "s", property_get_start_limit_action, offsetof(Service, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("FailureAction", "s", property_get_start_limit_action, offsetof(Service, failure_action), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PermissionsStartOnly", "b", bus_property_get_bool, offsetof(Service, permissions_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootDirectoryStartOnly", "b", bus_property_get_bool, offsetof(Service, root_directory_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RemainAfterExit", "b", bus_property_get_bool, offsetof(Service, remain_after_exit), SD_BUS_VTABLE_PROPERTY_CONST),
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index dbb5d13..dc83247 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -180,6 +180,7 @@ Service.WatchdogSec, config_parse_sec, 0,
Service.StartLimitInterval, config_parse_sec, 0, offsetof(Service, start_limit.interval)
Service.StartLimitBurst, config_parse_unsigned, 0, offsetof(Service, start_limit.burst)
Service.StartLimitAction, config_parse_start_limit_action, 0, offsetof(Service, start_limit_action)
+Service.FailureAction, config_parse_start_limit_action, 0, offsetof(Service, failure_action)
Service.Type, config_parse_service_type, 0, offsetof(Service, type)
Service.Restart, config_parse_service_restart, 0, offsetof(Service, restart)
Service.PermissionsStartOnly, config_parse_bool, 0, offsetof(Service, permissions_start_only)
diff --git a/src/core/service.c b/src/core/service.c
index ae3695a..a71885c 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1835,6 +1835,8 @@ static int cgroup_good(Service *s) {
return !r;
}
+static int service_execute_action(Service *s, StartLimitAction action, const char *reason, bool log_action_none);
+
static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) {
int r;
assert(s);
@@ -1844,6 +1846,9 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD);
+ if (s->result != SERVICE_SUCCESS)
+ service_execute_action(s, s->failure_action, "failed", false);
+
if (allow_restart &&
!s->forbid_restart &&
(s->restart == SERVICE_RESTART_ALWAYS ||
@@ -2366,18 +2371,15 @@ fail:
service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
}
-static int service_start_limit_test(Service *s) {
+static int service_execute_action(Service *s, StartLimitAction action, const char *reason, bool log_action_none) {
assert(s);
- if (ratelimit_test(&s->start_limit))
- return 0;
-
- switch (s->start_limit_action) {
+ switch (action) {
case SERVICE_START_LIMIT_NONE:
- log_warning_unit(UNIT(s)->id,
- "%s start request repeated too quickly, refusing to start.",
- UNIT(s)->id);
+ if (log_action_none)
+ log_warning_unit(UNIT(s)->id,
+ "%s %s, refusing to start.", UNIT(s)->id, reason);
break;
case SERVICE_START_LIMIT_REBOOT: {
@@ -2385,7 +2387,7 @@ static int service_start_limit_test(Service *s) {
int r;
log_warning_unit(UNIT(s)->id,
- "%s start request repeated too quickly, rebooting.", UNIT(s)->id);
+ "%s %s, rebooting.", UNIT(s)->id, reason);
r = manager_add_job_by_name(UNIT(s)->manager, JOB_START,
SPECIAL_REBOOT_TARGET, JOB_REPLACE,
@@ -2399,26 +2401,35 @@ static int service_start_limit_test(Service *s) {
case SERVICE_START_LIMIT_REBOOT_FORCE:
log_warning_unit(UNIT(s)->id,
- "%s start request repeated too quickly, forcibly rebooting.", UNIT(s)->id);
+ "%s %s, forcibly rebooting.", UNIT(s)->id, reason);
UNIT(s)->manager->exit_code = MANAGER_REBOOT;
break;
case SERVICE_START_LIMIT_REBOOT_IMMEDIATE:
log_warning_unit(UNIT(s)->id,
- "%s start request repeated too quickly, rebooting immediately.", UNIT(s)->id);
+ "%s %s, rebooting immediately.", UNIT(s)->id, reason);
sync();
reboot(RB_AUTOBOOT);
break;
default:
log_error_unit(UNIT(s)->id,
- "start limit action=%i", s->start_limit_action);
+ "start limit action=%i", action);
assert_not_reached("Unknown StartLimitAction.");
}
return -ECANCELED;
}
+static int service_start_limit_test(Service *s) {
+ assert(s);
+
+ if (ratelimit_test(&s->start_limit))
+ return 0;
+
+ return service_execute_action(s, s->start_limit_action, "start request repeated too quickly", true);
+}
+
static int service_start(Unit *u) {
Service *s = SERVICE(u);
int r;
diff --git a/src/core/service.h b/src/core/service.h
index 1992926..d76563d 100644
--- a/src/core/service.h
+++ b/src/core/service.h
@@ -187,6 +187,8 @@ struct Service {
char *status_text;
+ StartLimitAction failure_action;
+
RateLimit start_limit;
StartLimitAction start_limit_action;
--
1.9.1
More information about the systemd-devel
mailing list