pid1: introduce new SERVICE_{DEAD|FAILED}_BEFORE_AUTO_RESTART service substates
When a service deactivates and is then automatically restarted via
Restart= we currently quickly transition through
SERVICE_DEAD/SERVICE_FAILED. Which is weird given it's not the
normal ("permanent") dead/failed state, but a transitory one we
immediately leave from again. We do this so that software that looks for
failures/successes can take notice, even if we restart as a consequence
of the deactivation.
Let's clean this up a bit: let's introduce two new states:
SERVICE_DEAD_BEFORE_AUTO_RESTART and SERVICE_FAILED_BEFORE_AUTO_RESTART
that are used for the transitory states. Both the SERVICE_DEAD and
SERVICE_DEAD_BEFORE_AUTO_RESTART will map to the high-level
UNIT_INACTIVE state though. (and similar for the respective failed
states). This means the high-level state machine won't change by this,
only the low-level one.
This clearly seperates the substates, which makes the state engine
cleaner, and allows clients to follow precisely whether we are in a
transitory dead/failed state, or a permanent one, by looking at the
service substate. Moreover it allows us to remove the 'n_keep_fd_store'
which so far we used to ensure the fdstore was not released during this
transitory dead/failed state but only during the permanent one. Since we
can now distinguish these states properly we can just use that.
This has been bugging me for a while. Let's clean this up.
Note that the unit restart logic is already nicely covered in the
testsiute, hence this adds no new tests for that.
And yes, this could be considered a compat break, but sofar we took the
liberty to make changes to the low-level state machine (i.e. SERVICE_xyz
states, sometimes called "substates") without considering this a bad
breakage – the high-level state machine (i.e. UNIT_xyz states) should
be considered API that cannot be changed.
This commit is contained in:
+23
-21
@@ -180,27 +180,29 @@ static const char* const scope_state_table[_SCOPE_STATE_MAX] = {
|
||||
DEFINE_STRING_TABLE_LOOKUP(scope_state, ScopeState);
|
||||
|
||||
static const char* const service_state_table[_SERVICE_STATE_MAX] = {
|
||||
[SERVICE_DEAD] = "dead",
|
||||
[SERVICE_CONDITION] = "condition",
|
||||
[SERVICE_START_PRE] = "start-pre",
|
||||
[SERVICE_START] = "start",
|
||||
[SERVICE_START_POST] = "start-post",
|
||||
[SERVICE_RUNNING] = "running",
|
||||
[SERVICE_EXITED] = "exited",
|
||||
[SERVICE_RELOAD] = "reload",
|
||||
[SERVICE_RELOAD_SIGNAL] = "reload-signal",
|
||||
[SERVICE_RELOAD_NOTIFY] = "reload-notify",
|
||||
[SERVICE_STOP] = "stop",
|
||||
[SERVICE_STOP_WATCHDOG] = "stop-watchdog",
|
||||
[SERVICE_STOP_SIGTERM] = "stop-sigterm",
|
||||
[SERVICE_STOP_SIGKILL] = "stop-sigkill",
|
||||
[SERVICE_STOP_POST] = "stop-post",
|
||||
[SERVICE_FINAL_WATCHDOG] = "final-watchdog",
|
||||
[SERVICE_FINAL_SIGTERM] = "final-sigterm",
|
||||
[SERVICE_FINAL_SIGKILL] = "final-sigkill",
|
||||
[SERVICE_FAILED] = "failed",
|
||||
[SERVICE_AUTO_RESTART] = "auto-restart",
|
||||
[SERVICE_CLEANING] = "cleaning",
|
||||
[SERVICE_DEAD] = "dead",
|
||||
[SERVICE_CONDITION] = "condition",
|
||||
[SERVICE_START_PRE] = "start-pre",
|
||||
[SERVICE_START] = "start",
|
||||
[SERVICE_START_POST] = "start-post",
|
||||
[SERVICE_RUNNING] = "running",
|
||||
[SERVICE_EXITED] = "exited",
|
||||
[SERVICE_RELOAD] = "reload",
|
||||
[SERVICE_RELOAD_SIGNAL] = "reload-signal",
|
||||
[SERVICE_RELOAD_NOTIFY] = "reload-notify",
|
||||
[SERVICE_STOP] = "stop",
|
||||
[SERVICE_STOP_WATCHDOG] = "stop-watchdog",
|
||||
[SERVICE_STOP_SIGTERM] = "stop-sigterm",
|
||||
[SERVICE_STOP_SIGKILL] = "stop-sigkill",
|
||||
[SERVICE_STOP_POST] = "stop-post",
|
||||
[SERVICE_FINAL_WATCHDOG] = "final-watchdog",
|
||||
[SERVICE_FINAL_SIGTERM] = "final-sigterm",
|
||||
[SERVICE_FINAL_SIGKILL] = "final-sigkill",
|
||||
[SERVICE_FAILED] = "failed",
|
||||
[SERVICE_DEAD_BEFORE_AUTO_RESTART] = "dead-before-auto-restart",
|
||||
[SERVICE_FAILED_BEFORE_AUTO_RESTART] = "failed-before-auto-restart",
|
||||
[SERVICE_AUTO_RESTART] = "auto-restart",
|
||||
[SERVICE_CLEANING] = "cleaning",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(service_state, ServiceState);
|
||||
|
||||
@@ -144,6 +144,8 @@ typedef enum ServiceState {
|
||||
SERVICE_FINAL_SIGTERM, /* In case the STOP_POST executable hangs, we shoot that down, too */
|
||||
SERVICE_FINAL_SIGKILL,
|
||||
SERVICE_FAILED,
|
||||
SERVICE_DEAD_BEFORE_AUTO_RESTART,
|
||||
SERVICE_FAILED_BEFORE_AUTO_RESTART,
|
||||
SERVICE_AUTO_RESTART,
|
||||
SERVICE_CLEANING,
|
||||
_SERVICE_STATE_MAX,
|
||||
|
||||
Reference in New Issue
Block a user