mirror of
https://github.com/clearlinux/systemd-stable.git
synced 2026-09-28 17:10:23 +00:00
service: add FailureAction= option
It has the same possible values as StartLimitAction= and is executed immediately if a service fails.
This commit is contained in:
committed by
Lennart Poettering
parent
209b031e4f
commit
93ae25e6fd
@@ -1030,6 +1030,17 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
|
||||
command.</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
|
||||
|
||||
@@ -51,6 +51,7 @@ const sd_bus_vtable bus_service_vtable[] = {
|
||||
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("RebootArgument", "s", NULL, offsetof(Service, reboot_arg), 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),
|
||||
|
||||
@@ -181,6 +181,7 @@ Service.StartLimitInterval, config_parse_sec, 0,
|
||||
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.RebootArgument, config_parse_string, 0, offsetof(Service, reboot_arg)
|
||||
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)
|
||||
|
||||
+25
-14
@@ -1840,6 +1840,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);
|
||||
@@ -1849,6 +1851,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 ||
|
||||
@@ -2371,22 +2376,19 @@ 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;
|
||||
|
||||
if (s->start_limit_action == SERVICE_START_LIMIT_REBOOT ||
|
||||
s->start_limit_action == SERVICE_START_LIMIT_REBOOT_FORCE)
|
||||
if (action == SERVICE_START_LIMIT_REBOOT ||
|
||||
action == SERVICE_START_LIMIT_REBOOT_FORCE)
|
||||
update_reboot_param_file(s->reboot_arg);
|
||||
|
||||
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: {
|
||||
@@ -2394,7 +2396,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,
|
||||
@@ -2408,13 +2410,13 @@ 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();
|
||||
if (s->reboot_arg) {
|
||||
log_info("Rebooting with argument '%s'.", s->reboot_arg);
|
||||
@@ -2428,13 +2430,22 @@ static int service_start_limit_test(Service *s) {
|
||||
|
||||
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;
|
||||
|
||||
@@ -187,6 +187,8 @@ struct Service {
|
||||
|
||||
char *status_text;
|
||||
|
||||
StartLimitAction failure_action;
|
||||
|
||||
RateLimit start_limit;
|
||||
StartLimitAction start_limit_action;
|
||||
char *reboot_arg;
|
||||
|
||||
Reference in New Issue
Block a user