From 81c4e4f507cd97ed96b8b2a933114bbe4ba53f51 Mon Sep 17 00:00:00 2001 From: Roman Kivalin Date: Sat, 18 Apr 2026 14:57:38 +0200 Subject: [PATCH] Skip systemd reload/restart hooks for inactive units Query the unit's ActiveState via D-Bus before calling reload or restart. If the unit is not active, log and skip rather than starting a stopped service. Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 2 ++ debian/changelog | 2 +- src/hooks.rs | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5151c26..932d8e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Features +- Systemd reload/restart hooks skip units that are not active, avoiding unintended service starts + ### Fixes ### Changes diff --git a/debian/changelog b/debian/changelog index 46f7dc0..bb39b85 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,6 @@ certforge (0.10.0-1) unstable; urgency=low - * No changes + * Systemd hooks skip units that are not active -- Roman Kivalin Fri, 18 Apr 2026 00:00:00 +0000 diff --git a/src/hooks.rs b/src/hooks.rs index 14c7945..921df49 100644 --- a/src/hooks.rs +++ b/src/hooks.rs @@ -72,6 +72,42 @@ async fn systemd_unit_action(unit: &str, action: &str) -> Result<()> { message: format!("failed to create proxy: {e}"), })?; + // Check if the unit is active before acting — don't start a stopped service + let unit_path: zbus::zvariant::OwnedObjectPath = proxy + .call("GetUnit", &(unit,)) + .await + .map_err(|e| Error::Hook { + hook: format!("systemd-{action}({unit})"), + message: format!("GetUnit failed: {e}"), + })?; + + let unit_proxy: zbus::Proxy<'_> = zbus::proxy::Builder::new(&connection) + .interface("org.freedesktop.systemd1.Unit") + .expect("valid interface") + .path(unit_path) + .expect("valid path") + .destination("org.freedesktop.systemd1") + .expect("valid destination") + .build() + .await + .map_err(|e| Error::Hook { + hook: format!("systemd-{action}({unit})"), + message: format!("failed to create unit proxy: {e}"), + })?; + + let active_state: String = unit_proxy + .get_property("ActiveState") + .await + .map_err(|e| Error::Hook { + hook: format!("systemd-{action}({unit})"), + message: format!("failed to get ActiveState: {e}"), + })?; + + if active_state != "active" { + tracing::info!(%unit, %active_state, "skipping {action}: unit is not active"); + return Ok(()); + } + let method = match action { "reload" => "ReloadUnit", "restart" => "RestartUnit",