steam-backlog-enforcer/steam-backlog-enforcer.service
2026-10-10 16:07:42 +02:00

53 lines
2.4 KiB
Desktop File

[Unit]
Description=Steam Backlog Enforcer
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/steam-backlog-enforcer
ExecStart=/usr/bin/python3 -m steam_backlog_enforcer.main enforce
Restart=always
RestartSec=5
Environment=PYTHONUNBUFFERED=1
Environment=PYTHONPATH=/opt/steam-backlog-enforcer
Environment=HOME=/home/kuhy
Environment=STEAM_ENFORCER_DESKTOP_USER=__DESKTOP_USER__
Environment=DISPLAY=:0
# Hardening: enforcer must not be easily killed.
OOMScoreAdjust=-900
# /run/steam-backlog-enforcer: the control socket for the web UI (ctl.sock) and
# the playtime refusal stub (gaming-blocked, bind-mounted over /usr/bin/steam
# while the budget is spent). Mode 0755 so the stub stays executable by
# everyone; the socket file carries its own 0660 + SO_PEERCRED check.
# Preserve=yes: with the default (no) systemd deletes the directory whenever the
# unit stops, which would delete the stub out from under a live block.
RuntimeDirectory=steam-backlog-enforcer
RuntimeDirectoryMode=0755
RuntimeDirectoryPreserve=yes
# /var/lib/steam-backlog-enforcer: root-only state of the control socket (the
# persisted restart rate limit).
StateDirectory=steam-backlog-enforcer
StateDirectoryMode=0700
# Journal backstop. Steam's srt-logger runs in this unit's cgroup and mirrors
# Steam's console into journald; 2026-09-12 it wrote 481k "joystick FFB"
# lines in one boot (99% of the journal) and evicted two weeks of history.
# SRT_LOGGER_USE_JOURNAL=0 in the spawn env is the fix at source; these two
# make sure a future Steam that ignores it still cannot flood the journal.
LogFilterPatterns=~Failed to get joystick[0-9]+ FFB effect status
LogFilterPatterns=~FFBInterface
LogRateLimitIntervalSec=1min
LogRateLimitBurst=2000
#
# DO NOT ADD PrivateMounts=, PrivateTmp=, ProtectSystem= OR ProtectHome= HERE.
# The daily gaming budget enforces its cutoff by bind-mounting a refusal stub
# over /usr/bin/steam and the other launcher entry points. Any of those
# directives gives this service a private mount namespace, so those mounts stay
# invisible to the rest of the system: the launchers keep working while the
# counter keeps running, and the block silently becomes a no-op. That failure
# mode is invisible from the outside, which is why it is spelled out here.
# _playtime_block.mounts_are_visible() logs an error if it ever happens.
[Install]
WantedBy=multi-user.target