Prevent main process from starting if pre: script fails

Check exit status of `pre:` scripts, on failure drive service/sysv to
`crashed` state.  The exit code of `post:` scripts remain ignored for
now.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2025-02-11 09:39:40 +01:00
1 parent 9a3148a49d
commit 23d034f521
2 files changed
+33 -3

No files matched your search

+8
View File
@@ -7,11 +7,19 @@ All relevant changes are documented in this file.
[4.9][UNRELEASED] [4.9][UNRELEASED]
-------------------- --------------------
> [!CAUTION]
> This release changes how Finit reacts to the exit status of `pre:`
> scripts. Finit will now no longer start the main process if its
> `pre:` script fails for any reason. So, if you have pre scripts that,
> e.g., create directories, make sure they are idempotent.
### Changes ### Changes
- Add individual timeout (optional) support for pre/post/ready scripts - Add individual timeout (optional) support for pre/post/ready scripts
- Add support for systems with broken RTC, i.e., those that at power-on - Add support for systems with broken RTC, i.e., those that at power-on
may reset the RTC to a random date instead of zero, issue #418 may reset the RTC to a random date instead of zero, issue #418
- Add support for detecting "in-container" when in `systemd-nspawn` - Add support for detecting "in-container" when in `systemd-nspawn`
- Check exit status of `pre:` scripts, on failure drive service/sysv to
`crashed` state. (The exit code of `post:` scripts remain ignored)
- Reset color attributes and clear screen when starting up. This is - Reset color attributes and clear screen when starting up. This is
for boot loaders like GRUB, which leave background color artifacts for boot loaders like GRUB, which leave background color artifacts
+25 -3
View File
@@ -1943,8 +1943,11 @@ void service_monitor(pid_t lost, int status)
} }
switch (svc->state) { switch (svc->state) {
case SVC_CLEANUP_STATE:
case SVC_SETUP_STATE: case SVC_SETUP_STATE:
/* If the setup phase fails, drive svc to crashed. */
svc->status = status;
/* fallthrough */
case SVC_CLEANUP_STATE:
dbg("collected script %s(%d), normal exit: %d, signaled: %d, exit code: %d", dbg("collected script %s(%d), normal exit: %d, signaled: %d, exit code: %d",
svc->state == SVC_CLEANUP_STATE ? svc->post_script : svc->pre_script, svc->state == SVC_CLEANUP_STATE ? svc->post_script : svc->pre_script,
lost, WIFEXITED(status), WIFSIGNALED(status), WEXITSTATUS(status)); lost, WIFEXITED(status), WIFSIGNALED(status), WEXITSTATUS(status));
@@ -2478,8 +2481,27 @@ restart:
break; break;
case SVC_SETUP_STATE: case SVC_SETUP_STATE:
if (!svc->pid) if (!svc->pid) {
svc_set_state(svc, SVC_STARTING_STATE); int rc = WEXITSTATUS(svc->status);
int ok = WIFEXITED(svc->status);
if (!ok || rc) {
const char *sig;
if (WIFSIGNALED(svc->status))
sig = sig_name(WTERMSIG(svc->status));
else
sig = "none";
logit(LOG_WARNING, "Service %s pre:%s failed, rc: %d sig:%s",
svc_ident(svc, NULL, 0), svc->pre_script, rc, sig);
svc_set_state(svc, SVC_STOPPING_STATE);
svc_crashing(svc);
} else {
svc_set_state(svc, SVC_STARTING_STATE);
}
}
break; break;
case SVC_WAITING_STATE: case SVC_WAITING_STATE: