dbus: notify externals when reconfiguration completes

initctl reload freezes conditions to the old generation and each
owner re-asserts.  Finit's own providers do this in-process; an
external provider whose conditions are generation files, rather than
the oneshot symlinks keventd uses, has no way to know the moment.
Emit Manager1.ConfigReloaded when reconfiguration completes.

keventd needs no subscriber: its conditions are symlinks to the
reconf marker itself, so they read the current generation by
construction and never flux, which the device bus test now pins
down.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2026-08-16 22:03:44 +02:00
parent 230c65a080
commit 558c0f8c3b
5 changed files with 23 additions and 1 deletions
+1 -1
View File
@@ -137,7 +137,7 @@ All read-only strings; observable via `Properties.Get` and
|-----------------------|----------------------------------------|------------------------|
| `ServiceStateChanged` | `sss` — identity, old state, new state | Service transitions |
| `RunlevelChanged` | `ss` — old level, new level | System runlevel change |
| `ConfigReloaded` | — | `initctl reload` completed; external condition providers re-assert |
| `ConfigReloaded` | — | `initctl reload` completed; providers of generation-file conditions re-assert |
State names emitted by `ServiceStateChanged` are stable wire strings:
`halted`, `done`, `dead`, `cleanup`, `teardown`, `stopping`, `setup`,
+13
View File
@@ -626,6 +626,7 @@ static const link_method_t manager_methods[] = {
static const link_signal_t manager_signals[] = {
{ .name = "ServiceStateChanged", .sig = "sss" },
{ .name = "RunlevelChanged", .sig = "ss" },
{ .name = "ConfigReloaded", .sig = "" },
{ NULL, NULL }
};
@@ -1042,6 +1043,18 @@ void dbus_notify_runlevel_change(int old_level, int new_level)
"RunlevelChanged", "ss", body, (size_t)blen);
}
/*
* Reconfiguration complete: all conditions have been re-asserted by
* their in-Finit owners. External providers whose conditions are
* generation files, rather than the oneshot symlinks keventd uses,
* subscribe to this to re-assert theirs.
*/
void dbus_notify_reload(void)
{
dbus_emit_signal("/org/finit/manager", "org.finit.Manager1",
"ConfigReloaded", "", NULL, 0);
}
/* ---------- org.finit.Cond1 ---------- */
#define COND_PATH_OBJECT "/org/finit/cond"
+1
View File
@@ -54,6 +54,7 @@ void dbus_unregister_service (svc_t *svc);
void dbus_notify_service_state (svc_t *svc, int old_state, int new_state);
void dbus_notify_condition_change(const char *name, const char *state);
void dbus_notify_runlevel_change(int old_level, int new_level);
void dbus_notify_reload (void);
#endif
void conf_flush_events(void);
+3
View File
@@ -633,6 +633,9 @@ restart:
service_step_all(SVC_TYPE_ANY);
dbg("Reconfiguration done");
#ifdef HAVE_DBUS
dbus_notify_reload();
#endif
sm.state = SM_RUNNING_STATE;
break;
}
+5
View File
@@ -133,3 +133,8 @@ case "$(cat /tmp/dbus-devauthz.out)" in
*AccessDenied*) assert "Device1 authz fires" 0 -eq 0 ;;
*) fail "Unexpected reply: $(cat /tmp/dbus-devauthz.out)" ;;
esac
say "Conditions are generation symlinks, unaffected by initctl reload"
run "initctl reload"
retry 'assert_cond "class/net/dummy0"'
assert "class/net/dummy0 still asserted after reload" 0 -eq 0