Skip to content

runit: initiate shutdown on receiving SIGPWR - #39

Open
jchook wants to merge 1 commit into
void-linux:masterfrom
jchook:sigpwr
Open

runit: initiate shutdown on receiving SIGPWR#39
jchook wants to merge 1 commit into
void-linux:masterfrom
jchook:sigpwr

Conversation

@jchook

@jchook jchook commented Aug 14, 2026

Copy link
Copy Markdown

This is a port of Debian's runit patch to support SIGPWR with a couple fixes.

Container frameworks (e.g. Incus, LXC) use SIGPWR to poweroff containers. runit ignores these, so incus stop hangs until timeout, e.g.

incus launch images:voidlinux/current runit-repro
incus stop runit-repro  # hangs until timeout

The feature is opt-in so it can be rolled out incrementally or only to stock void container images. To opt-in, add +x /etc/runit/pwrfail. A one-liner that exits 0 works.

Fixes against the original Debian patch (made by Claude Fable):

  • on fork() failure the pwrfail handler retries in a loop like the existing ctrlaltdel handler, instead of falling through to wait_pid(&wstat, -1), which would reap an arbitrary child.
  • stage children unblock and uncatch SIGPWR before execve, matching the treatment of the other caught signals. Debian's patch leaves SIGPWR (SIGUSR2 on platforms without it) blocked in the inherited signal mask of every process on the system.

Original patch by Dmitry Bogatov for Debian bug #923924, shipped in Debian since 2019.

Tested by running the patched runit as PID 1 in an unprivileged PID+user namespace: SIGPWR runs pwrfail, arms stopit, and proceeds through stage 3; without pwrfail present, SIGPWR is a no-op and runit keeps running; stage-2 descendants show a clean SigBlk mask in /proc/pid/status, confirming the second fix.

Closes #2

This is a port of Debian's runit patch
0013-Shutdown-when-runit-init-receices-SIGPWR.patch by
Dmitry Bogatov <KAction@debian.org> (Debian bug #923924), shipped
in Debian since runit 2.1.2-27, adapted to this tree's const sig_*
constants and handler signatures, with two fixes over the Debian
version:

- on fork() failure the pwrfail handler retries in a loop like the
  existing ctrlaltdel handler, instead of falling through to
  wait_pid(&wstat, -1), which would reap an arbitrary child.
- stage children unblock and uncatch SIGPWR before execve, matching
  the treatment of the other caught signals; Debian's patch leaves
  SIGPWR (SIGUSR2 on platforms without it) blocked in the inherited
  signal mask of every process on the system.
@classabbyamp

Copy link
Copy Markdown
Member

PRs should generally be addressed to https://github.com/g-pape/runit, Void used this repo to document our patches when it seemed the upstream was gone, which is no longer the case.

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.

Handle SIGPWR signal (shutdown)

2 participants