switch-to-configuration-ng: add timeout to systemd daemon reload/reexecute

Just like `systemctl daemon-reload`/`systemctl daemon-reexec`, we ensure
we don't wait forever for the reload action to finish.
This commit is contained in:
Jared Baur
2026-01-08 10:23:15 -08:00
parent de220b0a65
commit 039a1bee5f
@@ -87,6 +87,12 @@ const DRY_RELOAD_BY_ACTIVATION_LIST_FILE: &str = "/run/nixos/dry-activation-relo
// Reuse the same default timeout that systemd uses. See https://github.com/systemd/systemd/blob/8b4278d12ec55cc3f96764bc8197e1055fbb6d3f/src/libsystemd/sd-bus/bus-internal.h#L312
const BUS_TIMEOUT: Duration = Duration::from_secs(25);
// Reuse the same daemon reload/reexecute timeout that systemd uses. See https://github.com/systemd/systemd/blob/5366dbdbd44ba4dc0c914dd4daa1a5297e0b2bde/src/basic/constants.h#L18
const DAEMON_RELOAD_TIMEOUT: Duration = Duration::from_secs(180);
// Used during times of waiting for D-Bus to process messages.
const DBUS_PROCESS_TIME: Duration = Duration::from_millis(500);
#[derive(Debug, Clone, PartialEq)]
enum Action {
Switch,
@@ -932,7 +938,7 @@ fn block_on_jobs(
"waiting for submitted jobs to finish, still have {} job(s)",
submitted_jobs.borrow().len()
);
_ = conn.process(Duration::from_millis(500));
_ = conn.process(DBUS_PROCESS_TIME);
}
}
@@ -987,7 +993,7 @@ fn do_user_switch(parent_exe: String) -> anyhow::Result<()> {
log::debug!("waiting for nixos activation to finish");
while !*nixos_activation_done.borrow() {
_ = dbus_conn
.process(Duration::from_secs(500))
.process(DBUS_PROCESS_TIME)
.context("Failed to process dbus messages")?;
}
@@ -1695,10 +1701,18 @@ won't take effect until you reboot the system.
log::debug!("waiting for systemd restart to finish");
let mut reexec_time_waited = Duration::from_secs(0);
while *systemd_is_reloading.borrow() {
_ = dbus_conn
.process(Duration::from_millis(500))
.process(DBUS_PROCESS_TIME)
.context("Failed to process dbus messages")?;
reexec_time_waited += DBUS_PROCESS_TIME;
if reexec_time_waited >= DAEMON_RELOAD_TIMEOUT {
anyhow::bail!(
"systemd daemon reexecute failed, timeout after {:?}",
DAEMON_RELOAD_TIMEOUT
);
}
}
}
@@ -1712,10 +1726,18 @@ won't take effect until you reboot the system.
_ = systemd.reload(); // we don't get a dbus reply here
log::debug!("waiting for systemd reload to finish");
let mut reload_time_waited = Duration::from_secs(0);
while *systemd_is_reloading.borrow() {
_ = dbus_conn
.process(Duration::from_millis(500))
.process(DBUS_PROCESS_TIME)
.context("Failed to process dbus messages")?;
reload_time_waited += DBUS_PROCESS_TIME;
if reload_time_waited >= DAEMON_RELOAD_TIMEOUT {
anyhow::bail!(
"systemd daemon reload failed, timeout after {:?}",
DAEMON_RELOAD_TIMEOUT
);
}
}
dbus_conn