diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md index ae0635bb..35c61552 100644 --- a/doc/ChangeLog.md +++ b/doc/ChangeLog.md @@ -3,6 +3,31 @@ Change Log All relevant changes are documented in this file. +[Unreleased] +------------ + +### Changes + +- Restart log now spells out the signal name and flags core dumps, + e.g. `killed by SIGKILL` or `killed by SIGSEGV, core dumped`, in + place of the bare numeric `by signal: N`. Gives operators a much + stronger breadcrumb when a daemon dies unexpectedly + +### Fixes + +- Remove stale daemon-owned (`pid:!`) pidfiles after unclean exits. + When a daemon dies via SIGKILL/OOM/segfault, or exits early during + startup, its pidfile lingers and can prevent the next instance from + starting -- `dbus-daemon` for example refuses to start when its + pidfile already exists, so Finit's restart loop gives up. Finit now + drops the file when it still names the just-reaped PID and that PID + is no longer alive (the liveness check guards against PID reuse). + This is a controlled exception to the long-standing rule that Finit + does not touch service-owned pidfiles +- Fix misspelled `SIGUNKOWN` returned by `sig_name()` for unknown + signal numbers, now spelled correctly as `SIGUNKNOWN`. Surfaced by + the new restart log above + [4.17][] - 2026-04-28 --------------------- diff --git a/doc/config/services.md b/doc/config/services.md index a315b372..a65b037c 100644 --- a/doc/config/services.md +++ b/doc/config/services.md @@ -31,6 +31,14 @@ basename of the binary to guess the PID file to watch for the PID: `/var/run/ntpd.pid`. If Finit guesses wrong, you have to submit the full `pid:!/path/to/file.pid`. +With `pid:!/path`, the file belongs to the service: Finit reads it +but does not create or remove it. The one exception is *stale* +cleanup — if the service dies without removing its own pidfile +(SIGKILL, OOM, segfault), and the file still names the just-reaped +PID, Finit removes it before the next retry. This prevents daemons +that refuse to start on an existing pidfile (e.g. `dbus-daemon`) +from getting stuck in a crash-restart loop. + **Example:** In the case of `ospfd` (below), we omit the `-d` flag (daemonize) to diff --git a/src/pid.c b/src/pid.c index 16f97b59..60994061 100644 --- a/src/pid.c +++ b/src/pid.c @@ -201,7 +201,10 @@ int pid_file_set(svc_t *svc, char *file, int not) * pid:!foo --> !/run/foo.pid * pid:!/run/foo.pid --> !/run/foo.pid * - * Note, nothing is created or removed by Finit in this latter form. + * Nothing is created or removed by Finit in this latter form, with one + * exception: a verifiably stale pidfile (still names the just-reaped + * PID, and that PID is no longer alive) is removed so the next instance + * can start. See service_clean_pidfile() in src/service.c. */ int pid_file_parse(svc_t *svc, char *arg) {