Skip to content

Commit

Permalink
Fix #382: do not clear service conditions if only paused
Browse files Browse the repository at this point in the history
Introduced back in v4.3-rc2, 82cc10b, the support for automatic
service conditions have had a weird and unintended behavior.  Any
change in state (see doc/svc-machine.png) caused Finit to clear
out *all* previously acquired service conditions.

However, when moving between RUNNING and PAUSED states, a service
should not have its conditions cleared.  The PAUSED state, seen
also by all conditions moving to FLUX, is only temporary while an
`initctl reload` is processed.  If a service has no changes to be
applied it will move back to RUNNING.

Also, we cannot clear the service conditions because other run/task
or services may depend on it and clearing them would cause Finit to
SIGTERM these processes (since they are no longer eligible to run).

This patch not only adds this pre-condition to `cond_clearn()`, it
also clarifies which state (before or after) the particular code
is interested in.

Signed-off-by: Joachim Wiberg <[email protected]>
  • Loading branch information
troglobit committed Oct 30, 2023
1 parent 19b2b2a commit 84adec4
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions src/service.c
Original file line number Diff line number Diff line change
Expand Up @@ -2203,6 +2203,7 @@ static void service_retry(svc_t *svc)
static void svc_set_state(svc_t *svc, svc_state_t new_state)
{
svc_state_t *state = (svc_state_t *)&svc->state;
const svc_state_t old_state = svc->state;

/* if PID isn't collected within SVC_TERM_TIMEOUT msec, kill it! */
if (new_state == SVC_STOPPING_STATE) {
Expand All @@ -2223,15 +2224,15 @@ static void svc_set_state(svc_t *svc, svc_state_t new_state)
snprintf(failure, sizeof(failure), "%s/%s/failure", svc_typestr(svc), svc_ident(svc, NULL, 0));

/* create success/failure condition when entering SVC_DONE_STATE. */
if (*state == SVC_DONE_STATE) {
if (new_state == SVC_DONE_STATE) {
if (svc->started && !WEXITSTATUS(svc->status))
cond_set_oneshot(success);
else
cond_set_oneshot(failure);
}

/* clear all conditions when entering SVC_HALTED_STATE. */
if (*state == SVC_HALTED_STATE) {
if (new_state == SVC_HALTED_STATE) {
cond_clear(success);
cond_clear(failure);
}
Expand All @@ -2241,9 +2242,14 @@ static void svc_set_state(svc_t *svc, svc_state_t new_state)
char cond[MAX_COND_LEN];

snprintf(cond, sizeof(cond), "service/%s/", svc_ident(svc, NULL, 0));
cond_clear(cond);

switch (svc->state) {
if ((old_state == SVC_RUNNING_STATE && new_state == SVC_PAUSED_STATE) ||
(old_state == SVC_PAUSED_STATE && new_state == SVC_RUNNING_STATE))
; /* only paused during reload, don't clear conds. */
else
cond_clear(cond);

switch (new_state) {
case SVC_HALTED_STATE:
case SVC_RUNNING_STATE:
strlcat(cond, svc_status(svc), sizeof(cond));
Expand Down

0 comments on commit 84adec4

Please sign in to comment.