[systemd-commits] 2 commits - man/systemd.service.xml src/core src/test

Lennart Poettering lennart at kemper.freedesktop.org
Thu Apr 24 11:15:14 PDT 2014


 man/systemd.service.xml               |   11 ++++++
 src/core/dbus-service.c               |    5 +-
 src/core/load-fragment-gperf.gperf.m4 |    3 +
 src/core/load-fragment.c              |    4 +-
 src/core/load-fragment.h              |    2 -
 src/core/service.c                    |   61 ++++++++++++++++++++--------------
 src/core/service.h                    |   24 +++++++------
 src/test/test-tables.c                |    2 -
 8 files changed, 69 insertions(+), 43 deletions(-)

New commits:
commit bf500566323bbc2240d1fdd1165a8c908faf4098
Author: Michael Olbrich <m.olbrich at pengutronix.de>
Date:   Thu Apr 24 09:35:38 2014 +0200

    service: rename StartLimitAction enum to FailureAction
    
    It's used for the FailureAction property as well.

diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
index 2f9c25a..093289f 100644
--- a/src/core/dbus-service.c
+++ b/src/core/dbus-service.c
@@ -34,7 +34,7 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, service_type, ServiceType
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, service_result, ServiceResult);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart, service_restart, ServiceRestart);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_notify_access, notify_access, NotifyAccess);
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_start_limit_action, start_limit_action, StartLimitAction);
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_failure_action, failure_action, FailureAction);
 
 const sd_bus_vtable bus_service_vtable[] = {
         SD_BUS_VTABLE_START(0),
@@ -49,9 +49,9 @@ const sd_bus_vtable bus_service_vtable[] = {
         BUS_PROPERTY_DUAL_TIMESTAMP("WatchdogTimestamp", offsetof(Service, watchdog_timestamp), 0),
         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("StartLimitAction", "s", property_get_failure_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("FailureAction", "s", property_get_failure_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 da6df5c..b8d8738 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -179,9 +179,9 @@ Service.TimeoutStopSec,          config_parse_service_timeout,       0,
 Service.WatchdogSec,             config_parse_sec,                   0,                             offsetof(Service, watchdog_usec)
 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.StartLimitAction,        config_parse_failure_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.FailureAction,           config_parse_failure_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/load-fragment.c b/src/core/load-fragment.c
index c604f90..6c92935 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -2000,7 +2000,7 @@ int config_parse_unit_condition_null(const char *unit,
 }
 
 DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier");
-DEFINE_CONFIG_PARSE_ENUM(config_parse_start_limit_action, start_limit_action, StartLimitAction, "Failed to parse start limit action specifier");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_failure_action, failure_action, FailureAction, "Failed to parse failure action specifier");
 
 int config_parse_unit_requires_mounts_for(
                 const char *unit,
@@ -3387,7 +3387,7 @@ void unit_dump_config_items(FILE *f) {
                 { config_parse_unit_slice,            "SLICE" },
                 { config_parse_documentation,         "URL" },
                 { config_parse_service_timeout,       "SECONDS" },
-                { config_parse_start_limit_action,    "ACTION" },
+                { config_parse_failure_action,        "ACTION" },
                 { config_parse_set_status,            "STATUS" },
                 { config_parse_service_sockets,       "SOCKETS" },
                 { config_parse_environ,               "ENVIRON" },
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
index 3513851..0f3c0c7 100644
--- a/src/core/load-fragment.h
+++ b/src/core/load-fragment.h
@@ -72,7 +72,7 @@ int config_parse_unit_condition_string(const char *unit, const char *filename, u
 int config_parse_unit_condition_null(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_kill_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_notify_access(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_start_limit_action(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_failure_action(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_unit_requires_mounts_for(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_syscall_filter(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_syscall_archs(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/core/service.c b/src/core/service.c
index 593237a..694a265 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1840,7 +1840,7 @@ 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 int service_execute_action(Service *s, FailureAction action, const char *reason, bool log_action_none);
 
 static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) {
         int r;
@@ -2376,22 +2376,22 @@ fail:
         service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
 }
 
-static int service_execute_action(Service *s, StartLimitAction action, const char *reason, bool log_action_none) {
+static int service_execute_action(Service *s, FailureAction action, const char *reason, bool log_action_none) {
         assert(s);
 
-        if (action == SERVICE_START_LIMIT_REBOOT ||
-            action == SERVICE_START_LIMIT_REBOOT_FORCE)
+        if (action == SERVICE_FAILURE_ACTION_REBOOT ||
+            action == SERVICE_FAILURE_ACTION_REBOOT_FORCE)
                 update_reboot_param_file(s->reboot_arg);
 
         switch (action) {
 
-        case SERVICE_START_LIMIT_NONE:
+        case SERVICE_FAILURE_ACTION_NONE:
                 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: {
+        case SERVICE_FAILURE_ACTION_REBOOT: {
                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
                 int r;
 
@@ -2408,13 +2408,13 @@ static int service_execute_action(Service *s, StartLimitAction action, const cha
                 break;
         }
 
-        case SERVICE_START_LIMIT_REBOOT_FORCE:
+        case SERVICE_FAILURE_ACTION_REBOOT_FORCE:
                 log_warning_unit(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:
+        case SERVICE_FAILURE_ACTION_REBOOT_IMMEDIATE:
                 log_warning_unit(UNIT(s)->id,
                                  "%s %s, rebooting immediately.", UNIT(s)->id, reason);
                 sync();
@@ -2430,8 +2430,8 @@ static int service_execute_action(Service *s, StartLimitAction action, const cha
 
         default:
                 log_error_unit(UNIT(s)->id,
-                               "start limit action=%i", action);
-                assert_not_reached("Unknown StartLimitAction.");
+                               "failure action=%i", action);
+                assert_not_reached("Unknown FailureAction.");
         }
 
         return -ECANCELED;
@@ -3832,13 +3832,13 @@ static const char* const service_result_table[_SERVICE_RESULT_MAX] = {
 
 DEFINE_STRING_TABLE_LOOKUP(service_result, ServiceResult);
 
-static const char* const start_limit_action_table[_SERVICE_START_LIMIT_MAX] = {
-        [SERVICE_START_LIMIT_NONE] = "none",
-        [SERVICE_START_LIMIT_REBOOT] = "reboot",
-        [SERVICE_START_LIMIT_REBOOT_FORCE] = "reboot-force",
-        [SERVICE_START_LIMIT_REBOOT_IMMEDIATE] = "reboot-immediate"
+static const char* const failure_action_table[_SERVICE_FAILURE_ACTION_MAX] = {
+        [SERVICE_FAILURE_ACTION_NONE] = "none",
+        [SERVICE_FAILURE_ACTION_REBOOT] = "reboot",
+        [SERVICE_FAILURE_ACTION_REBOOT_FORCE] = "reboot-force",
+        [SERVICE_FAILURE_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate"
 };
-DEFINE_STRING_TABLE_LOOKUP(start_limit_action, StartLimitAction);
+DEFINE_STRING_TABLE_LOOKUP(failure_action, FailureAction);
 
 const UnitVTable service_vtable = {
         .object_size = sizeof(Service),
diff --git a/src/core/service.h b/src/core/service.h
index 13b2b06..2254c3e 100644
--- a/src/core/service.h
+++ b/src/core/service.h
@@ -103,14 +103,14 @@ typedef enum ServiceResult {
         _SERVICE_RESULT_INVALID = -1
 } ServiceResult;
 
-typedef enum StartLimitAction {
-        SERVICE_START_LIMIT_NONE,
-        SERVICE_START_LIMIT_REBOOT,
-        SERVICE_START_LIMIT_REBOOT_FORCE,
-        SERVICE_START_LIMIT_REBOOT_IMMEDIATE,
-        _SERVICE_START_LIMIT_MAX,
-        _SERVICE_START_LIMIT_INVALID = -1
-} StartLimitAction;
+typedef enum FailureAction {
+        SERVICE_FAILURE_ACTION_NONE,
+        SERVICE_FAILURE_ACTION_REBOOT,
+        SERVICE_FAILURE_ACTION_REBOOT_FORCE,
+        SERVICE_FAILURE_ACTION_REBOOT_IMMEDIATE,
+        _SERVICE_FAILURE_ACTION_MAX,
+        _SERVICE_FAILURE_ACTION_INVALID = -1
+} FailureAction;
 
 struct Service {
         Unit meta;
@@ -187,10 +187,10 @@ struct Service {
 
         char *status_text;
 
-        StartLimitAction failure_action;
+        FailureAction failure_action;
 
         RateLimit start_limit;
-        StartLimitAction start_limit_action;
+        FailureAction start_limit_action;
         char *reboot_arg;
 
         UnitRef accept_socket;
@@ -225,5 +225,5 @@ NotifyAccess notify_access_from_string(const char *s) _pure_;
 const char* service_result_to_string(ServiceResult i) _const_;
 ServiceResult service_result_from_string(const char *s) _pure_;
 
-const char* start_limit_action_to_string(StartLimitAction i) _const_;
-StartLimitAction start_limit_action_from_string(const char *s) _pure_;
+const char* failure_action_to_string(FailureAction i) _const_;
+FailureAction failure_action_from_string(const char *s) _pure_;
diff --git a/src/test/test-tables.c b/src/test/test-tables.c
index dff6431..fb751d1 100644
--- a/src/test/test-tables.c
+++ b/src/test/test-tables.c
@@ -82,7 +82,7 @@ int main(int argc, char **argv) {
         test_table(socket_exec_command, SOCKET_EXEC_COMMAND);
         test_table(socket_result, SOCKET_RESULT);
         test_table(socket_state, SOCKET_STATE);
-        test_table(start_limit_action, SERVICE_START_LIMIT);
+        test_table(failure_action, SERVICE_FAILURE_ACTION);
         test_table(swap_exec_command, SWAP_EXEC_COMMAND);
         test_table(swap_result, SWAP_RESULT);
         test_table(swap_state, SWAP_STATE);

commit 93ae25e6fd62b2f87c3dd9ad3e81934eecc48057
Author: Michael Olbrich <m.olbrich at pengutronix.de>
Date:   Thu Apr 24 09:35:37 2014 +0200

    service: add FailureAction= option
    
    It has the same possible values as StartLimitAction= and is executed
    immediately if a service fails.

diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index a2a1b6b..af32ccb 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -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
diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
index 45bfecf..2f9c25a 100644
--- a/src/core/dbus-service.c
+++ b/src/core/dbus-service.c
@@ -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),
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index cb98c83..da6df5c 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -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)
diff --git a/src/core/service.c b/src/core/service.c
index 4ebce6a..593237a 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -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;
diff --git a/src/core/service.h b/src/core/service.h
index fd05e9b..13b2b06 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;
         char *reboot_arg;



More information about the systemd-commits mailing list