From ea5071a264b41986aeae38bcad71ea9e8e8705ea Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Thu, 19 Mar 2026 06:56:45 +0100 Subject: [PATCH] package/finit: backport upstream fixes Backport fixes from upstream post v4.16 release. Mainly to fix mdns-alias crash+restart counter issue when avahi-daemon has to be restarted. Finit did not properly clear the dependency that mdns-alias had on avahi-daemon, causing it to crash and have its restart counter incremented. Signed-off-by: Joachim Wiberg --- ...-global-path-var-and-fix-memory-corr.patch | 54 +++ ...gin-names-to-prevent-subtle-macro-pr.patch | 318 ++++++++++++++++++ ...ndition-before-stopping-rdeps-on-rel.patch | 66 ++++ 3 files changed, 438 insertions(+) create mode 100644 package/finit/0001-Remove-redundant-global-path-var-and-fix-memory-corr.patch create mode 100644 package/finit/0002-Use-explicit-plugin-names-to-prevent-subtle-macro-pr.patch create mode 100644 package/finit/0003-service-clear-condition-before-stopping-rdeps-on-rel.patch diff --git a/package/finit/0001-Remove-redundant-global-path-var-and-fix-memory-corr.patch b/package/finit/0001-Remove-redundant-global-path-var-and-fix-memory-corr.patch new file mode 100644 index 00000000..e10e6655 --- /dev/null +++ b/package/finit/0001-Remove-redundant-global-path-var-and-fix-memory-corr.patch @@ -0,0 +1,54 @@ +From 184c079c08387d1b0f74de25b63c56304d2156d0 Mon Sep 17 00:00:00 2001 +From: bazub +Date: Tue, 3 Mar 2026 20:31:33 +0000 +Subject: [PATCH 1/3] Remove redundant global path var and fix memory + corruption +Organization: Wires + +Signed-off-by: Joachim Wiberg +--- + src/conf.c | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +diff --git a/src/conf.c b/src/conf.c +index d0abb61d..6e8ec834 100644 +--- a/src/conf.c ++++ b/src/conf.c +@@ -121,9 +121,6 @@ static uev_t etcw; + + static TAILQ_HEAD(, conf_change) conf_change_list = TAILQ_HEAD_INITIALIZER(conf_change_list); + +-static char *path; +-static char *shell; +- + static int parse_conf(char *file, int is_rcsd); + static void drop_changes(void); + +@@ -377,8 +374,6 @@ void conf_parse_cmdline(int argc, char *argv[]) + fstab = strdup(ptr); + finit_conf = strdup(FINIT_CONF); + finit_rcsd = strdup(FINIT_RCSD); +- path = getenv("PATH"); +- shell = getenv("SHELL"); + + for (int i = 1; i < argc; i++) + parse_arg(argv[i]); +@@ -404,13 +399,9 @@ void conf_reset_env(void) + free(node); + } + +- if (path) +- setenv("PATH", path, 1); +- else ++ if (!getenv("PATH")) + setenv("PATH", _PATH_STDPATH, 1); +- if (shell) +- setenv("SHELL", shell, 1); +- else ++ if (!getenv("SHELL")) + setenv("SHELL", _PATH_BSHELL, 1); + setenv("LOGNAME", "root", 1); + setenv("USER", "root", 1); +-- +2.43.0 + diff --git a/package/finit/0002-Use-explicit-plugin-names-to-prevent-subtle-macro-pr.patch b/package/finit/0002-Use-explicit-plugin-names-to-prevent-subtle-macro-pr.patch new file mode 100644 index 00000000..1c9bdb72 --- /dev/null +++ b/package/finit/0002-Use-explicit-plugin-names-to-prevent-subtle-macro-pr.patch @@ -0,0 +1,318 @@ +From 662293e194811213b9b387163dfe8499e3300ccf Mon Sep 17 00:00:00 2001 +From: bazub +Date: Fri, 6 Mar 2026 20:36:23 +0000 +Subject: [PATCH 2/3] Use explicit plugin names to prevent subtle macro + processing bugs +Organization: Wires + +Signed-off-by: Joachim Wiberg +--- + plugins/alsa-utils.c | 6 +++--- + plugins/bootmisc.c | 2 +- + plugins/dbus.c | 4 ++-- + plugins/hook-scripts.c | 2 +- + plugins/modprobe.c | 2 +- + plugins/modules-load.c | 2 +- + plugins/netlink.c | 2 +- + plugins/pidfile.c | 2 +- + plugins/procps.c | 4 ++-- + plugins/resolvconf.c | 2 +- + plugins/rtc.c | 6 +++--- + plugins/sys.c | 2 +- + plugins/tty.c | 1 + + plugins/urandom.c | 6 +++--- + plugins/usr.c | 2 +- + plugins/x11-common.c | 4 ++-- + 16 files changed, 25 insertions(+), 24 deletions(-) + +diff --git a/plugins/alsa-utils.c b/plugins/alsa-utils.c +index 6b2c3603..a8a967b0 100644 +--- a/plugins/alsa-utils.c ++++ b/plugins/alsa-utils.c +@@ -38,7 +38,7 @@ + static void save(void *arg) + { + if (rescue) { +- dbg("Skipping %s plugin in rescue mode.", __FILE__); ++ dbg("Skipping %s plugin in rescue mode.", "alsa-utils"); + return; + } + +@@ -51,7 +51,7 @@ static void save(void *arg) + static void restore(void *arg) + { + if (rescue) { +- dbg("Skipping %s plugin in rescue mode.", __FILE__); ++ dbg("Skipping %s plugin in rescue mode.", "alsa-utils"); + return; + } + +@@ -62,7 +62,7 @@ static void restore(void *arg) + } + + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "alsa-utils", + .hook[HOOK_BASEFS_UP] = { .cb = restore }, + .hook[HOOK_SHUTDOWN] = { .cb = save } + }; +diff --git a/plugins/bootmisc.c b/plugins/bootmisc.c +index 701f73f0..a8ba3808 100644 +--- a/plugins/bootmisc.c ++++ b/plugins/bootmisc.c +@@ -172,7 +172,7 @@ static void setup(void *arg) + } + + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "bootmisc", + .hook[HOOK_MOUNT_POST] = { .cb = clean }, + .hook[HOOK_BASEFS_UP] = { .cb = setup }, + .depends = { "pidfile" }, +diff --git a/plugins/dbus.c b/plugins/dbus.c +index bbf55bc2..a8a155a1 100644 +--- a/plugins/dbus.c ++++ b/plugins/dbus.c +@@ -106,7 +106,7 @@ static void setup(void *arg) + char *cmd; + + if (rescue) { +- dbg("Skipping %s plugin in rescue mode.", __FILE__); ++ dbg("Skipping %s plugin in rescue mode.", "dbus"); + return; + } + +@@ -164,7 +164,7 @@ static void setup(void *arg) + } + + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "dbus", + .hook[HOOK_SVC_PLUGIN] = { .cb = setup }, + }; + +diff --git a/plugins/hook-scripts.c b/plugins/hook-scripts.c +index 9aa78173..e75808c5 100644 +--- a/plugins/hook-scripts.c ++++ b/plugins/hook-scripts.c +@@ -79,7 +79,7 @@ static void hscript_shutdown(void *arg) + } + + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "hook-scripts", + .hook[HOOK_BANNER] = { .cb = hscript_banner }, + .hook[HOOK_ROOTFS_UP] = { .cb = hscript_rootfs_up }, + .hook[HOOK_MOUNT_ERROR] = { .cb = hscript_mount_error }, +diff --git a/plugins/modprobe.c b/plugins/modprobe.c +index b6b7e7bb..e52bf228 100644 +--- a/plugins/modprobe.c ++++ b/plugins/modprobe.c +@@ -228,7 +228,7 @@ static void coldplug(void *arg) + } + + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "modprobe", + .hook[HOOK_BASEFS_UP] = { .cb = coldplug }, + .depends = { "bootmisc", } + }; +diff --git a/plugins/modules-load.c b/plugins/modules-load.c +index 53aef82f..e2e45c72 100644 +--- a/plugins/modules-load.c ++++ b/plugins/modules-load.c +@@ -213,7 +213,7 @@ static void load(void *arg) + } + + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "modules-load", + .hook[HOOK_SVC_PLUGIN] = { .cb = load }, + }; + +diff --git a/plugins/netlink.c b/plugins/netlink.c +index a70b01e8..625cbd1b 100644 +--- a/plugins/netlink.c ++++ b/plugins/netlink.c +@@ -426,7 +426,7 @@ static void nl_enumerate(void *arg) + } + + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "netlink", + .hook[HOOK_SVC_RECONF] = { .cb = nl_reconf }, + .hook[HOOK_SVC_PLUGIN] = { .cb = nl_enumerate }, + .io = { +diff --git a/plugins/pidfile.c b/plugins/pidfile.c +index ae0fdeea..f1232ab6 100644 +--- a/plugins/pidfile.c ++++ b/plugins/pidfile.c +@@ -335,7 +335,7 @@ static void pidfile_init(void *arg) + * SIGSTP:ed (in state PAUSED) waiting for . + */ + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "pidfile", + .hook[HOOK_BASEFS_UP] = { .cb = pidfile_init }, + .hook[HOOK_SVC_RECONF] = { .cb = pidfile_reconf }, + .depends = { "netlink" }, /* bootmisc depends on us */ +diff --git a/plugins/procps.c b/plugins/procps.c +index 826e38ad..5a178d75 100644 +--- a/plugins/procps.c ++++ b/plugins/procps.c +@@ -43,7 +43,7 @@ static void setup(void *arg) + glob_t gl; + + if (rescue) { +- dbg("Skipping %s plugin in rescue mode.", __FILE__); ++ dbg("Skipping %s plugin in rescue mode.", "procps"); + return; + } + +@@ -69,7 +69,7 @@ static void setup(void *arg) + } + + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "procps", + .hook[HOOK_BASEFS_UP] = { + .cb = setup + }, +diff --git a/plugins/resolvconf.c b/plugins/resolvconf.c +index 1ac29dae..b98e9214 100644 +--- a/plugins/resolvconf.c ++++ b/plugins/resolvconf.c +@@ -51,7 +51,7 @@ static void setup(void *arg) + } + + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "resolvconf", + .hook[HOOK_BASEFS_UP] = { + .cb = setup + }, +diff --git a/plugins/rtc.c b/plugins/rtc.c +index faf69415..cf734763 100644 +--- a/plugins/rtc.c ++++ b/plugins/rtc.c +@@ -236,7 +236,7 @@ static void rtc_save(void *arg) + int fd, rc = 0; + + if (rescue) { +- dbg("Skipping %s plugin in rescue mode.", __FILE__); ++ dbg("Skipping %s plugin in rescue mode.", "rtc"); + return; + } + +@@ -266,7 +266,7 @@ static void rtc_restore(void *arg) + int fd, rc = 0; + + if (rescue) { +- dbg("Skipping %s plugin in rescue mode.", __FILE__); ++ dbg("Skipping %s plugin in rescue mode.", "rtc"); + return; + } + +@@ -321,7 +321,7 @@ static void update(uev_t *w, void *arg, int events) + + + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "rtc", + .hook[HOOK_BASEFS_UP] = { + .cb = rtc_restore + }, +diff --git a/plugins/sys.c b/plugins/sys.c +index 438fdfd5..484adc05 100644 +--- a/plugins/sys.c ++++ b/plugins/sys.c +@@ -180,7 +180,7 @@ static void sys_init(void *arg) + } + + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "sys", + .hook[HOOK_BASEFS_UP] = { .cb = sys_init }, + .depends = { "bootmisc", }, + }; +diff --git a/plugins/tty.c b/plugins/tty.c +index b3255f9f..c6a750b0 100644 +--- a/plugins/tty.c ++++ b/plugins/tty.c +@@ -43,6 +43,7 @@ + static void tty_watcher(void *arg, int fd, int events); + + static plugin_t plugin = { ++ .name = "tty", + .io = { + .cb = tty_watcher, + .flags = PLUGIN_IO_READ, +diff --git a/plugins/urandom.c b/plugins/urandom.c +index 410d0660..9bb6252b 100644 +--- a/plugins/urandom.c ++++ b/plugins/urandom.c +@@ -87,7 +87,7 @@ static void setup(void *arg) + int fd, err; + + if (rescue) { +- dbg("Skipping %s plugin in rescue mode.", __FILE__); ++ dbg("Skipping %s plugin in rescue mode.", "urandom"); + return; + } + +@@ -188,7 +188,7 @@ static void save(void *arg) + mode_t prev; + + if (rescue) { +- dbg("Skipping %s plugin in rescue mode.", __FILE__); ++ dbg("Skipping %s plugin in rescue mode.", "urandom"); + return; + } + +@@ -202,7 +202,7 @@ static void save(void *arg) + } + + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "urandom", + .hook[HOOK_BASEFS_UP] = { .cb = setup }, + .hook[HOOK_SHUTDOWN] = { .cb = save }, + .depends = { "bootmisc", } +diff --git a/plugins/usr.c b/plugins/usr.c +index d30d9440..496facc2 100644 +--- a/plugins/usr.c ++++ b/plugins/usr.c +@@ -104,7 +104,7 @@ static void usr_init(void *arg) + } + + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "usr", + .hook[HOOK_BASEFS_UP] = { .cb = usr_init }, + .depends = { "bootmisc", }, + }; +diff --git a/plugins/x11-common.c b/plugins/x11-common.c +index f65331a0..75825a36 100644 +--- a/plugins/x11-common.c ++++ b/plugins/x11-common.c +@@ -39,7 +39,7 @@ + static void setup(void *arg) + { + if (rescue) { +- dbg("Skipping %s plugin in rescue mode.", __FILE__); ++ dbg("Skipping %s plugin in rescue mode.", "x11-common"); + return; + } + +@@ -48,7 +48,7 @@ static void setup(void *arg) + } + + static plugin_t plugin = { +- .name = __FILE__, ++ .name = "x11-common", + .hook[HOOK_SVC_PLUGIN] = { .cb = setup }, + }; + +-- +2.43.0 + diff --git a/package/finit/0003-service-clear-condition-before-stopping-rdeps-on-rel.patch b/package/finit/0003-service-clear-condition-before-stopping-rdeps-on-rel.patch new file mode 100644 index 00000000..0925b673 --- /dev/null +++ b/package/finit/0003-service-clear-condition-before-stopping-rdeps-on-rel.patch @@ -0,0 +1,66 @@ +From c01faef99b7e4ff9c39f29ad5648db61a4742539 Mon Sep 17 00:00:00 2001 +From: Joachim Wiberg +Date: Thu, 19 Mar 2026 06:37:50 +0100 +Subject: [PATCH 3/3] service: clear condition before stopping rdeps on reload +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Organization: Wires + +When a service without SIGHUP reload support (noreload) is touched and +'initctl reload' is called, service_update_rdeps() correctly identifies +its reverse dependencies but only marks them dirty. It does not clear +the service's condition, so when service_step_all() runs: + + - rdeps supporting SIGHUP hit the sm_in_reload() guard and break early, + left running while their dependency is being killed. + - rdeps without SIGHUP support may receive SIGTERM too late, after the + dependency has already died and broken their connection, causing them + to exit from RUNNING state and have their restart counter incremented. + +Fix by calling cond_clear() on the service's condition immediately in +service_update_rdeps(), before service_step_all() runs. cond_clear() +calls cond_update() which calls service_step() inline on all affected +services, which see COND_OFF and transition to STOPPING_STATE — all +before SIGTERM is ever sent to the dependency itself. + +This mirrors the pattern already used in api.c:do_reload() for direct +'initctl reload ' calls. + +Fixes: avahi/mdns stop causing mdns-alias restart counter increment + +Signed-off-by: Joachim Wiberg +--- + src/service.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/src/service.c b/src/service.c +index b2c6c15b..016b5d2f 100644 +--- a/src/service.c ++++ b/src/service.c +@@ -2418,7 +2418,21 @@ void service_update_rdeps(void) + if (!svc_is_noreload(svc)) + continue; /* Yup, no need to stop start rdeps */ + +- svc_mark_affected(mkcond(svc, cond, sizeof(cond))); ++ /* ++ * Clear the condition immediately, before service_step_all() ++ * runs. cond_clear() calls cond_update() which calls ++ * service_step() on all affected services right now. Those ++ * services see COND_OFF and get service_stop() called, ++ * transitioning to STOPPING_STATE before we ever send SIGTERM ++ * to this service. Without this, the condition is only cleared ++ * after the service dies, by which time reverse-dependencies ++ * may have already crashed due to the lost connection. ++ * See also: api.c do_reload() which does the same for direct ++ * 'initctl reload ' calls. ++ */ ++ mkcond(svc, cond, sizeof(cond)); ++ cond_clear(cond); ++ svc_mark_affected(cond); + } + } + +-- +2.43.0 +