fix(reticulum-daemon): die with parent to stop RNode-jamming pile-ups
The daemon ships as a PyInstaller one-file binary; its direct parent is the bootloader, which the Rust supervisor (mesh/reticulum.rs Drop) stops via start_kill() == SIGKILL. SIGKILL can't be forwarded, so the Python child was orphaned on every link recreation and kept holding the RNode serial port. These stale daemons piled up (9 seen on one node), all clutching /dev/ttyUSB0 and garbling the RNode so it silently stopped transmitting (txb frozen, interface status False). Set PR_SET_PDEATHSIG(SIGTERM) at daemon startup so the kernel signals us when the parent exits; our existing SIGTERM handler then shuts down cleanly and frees the port. Linux-only, best-effort, no-op elsewhere. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
81444ab4a8
commit
469b0203b7
@ -502,7 +502,32 @@ def _parse_args(argv):
|
||||
return p.parse_args(argv)
|
||||
|
||||
|
||||
def _install_parent_death_signal() -> None:
|
||||
"""Die when our parent process does.
|
||||
|
||||
The daemon ships as a PyInstaller one-file binary: our direct parent is the
|
||||
bootloader, and the Rust supervisor (mesh/reticulum.rs) stops us by SIGKILL-
|
||||
ing that bootloader. SIGKILL can't be forwarded, so without this the Python
|
||||
child is orphaned and keeps holding the RNode serial port — which piles up
|
||||
stale daemons that jam the radio (observed: 9 instances on one node). Asking
|
||||
the kernel to send us SIGTERM on parent death lets our existing SIGTERM
|
||||
handler shut down cleanly and free the port. Linux-only; no-op elsewhere.
|
||||
"""
|
||||
if sys.platform != "linux":
|
||||
return
|
||||
try:
|
||||
import ctypes
|
||||
|
||||
PR_SET_PDEATHSIG = 1
|
||||
ctypes.CDLL("libc.so.6", use_errno=True).prctl(
|
||||
PR_SET_PDEATHSIG, signal.SIGTERM
|
||||
)
|
||||
except Exception:
|
||||
pass # best-effort; never block startup on this
|
||||
|
||||
|
||||
def main(argv=None) -> int:
|
||||
_install_parent_death_signal()
|
||||
args = _parse_args(argv if argv is not None else sys.argv[1:])
|
||||
|
||||
if args.check:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user