Compare commits

...
5 Commits
Author SHA1 Message Date
Joachim Wiberg c01faef99b service: clear condition before stopping rdeps on reload
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 <svc>' calls.

Fixes: avahi/mdns stop causing mdns-alias restart counter increment

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-19 06:37:50 +01:00
Joachim Wiberg 4867b7268b Merge pull request #482 from vazub/plugfix
Use explicit plugin names to prevent subtle macro processing bugs
2026-03-16 07:31:34 +01:00
bazub 662293e194 Use explicit plugin names to prevent subtle macro processing bugs 2026-03-06 20:36:23 +00:00
Joachim Wiberg 4ce810cc1f Merge pull request #481 from vazub/pathfix
Remove redundant global path var and fix memory corruption
2026-03-04 15:05:36 +01:00
bazub 184c079c08 Remove redundant global path var and fix memory corruption 2026-03-03 20:31:33 +00:00
18 changed files with 42 additions and 36 deletions
+3 -3
View File
@@ -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 }
};
+1 -1
View File
@@ -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" },
+2 -2
View File
@@ -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 },
};
+1 -1
View File
@@ -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 },
+1 -1
View File
@@ -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", }
};
+1 -1
View File
@@ -213,7 +213,7 @@ static void load(void *arg)
}
static plugin_t plugin = {
.name = __FILE__,
.name = "modules-load",
.hook[HOOK_SVC_PLUGIN] = { .cb = load },
};
+1 -1
View File
@@ -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 = {
+1 -1
View File
@@ -335,7 +335,7 @@ static void pidfile_init(void *arg)
* SIGSTP:ed (in state PAUSED) waiting for <net/iface/lo>.
*/
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 */
+2 -2
View File
@@ -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
},
+1 -1
View File
@@ -51,7 +51,7 @@ static void setup(void *arg)
}
static plugin_t plugin = {
.name = __FILE__,
.name = "resolvconf",
.hook[HOOK_BASEFS_UP] = {
.cb = setup
},
+3 -3
View File
@@ -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
},
+1 -1
View File
@@ -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", },
};
+1
View File
@@ -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,
+3 -3
View File
@@ -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", }
+1 -1
View File
@@ -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", },
};
+2 -2
View File
@@ -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 -11
View File
@@ -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);
+15 -1
View File
@@ -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 <svc>' calls.
*/
mkcond(svc, cond, sizeof(cond));
cond_clear(cond);
svc_mark_affected(cond);
}
}