core: add ReloadCount to Manager and bump on successful reload

Introduce a counter that tracks how many configuration reloads have
been successfully completed by the manager. The increment lives in
manager_reload() right after the "point of no return", so failed
reload attempts that bail out earlier (e.g. during serialization)
do not bump the counter.

It is accessible as a new ReloadCount property to
org.freedesktop.systemd1.Manager (D-Bus) and ReloadCount to
io.systemd.Manager.Describe (Varlink).

Also add an integration test for ReloadCount
that verifies that the new ReloadCount property increments by one per
daemon-reload, accumulates correctly across multiple reloads, and that
D-Bus and Varlink return identical values. Also tests that the counter
reset after a reexec.

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Simon Lucido <simonlucido@meta.com>
This commit is contained in:
Simon Lucido
2026-05-03 10:23:55 +01:00
committed by Luca Boccassi
parent db28490c9f
commit d667b6b97f
8 changed files with 81 additions and 4 deletions
+1
View File
@@ -2978,6 +2978,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_PROPERTY("DefaultRestrictSUIDSGID", "b", bus_property_get_bool, offsetof(Manager, defaults.restrict_suid_sgid), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CtrlAltDelBurstAction", "s", bus_property_get_emergency_action, offsetof(Manager, cad_burst_action), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SoftRebootsCount", "u", bus_property_get_unsigned, offsetof(Manager, soft_reboots_count), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ReloadCount", "t", NULL, offsetof(Manager, reload_count), 0),
SD_BUS_PROPERTY("DefaultMemoryZSwapWriteback", "b", bus_property_get_bool, offsetof(Manager, defaults.memory_zswap_writeback), SD_BUS_VTABLE_PROPERTY_CONST),
/* deprecated cgroup v1 property */
+4
View File
@@ -3650,6 +3650,10 @@ int manager_reload(Manager *m) {
/* 💀 This is the point of no return, from here on there is no way back. 💀 */
reloading = NULL;
/* Bump before sending the Reloading signal, so any client that reads
* ReloadCount in response to that signal observes the new value. */
m->reload_count = saturate_add(m->reload_count, 1, UINT64_MAX);
bus_manager_send_reloading(m, true);
/* Start by flushing out all jobs and units, all generated units, all runtime environments, all dynamic users
+3
View File
@@ -492,6 +492,9 @@ typedef struct Manager {
unsigned soft_reboots_count;
/* The number of successfully completed configuration reloads. */
uint64_t reload_count;
/* Original ambient capabilities when we were initialized */
uint64_t saved_ambient_set;
} Manager;
+2 -1
View File
@@ -193,7 +193,8 @@ static int manager_runtime_build_json(sd_json_variant **ret, const char *name, v
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("WatchdogLastPingTimestamp", watchdog_get_last_ping_as_dual_timestamp(&watchdog_last_ping)),
SD_JSON_BUILD_PAIR_STRING("SystemState", manager_state_to_string(manager_state(m))),
SD_JSON_BUILD_PAIR_UNSIGNED("ExitCode", m->return_value),
SD_JSON_BUILD_PAIR_UNSIGNED("SoftRebootsCount", m->soft_reboots_count));
SD_JSON_BUILD_PAIR_UNSIGNED("SoftRebootsCount", m->soft_reboots_count),
SD_JSON_BUILD_PAIR_UNSIGNED("ReloadCount", m->reload_count));
}
int vl_method_describe_manager(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {