343c6b45e6
The receiver service never started on the Pi: systemd blocks before exec in acquire_terminal(), waiting for a controlling terminal that the console session or getty on tty1 already owns. Symptoms: the status shows the main PID as "(screencast)" with Tasks:1 and ~40ms CPU, a silent journal, and no mDNS announcement — the binary never ran. Reproduced locally with a transient unit (the desktop's Wayland session owns tty1) and diagnosed by gdb-attaching the stuck process. The service now owns a dedicated free VT (tty7) so acquisition is immediate, with a tolerant ExecStartPre chvt to make the screencast the on-screen console at boot. tty1 keeps the console login; Ctrl+Alt+F1/Ctrl+Alt+F7 switch between them. The previous advice to enable Console Autologin actively caused the hang and is removed from the unit, RUNBOOK, and install script notes. Validated locally: the same properties via systemd-run give a running receiver with all ~15 threads alive that announces itself and is found by --discover; verified unit passes systemd-analyze verify; graceful stop withdraws mDNS.
65 lines
2.5 KiB
Desktop File
65 lines
2.5 KiB
Desktop File
# screencast-receiver.service — autostart for the receiver.
|
|
#
|
|
# This file is a template: scripts/install-receiver.sh substitutes
|
|
# __SC_RECEIVER_BIN__ and __SC_RECEIVER_USER__ before installing it to
|
|
# /etc/systemd/system/screencast-receiver.service.
|
|
#
|
|
# Display environments:
|
|
#
|
|
# 1. Headless console (SDL renders via KMSDRM): works as installed. The
|
|
# configured User needs access to /dev/dri and the input devices; the
|
|
# install script adds it to the video/render/input groups.
|
|
#
|
|
# 2. Graphical session (Wayland or X11 desktop with autologin): uncomment
|
|
# the Environment lines in [Service] and adjust them to the session
|
|
# owner (XDG_RUNTIME_DIR usually lives in /run/user/1000).
|
|
|
|
[Unit]
|
|
Description=Screencast receiver (H.264 over RTP/UDP)
|
|
Wants=network-online.target
|
|
After=network-online.target avahi-daemon.service
|
|
# Give slow-booting boards (and desktop sessions that start late) a chance;
|
|
# systemd's default limit would give up after 5 fast failures.
|
|
StartLimitIntervalSec=30
|
|
StartLimitBurst=10
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=__SC_RECEIVER_USER__
|
|
# SDL's KMSDRM backend wants a tty. The service gets its OWN virtual
|
|
# terminal: systemd must acquire the controlling terminal before exec, and
|
|
# acquiring one that another session owns (tty1: getty, console autologin,
|
|
# or a desktop) blocks the start FOREVER in a pre-exec placeholder process
|
|
# (systemctl status shows the main PID as "(screencast)"). tty7 is free on
|
|
# stock systems; tty1 keeps the console login.
|
|
ExecStartPre=-/usr/bin/chvt 7
|
|
ExecStart=__SC_RECEIVER_BIN__ --receive
|
|
StandardInput=tty
|
|
TTYPath=/dev/tty7
|
|
# SIGTERM (systemctl stop) shuts the receiver down gracefully, which
|
|
# withdraws its mDNS announcement. Never SIGKILL it; the systemd default
|
|
# KillMode escalates only after the graceful timeout.
|
|
KillSignal=SIGTERM
|
|
TimeoutStopSec=10
|
|
Restart=on-failure
|
|
RestartSec=3
|
|
NoNewPrivileges=true
|
|
PrivateTmp=true
|
|
|
|
# Graphical session: uncomment and adjust to the session owner.
|
|
#Environment=XDG_RUNTIME_DIR=/run/user/1000
|
|
#Environment=WAYLAND_DISPLAY=wayland-0
|
|
#Environment=DISPLAY=:0
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
|
|
# Headless console recipe (no window manager needed — SDL renders directly
|
|
# to the kernel via KMSDRM):
|
|
# * Raspberry Pi OS Lite, no desktop enabled (a running compositor would
|
|
# hold the DRM master and the receiver could not take it)
|
|
# * no console autologin needed: the service owns tty7 and switches to it
|
|
# at boot; Ctrl+Alt+F1 returns to the console login, Ctrl+Alt+F7 to the
|
|
# screencast
|
|
# * disable console blanking: add consoleblank=0 to
|
|
# /boot/firmware/cmdline.txt |