Skip to content

Reboot: reboot a Linux machine that holds a block inhibitor lock - #31

Merged
mastacontrola merged 1 commit into
mainfrom
fix/linux-reboot-inhibitor
Oct 14, 2026
Merged

mastacontrola merged 1 commit into
mainfrom
fix/linux-reboot-inhibitor

Conversation

@mastacontrola

Copy link
Copy Markdown
Member

Fixes #30.

Problem. A systemd block inhibitor lock makes logind refuse the agent's reboot ("Operation denied due to active block inhibitor", or "Access denied" on some systemd versions). The coordinator retries each poll, so the machine never reboots and the task never runs.

Cause. Both paths go through logind: shutdown +N for a delayed reboot, systemctl reboot for an immediate one. logind enforces the lock. Root cannot skip it there: systemctl -i turns into a polkit check that needs an interactive answer.

Fix. When logind refuses, start reboot.target (or poweroff.target) through PID 1 with --job-mode=replace-irreversibly. This is what logind does once it agrees, so the shutdown is orderly. A delayed action runs as a transient timer fog-agent-reboot.timer, and wall sends the warning. A second poll during the countdown reads as already in progress. With no lock held, the behavior is unchanged. This matches Windows, which already uses shutdown.exe /f.

Verified on the Debian 13 lab VM (systemd 257), with systemd-inhibit --what=shutdown --mode=block held by root:

build delayed (30s) immediate
main Failed to schedule shutdown: Access denied Call to Reboot failed: Access denied
this branch rebooted at the timer (boot ID changed) rebooted (boot ID changed)

Not verified on Fedora/Rocky with the reporter's exact message. The fallback triggers on any refusal, so it does not depend on the message text.

🤖 Generated with Claude Code

A systemd block inhibitor lock made logind refuse the reboot. The
coordinator put the reasons back and asked again each poll, so a lock
nobody released held the machine, and any task waiting on it, forever.

Root cannot skip the lock through logind: `systemctl -i` becomes a polkit
question that needs an interactive answer. So when logind refuses, the
agent starts reboot.target (or poweroff.target) through PID 1, which is
what logind does once it agrees. A delayed action runs as a transient
timer, fog-agent-reboot.timer, and wall sends the warning. The normal
path is unchanged when no lock is held. Windows already overrides with
shutdown.exe /f.

Verified on the Debian 13 lab VM (systemd 257) with a block lock held:
the old build fails both paths, the new build reboots on both.

Fixes #30

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mastacontrola
mastacontrola merged commit 76b5b29 into main Oct 14, 2026
2 checks passed
@mastacontrola
mastacontrola deleted the fix/linux-reboot-inhibitor branch October 14, 2026 20:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fog-agent unable to reboot a Linux computer due to active block inhibitor

1 participant