diff --git a/doc/dbus.md b/doc/dbus.md index 625609b4..99907605 100644 --- a/doc/dbus.md +++ b/doc/dbus.md @@ -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`, diff --git a/src/dbus.c b/src/dbus.c index 827e05c9..3e32a253 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -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" diff --git a/src/private.h b/src/private.h index ae501161..2530c354 100644 --- a/src/private.h +++ b/src/private.h @@ -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); diff --git a/src/sm.c b/src/sm.c index 4776b648..4bfcc3e2 100644 --- a/src/sm.c +++ b/src/sm.c @@ -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; } diff --git a/test/dbus-device.sh b/test/dbus-device.sh index 2342dee3..9c042b93 100755 --- a/test/dbus-device.sh +++ b/test/dbus-device.sh @@ -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