[PATCH] host/rootfs: Automatically select card node
This allows Weston to launch even if there if /dev/dri/card0 does not exist. This requires a shell script for string processing. It could be written in Rust, but that's not worth it for a temporary workaround. It also prevents waiting for the card to be ready. Instead, let s6 restart Weston over and over until Weston finally runs. Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com> --- This makes Spectrum work on my AMD system. --- host/rootfs/file-list.mk | 1 + host/rootfs/image/etc/s6-rc/weston/run | 6 +++--- host/rootfs/image/usr/bin/run-weston | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/host/rootfs/file-list.mk b/host/rootfs/file-list.mk index 3899d620717fc97f42e669e5313c4100dcf5b1cd..0ece8e08a0e2d367fe124e90896355aa98a58cb8 100644 --- a/host/rootfs/file-list.mk +++ b/host/rootfs/file-list.mk @@ -62,6 +62,7 @@ FILES = \ image/usr/bin/run-appimage \ image/usr/bin/run-flatpak \ image/usr/bin/run-vmm \ + image/usr/bin/run-weston \ image/usr/bin/spectrum-update \ image/usr/bin/vm-console \ image/usr/bin/vm-import \ diff --git a/host/rootfs/image/etc/s6-rc/weston/run b/host/rootfs/image/etc/s6-rc/weston/run index fd59586c719391deb546c29578341e16a61ed4ce..6c0aac4a2326b5d56b9c09f82589dfbcc78eaabd 100644 --- a/host/rootfs/image/etc/s6-rc/weston/run +++ b/host/rootfs/image/etc/s6-rc/weston/run @@ -2,7 +2,7 @@ # SPDX-License-Identifier: EUPL-1.2+ # SPDX-FileCopyrightText: 2021, 2025 Alyssa Ross <hi@alyssa.is> -importas -Siu WAYLAND_DISPLAY +importas -Si WAYLAND_DISPLAY piperw 4 3 background { @@ -40,7 +40,6 @@ redirfd -r 0 /dev/tty1 importas -i home HOME cd $home -if { udevadm wait /dev/dri/card0 } s6-setuidgid wayland bwrap # no --unshare-net, breaks udev hotplug @@ -88,4 +87,5 @@ bwrap --bind /run/user/0 /run/user/0 --bind /run/wayland /run/wayland -- -weston -S $WAYLAND_DISPLAY + elglob -w0 CARD "/dev/dri/card[0-9]*" + /usr/bin/run-weston $CARD diff --git a/host/rootfs/image/usr/bin/run-weston b/host/rootfs/image/usr/bin/run-weston new file mode 100755 index 0000000000000000000000000000000000000000..6a14f905d2e9e5533d00aac1ee7f920ebf55fac3 --- /dev/null +++ b/host/rootfs/image/usr/bin/run-weston @@ -0,0 +1,32 @@ +#!/usr/bin/sh -- +# SPDX-License-Identifier: EUPL-1.2+ +# SPDX-FileCopyrightText: 2026 Demi Marie Obenour <demiobenour@gmail.com> +set -euf +case ${1-} in +/dev/dri/card[0-9]*) + first_dev=${1#/dev/dri/} extra_cards= + shift + ;; +*) + echo 'No card nodes found, cannot run Weston' >&2 + exit 1 + ;; +esac +for i; do + case $i in + *,*) continue ;; + /dev/dri/card[0-9]*) : ;; + *) + echo 'Bad name from execline script' >&2 + exit 1 + ;; + esac + card_name=${i#/dev/dri/} + case $card_name in */*) continue ;; esac + if [ -z "$extra_cards" ]; then + extra_cards=--additional-devices=$card_name + else + extra_cards=$extra_cards,$card_name + fi +done +exec weston --backend=drm "--drm-device=$first_dev" $extra_cards -S "$WAYLAND_DISPLAY" --- base-commit: 4827f7591e945f331a945fb53a9fd4e8ebfdbc12 change-id: 20260523-weston-card-fix-725c98d5245f -- Sincerely, Demi Marie Obenour (she/her/hers)
Demi Marie Obenour <demiobenour@gmail.com> writes:
This allows Weston to launch even if there if /dev/dri/card0 does not exist.
This requires a shell script for string processing. It could be written in Rust, but that's not worth it for a temporary workaround.
It also prevents waiting for the card to be ready. Instead, let s6 restart Weston over and over until Weston finally runs.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com> --- This makes Spectrum work on my AMD system.
This made me look into the underlying issue a bit more. What happens if you just remove the udevadm wait? Does everything seem to work okay? My guess would be yes, because from what I can tell, the original problem was probably that Weston was started before the DRM kernel module was loaded. (systemd-logind.service has a dependency on modprobe@drm.service, and we had no such equivalent). Nowadays, DRM is built in to Nixpkgs kernels, so that shouldn't be able to happen any more. I think we should therefore be able to just drop the wait, and its equivalents in img/app and release/checks/wayland.
Weston can find a card itself. If the card is not ready, it will exit, but s6 will automatically restart it. Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com> --- This makes Spectrum work on my AMD system. --- Changes in v2: - Only remove the udevadm wait. - Rely on Weston to pick a card node. - Link to v1: https://spectrum-os.org/lists/archives/spectrum-devel/20260524-weston-card-f... --- host/rootfs/image/etc/s6-rc/weston/run | 1 - 1 file changed, 1 deletion(-) diff --git a/host/rootfs/image/etc/s6-rc/weston/run b/host/rootfs/image/etc/s6-rc/weston/run index fd59586c719391deb546c29578341e16a61ed4ce..68eff51ae127b848b56f6b3c3761b65ad1be9a0d 100644 --- a/host/rootfs/image/etc/s6-rc/weston/run +++ b/host/rootfs/image/etc/s6-rc/weston/run @@ -40,7 +40,6 @@ redirfd -r 0 /dev/tty1 importas -i home HOME cd $home -if { udevadm wait /dev/dri/card0 } s6-setuidgid wayland bwrap # no --unshare-net, breaks udev hotplug --- base-commit: 4827f7591e945f331a945fb53a9fd4e8ebfdbc12 change-id: 20260523-weston-card-fix-725c98d5245f -- Sincerely, Demi Marie Obenour (she/her/hers)
Demi Marie Obenour <demiobenour@gmail.com> writes:
Weston can find a card itself. If the card is not ready, it will exit, but s6 will automatically restart it.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
I don't think this commit message really captures it. As long as the card is not hotplugged, it _will_ be ready, as far as I know, because it will become ready when DRM is loaded, before userspace starts. This makes it sound like Weston not finding a card and being restarted by s6 would be routine behaviour, whereas we'd actually not expect to ever see it, except in the very unusual case of somebody having no cards at boot and later hotplugging one. (Even then it's not ideal to need to restart in a loop, but that case can wait for COSMIC.) I suggest the following alternative, which also removes some other obsolete instances of the same pattern. From 71216f0aa36049cbd3c7b7562e6e7ff225a1c810 Mon Sep 17 00:00:00 2001 From: Alyssa Ross <hi@alyssa.is> Date: Tue, 26 May 2026 16:05:21 +0200 Subject: [PATCH] Stop waiting for /dev/dri/card0 On the host, which does not run in a well-controlled VM environment, there might not be a card0 (sometimes you just get card1). This causes hangs. It hasn't been necessary to wait for non-hotplugged DRI devices to exist since the Nixpkgs kernel set CONFIG_DRM=y. (If there's no device at startup, s6 will just keep restarting the services until there is one, but that case should be pretty unusual.) Closes: https://matrix.to/#/!xSysqhzbOZImdvGpix:fairydust.space/$FXt0B6ZcIn1KO1k-sis... Link: https://matrix.to/#/!xSysqhzbOZImdvGpix:fairydust.space/$Gvq6jxvt5d5qngIqs0x... Reported-by: Yureka Lilian <yureka@cyberchaos.dev> Closes: https://inbox.spectrum-os.org/spectrum-devel/6ba1fc13-c905-4074-a878-bb2488e... Link: https://inbox.spectrum-os.org/spectrum-devel/20260524-weston-card-fix-v1-1-9... Signed-off-by: Alyssa Ross <hi@alyssa.is> --- host/rootfs/image/etc/s6-rc/weston/run | 1 - img/app/image/etc/mdev.conf | 2 +- img/app/image/etc/s6-rc/wayland-proxy-virtwl/run | 2 -- release/checks/wayland/default.nix | 8 ++------ 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/host/rootfs/image/etc/s6-rc/weston/run b/host/rootfs/image/etc/s6-rc/weston/run index fd59586c..68eff51a 100644 --- a/host/rootfs/image/etc/s6-rc/weston/run +++ b/host/rootfs/image/etc/s6-rc/weston/run @@ -40,7 +40,6 @@ redirfd -r 0 /dev/tty1 importas -i home HOME cd $home -if { udevadm wait /dev/dri/card0 } s6-setuidgid wayland bwrap # no --unshare-net, breaks udev hotplug diff --git a/img/app/image/etc/mdev.conf b/img/app/image/etc/mdev.conf index 33a07d6b..40c2149d 100644 --- a/img/app/image/etc/mdev.conf +++ b/img/app/image/etc/mdev.conf @@ -4,7 +4,7 @@ -$MODALIAS=.* 0:0 0 ! +importas -Siu MODALIAS modprobe -q $MODALIAS $INTERFACE=.* 0:0 0 ! +/etc/mdev/iface $MODALIAS=virtio:d0000001Av.* 0:0 0 ! +/etc/mdev/virtiofs -dri/card0 user:user 660 +background { /etc/mdev/listen card0 } +dri/card0 user:user 660 -SUBSYSTEM=sound;.* pipewire:pipewire 660 snd/controlC0 pipewire:pipewire 660 +background { /etc/mdev/listen controlC0 } diff --git a/img/app/image/etc/s6-rc/wayland-proxy-virtwl/run b/img/app/image/etc/s6-rc/wayland-proxy-virtwl/run index 3fe113fe..bcd4c0fc 100755 --- a/img/app/image/etc/s6-rc/wayland-proxy-virtwl/run +++ b/img/app/image/etc/s6-rc/wayland-proxy-virtwl/run @@ -20,8 +20,6 @@ redirfd -r 0 /dev/null if { fdmove 1 5 echo } fdclose 5 -if { /etc/mdev/wait card0 } - export LISTEN_FDS 2 export LISTEN_FDNAMES wayland:x11 getpid LISTEN_PID diff --git a/release/checks/wayland/default.nix b/release/checks/wayland/default.nix index 40f96199..a36f5b91 100644 --- a/release/checks/wayland/default.nix +++ b/release/checks/wayland/default.nix @@ -16,10 +16,6 @@ testers.nixosTest ({ lib, pkgs, ... }: { nodes.machine = { ... }: { hardware.graphics.enable = true; - services.udev.extraRules = '' - KERNEL=="card0", TAG+="systemd" - ''; - systemd.mounts = [ { name = "shared-config.mount"; @@ -63,8 +59,8 @@ testers.nixosTest ({ lib, pkgs, ... }: { }; systemd.services.weston = { - after = [ "dev-dri-card0.device" "surface-notify-socket.service" ]; - wants = [ "dev-dri-card0.device" "surface-notify-socket.service" ]; + after = [ "surface-notify-socket.service" ]; + wants = [ "surface-notify-socket.service" ]; environment.XDG_RUNTIME_DIR = "/run"; environment.WAYLAND_DEBUG = "server"; serviceConfig.ExecStart = "${lib.getExe pkgs.westonLite} --modules ${surface-notify}/lib/weston/surface-notify.so,systemd-notify.so"; -- 2.53.0
participants (2)
-
Alyssa Ross -
Demi Marie Obenour