Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
647e2b8891 | ||
|
|
3c096835c2 |
@@ -87,9 +87,10 @@ pub use session::{session_epoch, try_recover_session};
|
||||
#[path = "vdisplay/routing.rs"]
|
||||
pub(crate) mod routing;
|
||||
pub use routing::{
|
||||
apply_input_env, managed_session_available, resolve_gamescope_route, restore_managed_session,
|
||||
restore_takeover_now, restore_takeover_on_startup, start_restore_worker,
|
||||
wants_dedicated_game_session, GamescopeRoute,
|
||||
apply_input_env, managed_session_available, preflight_takeover_privilege,
|
||||
resolve_gamescope_route, restore_managed_session, restore_takeover_now,
|
||||
restore_takeover_on_startup, start_restore_worker, wants_dedicated_game_session,
|
||||
GamescopeRoute,
|
||||
};
|
||||
#[cfg(target_os = "linux")]
|
||||
pub use routing::{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -371,6 +371,19 @@ pub fn restore_takeover_on_startup() {
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
pub fn restore_takeover_on_startup() {}
|
||||
|
||||
/// Warn ONCE, at startup, when this box will need the managed gamescope takeover but its user is
|
||||
/// not in the `punktfunk` group the packaged privilege helper gates on — the one takeover
|
||||
/// prerequisite that fails silently mid-stream instead of at setup time. Gated so a box that will
|
||||
/// never attempt a takeover stays quiet; see [`gamescope::preflight_takeover_privilege`] for the
|
||||
/// exact conditions. Call once at `serve` startup, alongside [`restore_takeover_on_startup`].
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn preflight_takeover_privilege() {
|
||||
gamescope::preflight_takeover_privilege();
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
pub fn preflight_takeover_privilege() {}
|
||||
|
||||
/// Give the box its own session back **now**, synchronously, because the host is exiting. Blocks
|
||||
/// (it shells out to `systemctl`), so call it off the async runtime. Call from the host's shutdown
|
||||
/// path — a takeover that outlives the host leaves the box with no display manager and nobody left
|
||||
|
||||
@@ -374,6 +374,12 @@ pub(crate) async fn serve(
|
||||
// A3: recover a TV takeover stranded by a crashed previous host instance (persisted to
|
||||
// $XDG_RUNTIME_DIR) — schedule a restore after a reconnect grace. No-op on a clean start.
|
||||
crate::vdisplay::restore_takeover_on_startup();
|
||||
// …and check the takeover's one un-automatable prerequisite BEFORE a stream needs it: on a box
|
||||
// that will use the takeover, the host's user must be in the `punktfunk` group the packaged
|
||||
// privilege helper gates on. Missing membership fails nothing — the takeover degrades to
|
||||
// mirroring the box's own session — so without this it surfaces only as a black screen on
|
||||
// every connect. No-op off Linux and on any box the takeover can't apply to.
|
||||
crate::vdisplay::preflight_takeover_privilege();
|
||||
// …and the other end of that: give the box its session back when WE are the ones going away.
|
||||
install_shutdown_restore();
|
||||
// Host-lifetime cover-art warmer: fetches + caches GOG/Xbox cover art (no-auth api.gog.com /
|
||||
|
||||
@@ -57,17 +57,21 @@ sudo pacman -Syu punktfunk-scripting # optional: the plugin/script runner (see b
|
||||
sudo usermod -aG input "$USER" # /dev/uinput access for virtual gamepads (re-login to apply)
|
||||
```
|
||||
|
||||
Only if you want the **virtual Steam Deck controller** (paddles, trackpads, gyro — it reaches games
|
||||
as a real USB pad, which is why Steam Input adopts it), also join `punktfunk`:
|
||||
Also join `punktfunk` if **either** applies — you want the **virtual Steam Deck controller**
|
||||
(paddles, trackpads, gyro — it reaches games as a real USB pad, which is why Steam Input adopts
|
||||
it), or this box autologins into Steam **Gaming Mode** and you want the host to take that session
|
||||
over at the client's resolution:
|
||||
|
||||
```sh
|
||||
sudo usermod -aG punktfunk "$USER" # usbip/vhci access (re-login to apply)
|
||||
sudo usermod -aG punktfunk "$USER" # usbip/vhci + display-manager takeover (re-login to apply)
|
||||
```
|
||||
|
||||
That is a second group on purpose. It grants write access to the usbip `attach` file, which
|
||||
materialises an arbitrary emulated USB device — so it stays off the `input` group everyone is
|
||||
routinely told to join. Join it only on a machine you trust. Without it, everything else still
|
||||
works and the pad simply arrives as an ordinary Xbox 360 controller.
|
||||
routinely told to join. Join it only on a machine you trust. On a plain desktop host, everything
|
||||
else still works without it and the pad simply arrives as an ordinary Xbox 360 controller; on a
|
||||
Gaming Mode box the takeover silently degrades to mirroring the box's own screen — see
|
||||
[gamescope](/docs/gamescope#nobara-and-other-autologin-display-managers).
|
||||
|
||||
Each install is a **full** `-Syu`, on purpose: our packages are built against current Arch
|
||||
sonames, and `pacman -Sy <pkg>` would drop one onto a system whose other packages are still old —
|
||||
|
||||
@@ -126,17 +126,21 @@ ujust add-user-to-input-group
|
||||
Then **log out and back in**. (A controller that's "detected but does nothing" is almost always this
|
||||
permission, not a client problem.)
|
||||
|
||||
Only if you want the **virtual Steam Deck controller** (paddles, trackpads, gyro), also join
|
||||
`punktfunk` — `usermod` is fine here, because unlike `input` this group is ours and the sysext
|
||||
creates it on merge:
|
||||
Then join `punktfunk` — `usermod` is fine here, because unlike `input` this group is ours and the
|
||||
sysext creates it on merge:
|
||||
|
||||
```sh
|
||||
sudo usermod -aG punktfunk "$USER" # then log out and back in
|
||||
```
|
||||
|
||||
It is a separate group on purpose: it gates the usbip `attach` file, which can materialise
|
||||
arbitrary emulated USB hardware, so it is not folded into the group everyone is told to join for
|
||||
gamepads. Skip it and the pad arrives as an ordinary Xbox 360 controller instead.
|
||||
This box **is** a Gaming Mode box, so that group is not optional in practice: it authorizes the
|
||||
helper the host uses to stop the display manager when it takes the Gaming Mode session over at your
|
||||
client's resolution, and it gates the usbip `attach` file the **virtual Steam Deck controller**
|
||||
(paddles, trackpads, gyro) attaches through. It is a separate group on purpose — writing that file
|
||||
can materialise arbitrary emulated USB hardware, so it is not folded into the group everyone is
|
||||
told to join for gamepads. Without it the pad arrives as an ordinary Xbox 360 controller, and the
|
||||
takeover degrades to mirroring the box's own screen — see
|
||||
[gamescope](/docs/gamescope#nobara-and-other-autologin-display-managers).
|
||||
|
||||
## Configure
|
||||
|
||||
|
||||
@@ -93,17 +93,21 @@ sudo dnf install punktfunk
|
||||
sudo usermod -aG input "$USER" # /dev/uinput access for virtual gamepads (re-login to apply)
|
||||
```
|
||||
|
||||
Only if you want the **virtual Steam Deck controller** (paddles, trackpads, gyro — it reaches games
|
||||
as a real USB pad, which is why Steam Input adopts it), also join `punktfunk`:
|
||||
Also join `punktfunk` if **either** applies — you want the **virtual Steam Deck controller**
|
||||
(paddles, trackpads, gyro — it reaches games as a real USB pad, which is why Steam Input adopts
|
||||
it), or this box autologins into Steam **Gaming Mode** (Nobara and friends) and you want the host
|
||||
to take that session over at the client's resolution:
|
||||
|
||||
```sh
|
||||
sudo usermod -aG punktfunk "$USER" # usbip/vhci access (re-login to apply)
|
||||
sudo usermod -aG punktfunk "$USER" # usbip/vhci + display-manager takeover (re-login to apply)
|
||||
```
|
||||
|
||||
That is a second group on purpose: it grants write access to the usbip `attach` file, which
|
||||
materialises an arbitrary emulated USB device, so it stays off the `input` group everyone is
|
||||
routinely told to join. Join it only on a machine you trust. Skip it and the pad simply arrives as
|
||||
an ordinary Xbox 360 controller.
|
||||
routinely told to join. Join it only on a machine you trust. Skip it on a plain desktop host and
|
||||
the pad simply arrives as an ordinary Xbox 360 controller; skip it on a Gaming Mode box and the
|
||||
takeover silently degrades to mirroring the box's own screen — see
|
||||
[gamescope](/docs/gamescope#nobara-and-other-autologin-display-managers).
|
||||
|
||||
Updates later are just `sudo dnf upgrade punktfunk`, followed by
|
||||
`systemctl --user restart punktfunk-host` so the running host picks up the new binary. The package
|
||||
|
||||
@@ -40,16 +40,37 @@ the [Bazzite template](/docs/bazzite) ships with **attach** chosen instead.
|
||||
|
||||
### Nobara and other autologin display managers
|
||||
|
||||
The managed takeover has to stop the box's Gaming Mode session to free Steam. How it does that
|
||||
depends on the display manager driving the autologin:
|
||||
The managed takeover has to stop the box's Gaming Mode session to free Steam — and when that
|
||||
session is a display-manager autologin, it has to stop the **display manager** too, for the length
|
||||
of the stream. That is a privileged operation, and the privilege is granted to one group.
|
||||
|
||||
- **SDDM** (Bazzite, SteamOS): handled automatically — no setup.
|
||||
- **plasmalogin** (Nobara) and other display managers: the host must stop the display manager
|
||||
itself for the length of the stream and restart it afterwards, which needs privilege. The
|
||||
packages ship that privilege: a root helper (`/usr/libexec/punktfunk/pf-dm-helper`, or
|
||||
`/usr/lib/punktfunk/pf-dm-helper` from the Arch package) behind its own polkit action
|
||||
(`io.unom.punktfunk.dm-helper`), invoked automatically when the plain
|
||||
`systemctl` verbs are denied — no setup. The helper only stops/restores the unit the
|
||||
> **Join the `punktfunk` group on any box you stream Game Mode from.** The takeover's root helper
|
||||
> runs for members of that group and for nobody else, so this one command is what authorizes it:
|
||||
>
|
||||
> ```sh
|
||||
> sudo usermod -aG punktfunk "$USER" # then log out and back in
|
||||
> ```
|
||||
>
|
||||
> Your package created the group at install time and put **nobody** in it, on purpose: it also
|
||||
> gates the usbip nodes the virtual Steam Deck pad attaches through, and writing those can present
|
||||
> arbitrary emulated USB hardware — so joining stays a deliberate act, on a machine you trust.
|
||||
> Skip it and nothing fails loudly. Every takeover degrades to mirroring the box's own session
|
||||
> (below), which on a box whose panel is off reads as a black screen on every connect. The host
|
||||
> checks this at startup on any box that will need the takeover and says so in its log; the
|
||||
> symptom side is [Game Mode: black screen on
|
||||
> connect](/docs/troubleshooting#game-mode-black-screen-on-connect-or-the-stream-is-stuck-at-the-boxs-resolution).
|
||||
|
||||
How the takeover gets that privilege depends on the display manager driving the autologin:
|
||||
|
||||
- **SDDM** (Bazzite, SteamOS): SDDM survives having the session unit masked, so a box without the
|
||||
grant still streams — at the cost of SDDM relogin-looping against the takeover for the whole
|
||||
stream, which churns logind sessions and can starve the game.
|
||||
- **plasmalogin** (Nobara) and other display managers: masking is fatal there (the autologin
|
||||
start-limit-kills the display manager), so the host stops the display manager itself and
|
||||
restarts it afterwards. The packages ship that privilege: a root helper
|
||||
(`/usr/libexec/punktfunk/pf-dm-helper`, or `/usr/lib/punktfunk/pf-dm-helper` from the Arch
|
||||
package) behind its own polkit action (`io.unom.punktfunk.dm-helper`), invoked automatically
|
||||
when the plain `systemctl` verbs are denied. The helper only stops/restores the unit the
|
||||
`display-manager.service` symlink points at, the same class of local-seat operation these
|
||||
distros already authorize for their own session switcher (Nobara's `os-session-select`).
|
||||
|
||||
@@ -71,8 +92,11 @@ depends on the display manager driving the autologin:
|
||||
With no privilege path at all the host degrades safely: it **attaches** to the live Gaming Mode
|
||||
session instead (Game Mode stays on the box's display at the box's own resolution, mirrored to
|
||||
the client — if your monitor stays on and the stream runs at the desktop's resolution, this is
|
||||
what happened; check the host log for "managed takeover unavailable"). If the display-manager
|
||||
restart ever loses its privilege mid-restore, `PUNKTFUNK_RECOVER_SESSION_CMD` (see
|
||||
what happened; check the host log for "managed takeover unavailable"). That log line now quotes
|
||||
the privileged path's own reason for refusing, so read it before changing anything: by far the
|
||||
most common one is `not in the 'punktfunk' group`, which the group command above fixes and
|
||||
neither a reinstall nor a polkit rule does. If the display-manager restart ever loses its
|
||||
privilege mid-restore, `PUNKTFUNK_RECOVER_SESSION_CMD` (see
|
||||
[Configuration](/docs/configuration)) is fired as the fallback.
|
||||
|
||||
**Lingering is required here**, and the host turns it on for you the first time it takes the box
|
||||
@@ -81,7 +105,9 @@ depends on the display manager driving the autologin:
|
||||
taking the host with it, mid-stream, with the display manager down and nothing left to bring it
|
||||
back. If lingering can't be enabled the host refuses the takeover and degrades to attach instead
|
||||
(above) rather than risk that. Run `sudo loginctl enable-linger "$USER"` once, as the setup guides
|
||||
ask; `loginctl disable-linger "$USER"` reverts it.
|
||||
ask; `loginctl disable-linger "$USER"` reverts it. (A host with no login session of its own turns
|
||||
lingering on through the *same* helper, so a missing group grant surfaces here first — the log
|
||||
says "enabling lingering failed" and then quotes the same reason.)
|
||||
|
||||
With the takeover authorized the **in-stream session switch round-trips** in managed mode:
|
||||
Steam's "Switch to Desktop" inside the streamed Game Mode returns the box to its desktop session
|
||||
@@ -214,6 +240,18 @@ These apply to the **Gaming Mode (gamescope)** path only; the desktop path is un
|
||||
mode and rate, and `PUNKTFUNK_GAMESCOPE_REFRESH_RATES=60,90,120` puts more than one entry in that
|
||||
menu. If the host log says *"the session did not start at the mode we asked for"*, a file in
|
||||
`/etc/gamescope-session-plus/sessions.d/` is overriding `GAMESCOPE_BIN` or setting `GAMESCOPECMD`.
|
||||
- **Some distros' session script ignores `GAMESCOPE_BIN` entirely — the host works around it with a
|
||||
bind mount.** Nobara's `gamescope-session-plus` never reads that variable and hardcodes
|
||||
`/usr/bin/gamescope` outright, so neither the variable nor a `PATH` entry can point the session at
|
||||
`punktfunk-gamescope`; every session ran the stock binary, which cost HDR *and* the in-stream
|
||||
cursor. The host now detects that shape by reading the script, and binds its own wrapper over the
|
||||
hardcoded path **inside the session unit's own mount namespace** — the session gets the patched
|
||||
gamescope and the flags, and nothing outside that unit changes (the distro still owns
|
||||
`/usr/bin/gamescope`; you do not need to overwrite it). You will see *"binding the punktfunk
|
||||
wrapper over it"* in the log when this engages. It needs unprivileged user namespaces; on a box
|
||||
without them the host logs that it cannot take a mount namespace and streams SDR with a
|
||||
host-composited cursor, exactly as before. Boxes whose script does honour `GAMESCOPE_BIN`
|
||||
(Bazzite, SteamOS) are untouched by any of this.
|
||||
- **The performance overlay (fps / frametime / stats) needs the patched build.** It is mangoapp,
|
||||
which gamescope draws as an *external overlay* — a layer upstream's capture composite has never
|
||||
included on any version, so on a stock gamescope you can turn the overlay on and it simply will
|
||||
|
||||
@@ -156,11 +156,16 @@ you; on NixOS the module does steps 1 and 2, and [NixOS](#nixos) above has the u
|
||||
command differs per distro — see your guide (`usermod -aG input "$USER"`, or `ujust
|
||||
add-user-to-input-group` on Bazzite).
|
||||
|
||||
Only if you want the **virtual Steam Deck controller** (paddles, trackpads, gyro), also join
|
||||
`punktfunk`: `sudo usermod -aG punktfunk "$USER"`. Your package created that group at install
|
||||
time; it gates the usbip nodes that pad attaches through, and it is separate from `input` on
|
||||
purpose, because writing them can present arbitrary emulated USB hardware. Join it only on a
|
||||
machine you trust — skipping it costs you nothing but that one pad type.
|
||||
Also join `punktfunk` — `sudo usermod -aG punktfunk "$USER"`, then log out and back in — if
|
||||
**either** of these is true: you want the **virtual Steam Deck controller** (paddles,
|
||||
trackpads, gyro), or this box autologins into Steam **Gaming Mode** and you want the host to
|
||||
take that session over at your client's resolution
|
||||
([gamescope](/docs/gamescope#nobara-and-other-autologin-display-managers)). Your package created
|
||||
that group at install time and left it empty. It gates the usbip nodes the pad attaches through
|
||||
*and* the helper that stops the display manager for a takeover, and it is separate from `input`
|
||||
on purpose, because writing those nodes can present arbitrary emulated USB hardware — so join it
|
||||
only on a machine you trust. On a plain desktop host that streams no Gaming Mode, skipping it
|
||||
costs you nothing but that one pad type.
|
||||
2. Put your `host.env` in place, then start the host. Every Linux package ships a systemd **user**
|
||||
unit, so you don't run the host by hand — but that unit reads `~/.config/punktfunk/host.env` and
|
||||
won't start until the file exists. Each package ships a template to copy; your distro and desktop
|
||||
|
||||
@@ -133,7 +133,11 @@ disable, and the session unit differ per compositor, so each is documented on it
|
||||
- GNOME: [GNOME → Headless session](/docs/gnome#headless-session).
|
||||
- KDE Plasma: [KDE → Headless session](/docs/kde#headless-session).
|
||||
- Steam / gamescope: [gamescope](/docs/gamescope) — the host launches its own session per client, so
|
||||
there's no separate session unit.
|
||||
there's no separate session unit. A headless box that autologins into **Gaming Mode** needs one
|
||||
more thing: your user in the `punktfunk` group (`sudo usermod -aG punktfunk "$USER"`, then log
|
||||
out and back in). Without it the host cannot stop the display manager to take that session over,
|
||||
so every connect quietly mirrors the box's own screen — which, headless, is a black one. See
|
||||
[gamescope → autologin display managers](/docs/gamescope#nobara-and-other-autologin-display-managers).
|
||||
|
||||
Once a session comes up at boot, enable the host user service (section A) and reboot. The host comes up
|
||||
on that session.
|
||||
|
||||
@@ -198,6 +198,44 @@ Current hosts detect the display-manager flavor and never mask the session unit
|
||||
[gamescope → autologin display managers](/docs/gamescope) for the polkit rule that enables the full
|
||||
managed takeover on these boxes (without it the host mirrors Game Mode instead).
|
||||
|
||||
## Game Mode: black screen on connect, or the stream is stuck at the box's resolution
|
||||
|
||||
You connect to a box that autologins into Steam **Gaming Mode** and get a black picture every time
|
||||
— or a picture at the box's own resolution instead of the one your client asked for, with the box's
|
||||
monitor still lit. Nothing errors: the client connects, the host logs no failure, no unit is failed.
|
||||
|
||||
The managed takeover is being refused and the host is falling back to mirroring the box's own
|
||||
session. On a box whose panel is off (a headless appliance, a TV that's been switched away) there
|
||||
is nothing to mirror, so the fallback is a black screen. Almost always the cause is **group
|
||||
membership**: the takeover stops the display manager through a root helper, and that helper serves
|
||||
members of the `punktfunk` group only.
|
||||
|
||||
```sh
|
||||
id -nG | tr ' ' '\n' | grep -x punktfunk # are you in it?
|
||||
journalctl --user -u punktfunk-host | grep -iE "punktfunk. group|takeover unavailable"
|
||||
```
|
||||
|
||||
The host also checks at startup on any box that will need the takeover, so a fresh
|
||||
`systemctl --user restart punktfunk-host` puts the answer at the top of the log. The fix is one
|
||||
command and a fresh login:
|
||||
|
||||
```sh
|
||||
sudo usermod -aG punktfunk "$USER" # then log out and back in
|
||||
```
|
||||
|
||||
> **Read the reason the log quotes before doing anything else.** The takeover has three other ways
|
||||
> to be refused — no packaged helper (a tarball or source install), no polkit on the box, and
|
||||
> polkit denying the action — and the host now prints which one it hit, verbatim from the
|
||||
> privileged path. Hosts up to 0.27.0 printed a fixed guess instead ("reinstall the punktfunk
|
||||
> package, or install the display-manager polkit rule from the docs"), and on the group case both
|
||||
> of those suggestions were dead ends: neither adds anyone to a group.
|
||||
|
||||
Two things this is *not*: it isn't the [pad group problem](#the-pad-works-but-arrives-as-an-xbox-360-controller-instead-of-a-steam-deck)
|
||||
(same group, different symptom), and it isn't lingering — though a host with no login session of
|
||||
its own enables lingering through the same helper, so an unjoined user often sees "enabling
|
||||
lingering failed" first. Both are covered in
|
||||
[gamescope → autologin display managers](/docs/gamescope#nobara-and-other-autologin-display-managers).
|
||||
|
||||
## Session fails right after editing host.env
|
||||
|
||||
- Keys are **case-sensitive**: `punktfunk_gamescope_attach=1` sets nothing — use the exact
|
||||
@@ -275,6 +313,10 @@ the reliable way to get one.
|
||||
Joining the group is optional, and there is a real reason it is not automatic: writing that
|
||||
`attach` file materialises an arbitrary emulated USB device. Skip it on a machine you share.
|
||||
|
||||
It is not only the pad, though: the same group authorizes the helper that stops the display manager
|
||||
for a managed **Gaming Mode** takeover, so on a box that autologins into Game Mode, skipping it also
|
||||
costs you [the takeover](#game-mode-black-screen-on-connect-or-the-stream-is-stuck-at-the-boxs-resolution).
|
||||
|
||||
## Copy and paste between host and client does nothing
|
||||
|
||||
The shared clipboard needs **two** separate switches on, and turning on only one looks exactly like
|
||||
|
||||
@@ -111,17 +111,20 @@ re-login so the new group membership takes effect:
|
||||
sudo usermod -aG input "$USER" # re-login to apply
|
||||
```
|
||||
|
||||
Only if you want the **virtual Steam Deck controller** (paddles, trackpads, gyro), also join
|
||||
`punktfunk`. That pad reaches games as a real USB device over usbip — which is what makes Steam
|
||||
Input adopt it — and the group gating those nodes is deliberately separate from `input`, because
|
||||
Also join `punktfunk` if **either** applies — you want the **virtual Steam Deck controller**
|
||||
(paddles, trackpads, gyro), or this box autologins into Steam **Gaming Mode** and you want the host
|
||||
to take that session over at the client's resolution. That pad reaches games as a real USB device
|
||||
over usbip — which is what makes Steam Input adopt it — and the same group authorizes the helper
|
||||
that stops the display manager for a takeover. It is deliberately separate from `input`, because
|
||||
writing the usbip `attach` file can materialise arbitrary emulated USB hardware:
|
||||
|
||||
```sh
|
||||
sudo usermod -aG punktfunk "$USER" # re-login to apply
|
||||
```
|
||||
|
||||
Join it only on a machine you trust. Skip it and everything else still works; the pad just arrives
|
||||
as an ordinary Xbox 360 controller.
|
||||
Join it only on a machine you trust. On a plain desktop host, skipping it costs you nothing but
|
||||
that one pad type; on a Gaming Mode box the takeover silently degrades to mirroring the box's own
|
||||
screen — see [gamescope](/docs/gamescope#nobara-and-other-autologin-display-managers).
|
||||
|
||||
## 4. Check it installed
|
||||
|
||||
|
||||
@@ -8,7 +8,10 @@ _ensure_punktfunk_group() {
|
||||
# Owns the usbip vhci attach/detach nodes (60-punktfunk.rules). Separate from 'input' on
|
||||
# purpose: writing 'attach' materialises an arbitrary emulated USB device, which is a root-only
|
||||
# kernel primitive and must not ride on the group users are told to join for gamepads
|
||||
# (security-review 2026-08-05 M-4).
|
||||
# (security-review 2026-08-05 M-4). It is ALSO the group pf-dm-helper authorizes on (its polkit
|
||||
# action must stay allow_any, so membership is the real gate), i.e. what a managed gamescope
|
||||
# takeover needs to stop the display manager. Creating the group is necessary and NOT sufficient
|
||||
# for either use: membership is.
|
||||
getent group punktfunk >/dev/null 2>&1 || groupadd --system punktfunk 2>/dev/null || true
|
||||
}
|
||||
|
||||
@@ -62,9 +65,11 @@ post_install() {
|
||||
punktfunk-host installed.
|
||||
1. Add yourself to the 'input' group for virtual gamepads:
|
||||
sudo usermod -aG input "$USER" # then re-login
|
||||
Only if you want the virtual Steam Deck pad (usbip), ALSO join 'punktfunk':
|
||||
sudo usermod -aG punktfunk "$USER"
|
||||
That group can emulate arbitrary USB devices — join it only on a machine you trust.
|
||||
ALSO join 'punktfunk' if this box streams Steam Gaming Mode (gamescope), or you want the
|
||||
virtual Steam Deck pad (usbip):
|
||||
sudo usermod -aG punktfunk "$USER" # then log out and back in
|
||||
It authorizes stopping the display manager for a managed gamescope session, and the pad's
|
||||
usbip nodes. It can emulate arbitrary USB devices — join it only on a machine you trust.
|
||||
2. Pick a backend config (gamescope is the no-desktop default on SteamOS/Deck):
|
||||
mkdir -p ~/.config/punktfunk
|
||||
cp /usr/share/punktfunk/host.env.bazzite ~/.config/punktfunk/host.env
|
||||
|
||||
@@ -292,7 +292,10 @@ if [ "$1" = "configure" ]; then
|
||||
# Owns the usbip vhci attach/detach nodes (60-punktfunk.rules). Deliberately NOT 'input':
|
||||
# writing 'attach' materialises an arbitrary emulated USB device — a root-only kernel
|
||||
# primitive that must not ride on the group users are told to join for gamepads
|
||||
# (security-review 2026-08-05 M-4).
|
||||
# (security-review 2026-08-05 M-4). It is ALSO the group pf-dm-helper authorizes on (its
|
||||
# polkit action must stay allow_any, so membership is the real gate), i.e. what a managed
|
||||
# gamescope takeover needs to stop the display manager. Creating the group is necessary and
|
||||
# NOT sufficient for either use: membership is.
|
||||
getent group punktfunk >/dev/null 2>&1 || addgroup --system punktfunk 2>/dev/null || true
|
||||
# NO capability on the host binary — and an active removal of the one 0.26.0-1 granted here.
|
||||
#
|
||||
@@ -318,8 +321,13 @@ if [ "$1" = "configure" ]; then
|
||||
sysctl -p /usr/lib/sysctl.d/99-punktfunk-net.conf >/dev/null 2>&1 || true
|
||||
echo "punktfunk-host installed. Add yourself to the 'input' group for virtual gamepads:"
|
||||
echo " sudo usermod -aG input \"\$USER\" # then re-login"
|
||||
echo "For the virtual Steam Deck pad (usbip) ALSO: sudo usermod -aG punktfunk \"\$USER\""
|
||||
echo " — that group can emulate arbitrary USB devices; join it only on a machine you trust."
|
||||
# Naming only the usbip pad here is how a Nobara host shipped broken: its owner had no Deck
|
||||
# pad, so they correctly skipped this group — and then every managed gamescope takeover
|
||||
# degraded silently, because pf-dm-helper (which stops the display manager) gates on membership.
|
||||
echo "ALSO join 'punktfunk' if this box streams Steam Gaming Mode (gamescope) or you want the"
|
||||
echo "virtual Steam Deck pad: sudo usermod -aG punktfunk \"\$USER\" # then log out and back in"
|
||||
echo " — it authorizes stopping the display manager for a managed gamescope session, and the"
|
||||
echo " pad's usbip nodes; it can emulate arbitrary USB devices, so join it only on a box you trust."
|
||||
echo "Config: mkdir -p ~/.config/punktfunk && cp /usr/share/punktfunk-host/host.env.example ~/.config/punktfunk/host.env"
|
||||
echo "Enable: systemctl --user enable --now punktfunk-host"
|
||||
# Debian ships no active firewall and Ubuntu's ufw is inactive by default; hint whichever is present.
|
||||
|
||||
@@ -595,6 +595,9 @@ getent group punktfunk-update >/dev/null 2>&1 || groupadd --system punktfunk-upd
|
||||
# Owns the usbip vhci attach/detach nodes (60-punktfunk.rules). Deliberately NOT 'input': writing
|
||||
# 'attach' materialises an arbitrary emulated USB device — a root-only kernel primitive that must
|
||||
# not ride on the group users are told to join for gamepads (security-review 2026-08-05 M-4).
|
||||
# It is ALSO the group `pf-dm-helper` authorizes on (the polkit action must stay `allow_any`, so
|
||||
# membership is the real gate) — so it is what a managed gamescope takeover needs to stop the
|
||||
# display manager. Creating it is necessary and NOT sufficient for either use: membership is.
|
||||
getent group punktfunk >/dev/null 2>&1 || groupadd --system punktfunk 2>/dev/null || :
|
||||
# Reload udev so /dev/uinput picks up the new rule without a reboot (best-effort).
|
||||
udevadm control --reload-rules 2>/dev/null || :
|
||||
@@ -603,8 +606,13 @@ udevadm trigger --subsystem-match=misc 2>/dev/null || :
|
||||
# it takes effect on the next boot into the layered deployment).
|
||||
sysctl -p %{_prefix}/lib/sysctl.d/99-punktfunk-net.conf >/dev/null 2>&1 || :
|
||||
echo "punktfunk installed. Add yourself to the 'input' group (sudo usermod -aG input \$USER)"
|
||||
echo "For the virtual Steam Deck pad (usbip) ALSO: sudo usermod -aG punktfunk \$USER"
|
||||
echo " — that group can emulate arbitrary USB devices; join it only on a machine you trust."
|
||||
# Naming only the usbip pad here is how a Nobara host shipped broken: its owner had no Deck pad, so
|
||||
# they correctly skipped this group — and then every managed gamescope takeover degraded silently,
|
||||
# because pf-dm-helper (which stops the display manager for the stream) gates on THIS membership.
|
||||
echo "ALSO join 'punktfunk' if this box streams Steam Gaming Mode (gamescope) or you want the"
|
||||
echo "virtual Steam Deck pad: sudo usermod -aG punktfunk \$USER # then log out and back in"
|
||||
echo " — it authorizes stopping the display manager for a managed gamescope session, and the"
|
||||
echo " pad's usbip nodes; it can emulate arbitrary USB devices, so join it only on a box you trust."
|
||||
echo "then enable the host: systemctl --user enable --now punktfunk-host"
|
||||
echo "Config: cp %{_datadir}/%{name}/host.env.bazzite ~/.config/punktfunk/host.env"
|
||||
# Fedora/RHEL run firewalld by default — point the way to the installed service definitions.
|
||||
|
||||
Reference in New Issue
Block a user