From 7090321ff3c812644507d43e1ddea25de8cff93a Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 10 Feb 2026 15:58:46 +0100 Subject: [PATCH 1/5] Don't hide cursor when shutting down Users starting Finit based systems using U-Boot or Barebox may otherwise not get a visible cursor at their prompt. Signed-off-by: Joachim Wiberg --- src/sm.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sm.c b/src/sm.c index a1e982b2..f23fa65a 100644 --- a/src/sm.c +++ b/src/sm.c @@ -361,9 +361,6 @@ void sm_step(void) /* Restore terse mode and run hooks before shutdown */ if (runlevel == 0 || runlevel == 6) { - /* Hide cursor, we're going down ... */ - dprint(STDOUT_FILENO, "\033[?25l", 6); - api_exit(); log_exit(); plugin_run_hooks(HOOK_SHUTDOWN); From f0914f6d32b9cd055a888cf0a1c7e45dec871824 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 10 Feb 2026 15:59:49 +0100 Subject: [PATCH 2/5] Fix 'initctl reload NAME' not updating conditions for dependents When reloading a specific service with 'initctl reload foo', the pid/foo and service/foo/ready conditions were never cleared, so dependent services were not notified of the reload. Clear the service's pid condition and, for pid/none notify types, the ready condition before reloading. The conditions are then reasserted by the pidfile inotify handler when the service touches its PID file after processing SIGHUP. For s6/systemd services the ready condition is left intact since their readiness notification may not re-trigger on SIGHUP. Signed-off-by: Joachim Wiberg --- src/api.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/api.c b/src/api.c index 381c2197..85373350 100644 --- a/src/api.c +++ b/src/api.c @@ -112,6 +112,8 @@ static int restart(svc_t *svc, void *user_data) static int reload(svc_t *svc, void *user_data) { + char cond[MAX_COND_LEN]; + (void)user_data; if (!svc) @@ -122,6 +124,20 @@ static int reload(svc_t *svc, void *user_data) else service_timeout_cancel(svc); + /* + * Clear conditions before reload to ensure dependent services + * are properly updated. The conditions are reasserted when + * the service touches its PID file after processing SIGHUP. + * + * Note: only clear 'ready' for services where the pidfile + * inotify handler reasserts it (pid/none). For s6/systemd + * services readiness relies on their respective notification + * mechanism which may not re-trigger on SIGHUP. + */ + cond_clear(mkcond(svc, cond, sizeof(cond))); + if (svc->notify == SVC_NOTIFY_PID || svc->notify == SVC_NOTIFY_NONE) + service_ready(svc, 0); + svc_mark_dirty(svc); service_step(svc); From 0b182c063e36d893ded44ac8b1f8bb41d17b4e20 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 10 Feb 2026 16:00:57 +0100 Subject: [PATCH 3/5] test: Extend depserv test with per-service reload, fix slay race Verify that 'initctl reload foo' properly triggers dependent services by checking that bar gets a new PID after the reload. Also change the second test case from service/foo/running to service/foo/ready which is the actual condition set by pidfile.so. Fix a race in slay where the target process could exit between the PID lookup and kill -9, causing spurious test failures in tight kill loops (e.g., start-kill-service.sh). Signed-off-by: Joachim Wiberg --- test/depserv.sh | 13 +++++++++++-- test/skel/bin/slay | 2 +- test/src/serv.c | 6 ++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/test/depserv.sh b/test/depserv.sh index 2f5c7a3c..9c0ebb73 100755 --- a/test/depserv.sh +++ b/test/depserv.sh @@ -5,6 +5,7 @@ # - bar must not start until foo is ready # - bar must be stopped when foo goes down # - bar must be restarted when foo is restarted +# - bar must be restarted when foo is reloaded (per-service reload) # # Regression test bug #314, that bar is not in a restart loop when foo # is stopped. Also, verify that changing between runlevels, where foo @@ -49,6 +50,13 @@ test_one() run "initctl status" assert "bar is restarted" "$(texec initctl |grep bar | awk '{print $1;}')" != "$pid" + say "Verify bar is restarted when foo is reloaded (per-service) ..." + retry 'assert_status "bar" "running"' 5 1 + pid=$(texec initctl |grep bar | awk '{print $1;}') + run "initctl reload foo" + retry 'assert_status "bar" "running"' 5 1 + assert "bar is restarted on reload" "$(texec initctl |grep bar | awk '{print $1;}')" != "$pid" + # Wait for spice to be stolen by the Harkonnen sleep 3 # bar should now have detected the loss of spice and be in restart @@ -61,8 +69,9 @@ test_one() assert_status "bar" "waiting" } +run "initctl debug" sep test_one "pid/foo" sep -run "initctl debug" -test_one "service/foo/running" +#run "initctl debug" +test_one "service/foo/ready" diff --git a/test/skel/bin/slay b/test/skel/bin/slay index 314ba1f3..d1c04efc 100755 --- a/test/skel/bin/slay +++ b/test/skel/bin/slay @@ -52,4 +52,4 @@ done echo "$pid" > /tmp/oldpid #echo "PID $pid, kill -9 ..." -kill -9 "$pid" +kill -9 "$pid" 2>/dev/null || true diff --git a/test/src/serv.c b/test/src/serv.c index dd9567e2..8129efb1 100644 --- a/test/src/serv.c +++ b/test/src/serv.c @@ -325,6 +325,12 @@ int main(int argc, char *argv[]) #endif } } + + if (melange) { + mine(melange); + vanish = -2; + } + if (do_pidfile > 0) pidfile(NULL); reloading = 0; From 0de9cfb02005d9cb6d81515bed684dfa46a4e515 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 10 Feb 2026 16:01:47 +0100 Subject: [PATCH 4/5] doc: Note per-service reload behavior for conditions Signed-off-by: Joachim Wiberg --- doc/conditions.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/conditions.md b/doc/conditions.md index a08a1cb7..93df4169 100644 --- a/doc/conditions.md +++ b/doc/conditions.md @@ -194,6 +194,10 @@ When Finit configuration files are changed and the `initctl reload` command is called, it is expected of services to touch their PID files for Finit to reassert their conditions. +Similarly, when a single service is reloaded with `initctl reload NAME`, +its conditions are cleared and reasserted, ensuring dependent services +are properly updated. + Daemons that don't create PID files, or fail to touch them on reload, can be worked around by using the `pid:/path/to/file.pid` syntax in the service stanza for the daemon. It is far from optimal since any From 60478106ebd34281be5b2221d5309e2d75bcb715 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 10 Feb 2026 16:01:53 +0100 Subject: [PATCH 5/5] Update ChangeLog with latest changes and features Signed-off-by: Joachim Wiberg --- doc/ChangeLog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md index c78b73bb..4057ff1f 100644 --- a/doc/ChangeLog.md +++ b/doc/ChangeLog.md @@ -14,6 +14,10 @@ All relevant changes are documented in this file. - Set USER and LOGNAME environment variables when dropping privileges. Fixes issues with software like rootless Podman that determines user identity from environment variables, by Aaron Andersen +- Add `remain:yes` option for run/task oneshot commands, similar to the + systemd `RemainAfterExit=yes`, by Aaron Andersen +- Clear service conditions on `initctl reload NAME` to ensure dependent + services are properly updated ### Fixes - Fix #464: invalid user:group examples in cgroups.md