Device rules (udev)
Quasar needs a few devices on the host: /dev/uinput to create virtual
controllers, the GPU render nodes, and in console mode the screen, sound and
local input. Three udev rules files give the quasar group access to exactly
those. They live in the repository under
deploy/udev/.
Each rule adds an access entry (an ACL, set with setfacl) for the quasar
group. It never changes a device’s owner or mode, so nothing that already uses
these devices loses access. No broad group such as input or video is granted.
prepare-host.sh installs the same
files, byte for byte. Use this page if you install them by hand, or want to know
what they do.
The rules
Section titled “The rules”| File | Device | Why Quasar needs it | When needed |
|---|---|---|---|
70-quasar.rules |
/dev/uinput |
Creating virtual keyboards, mice, gamepads and touch devices for players. | Rootless installs |
Input devices named Quasar Virtual * |
Sessions open the virtual devices Quasar created. On an SELinux host they also get the container label, so a confined session can open them. | Rootless installs | |
GPU render nodes (/dev/dri/renderD*) |
Hardware encoding and rendering. | Rootless installs | |
71-quasar-console.rules |
Display cards (/dev/dri/card*) |
The console desktop drives the host’s own screen; the agent reads which monitors are connected. | Console mode |
| Sound devices | The console desktop plays its sound on the host. | Console mode | |
i2c buses (/dev/i2c-*) |
Monitor control (DDC), such as switching the monitor’s input. | Console mode | |
| The host’s input devices (keyboards, mice, controllers, touchpads, buttons) | The console desktop uses them, including ones plugged in later. | Console mode | |
tty8 |
Console mode’s own terminal, so nothing typed reaches a login prompt. | Console mode | |
72-quasar-seat.rules |
Input devices named Quasar Virtual * |
Moves them off the desktop’s seat. See below. | Any host where someone logs into a desktop |
70-quasar.rules does no harm on a rootful install; prepare-host.sh installs it
in both modes.
SELinux and console mode
Section titled “SELinux and console mode”On an SELinux host, sessions run as container_engine_t, and the policy gives that type
none of the console’s devices: without more, the desktop starts with no keyboard, mouse or
sound. prepare-host.sh --console also loads a small module, quasar-console-devices,
that allows exactly these and nothing else: the input nodes, the sound nodes, the hidraw
nodes Steam Input reads, and the udev database. SELinux stays enforcing. By hand:
cat > quasar-console-devices.cil <<'EOF'(allow container_engine_t device_t (dir (getattr open read search watch)))(allow container_engine_t event_device_t (chr_file (getattr ioctl lock map open read write append)))(allow container_engine_t sound_device_t (chr_file (getattr ioctl lock map open read write append)))(allow container_engine_t usb_device_t (chr_file (getattr ioctl lock map open read write append)))(allow container_engine_t udev_var_run_t (dir (getattr open read search)))(allow container_engine_t udev_var_run_t (file (getattr open read map)))EOFsudo semodule -i quasar-console-devices.cilRunning prepare-host.sh again without --console leaves the module in place and says so;
remove it with sudo semodule -r quasar-console-devices.
SELinux and session sound
Section titled “SELinux and session sound”On an SELinux host, an app that needs the nested-sandbox type (container_engine_t, Steam’s
sandbox) connects to its session’s audio sidecar (PipeWire, serving a PulseAudio socket), which runs as container_t. The policy
allows that connection only between containers of the same type, so without more the
session is silent. prepare-host.sh loads a module, quasar-nested-audio, with exactly one
rule for it, and SELinux stays enforcing. The rule is one permission between two types: any
container_engine_t process on the host may connect to a container_t unix socket it can reach
by path. Quasar mounts only the session’s own sidecar directory into the app, and file labels
and permissions still apply; an app given another session’s socket directory could reach that
session’s audio. By hand:
echo '(allow container_engine_t container_t (unix_stream_socket (connectto)))' > quasar-nested-audio.cilsudo semodule -i quasar-nested-audio.cilA host prepared before this module existed has no sound in Steam sessions until you run
prepare-host.sh again; it is safe to repeat. Check with
sudo semodule -l | grep quasar-nested-audio.
The seat rule
Section titled “The seat rule”When someone is logged into a desktop on the host, systemd-logind gives that user access to every input device on the seat, including a player’s virtual controller. The player’s input would then also drive the host desktop. The seat rule puts Quasar’s virtual devices on a seat of their own, so the desktop user never gets them.
There is no uhid rule: Quasar does not emulate a DualSense controller.
Install
Section titled “Install”The files use the group quasar, and setfacl from the acl package at
/usr/bin/setfacl. Create the group first if it does not exist
(prepare-host.sh does).
-
Copy the files you need from a checkout of the repository:
Terminal window sudo cp deploy/udev/70-quasar.rules deploy/udev/72-quasar-seat.rules /etc/udev/rules.d/# console mode onlysudo cp deploy/udev/71-quasar-console.rules /etc/udev/rules.d/ -
Apply them:
Terminal window sudo udevadm control --reload && sudo udevadm trigger -
Console mode only: keep login prompts off
tty8, the terminal console mode uses:Terminal window sudo systemctl mask getty@tty8.service autovt@tty8.service
Check it worked
Section titled “Check it worked”getfacl /dev/uinputThe output includes group:quasar:rw-. With a session running, a desktop user
should not appear on Quasar’s virtual devices:
for d in /sys/class/input/event*; do grep -q '^Quasar Virtual' "$d/device/name" 2>/dev/null && getfacl -p "/dev/input/${d##*/}"doneEach shows group:quasar:rw- and no named-user line such as user:alex:rw-.
Remove
Section titled “Remove”sudo rm -f /etc/udev/rules.d/70-quasar.rules /etc/udev/rules.d/71-quasar-console.rules /etc/udev/rules.d/72-quasar-seat.rulessudo udevadm control --reload && sudo udevadm triggerAccess entries already set stay until the device is recreated or the host reboots.