waypipe 报 Iris kernel too old 排查:被『客户端没有 GPU 节点』带偏的过程
八月 09, 2026 更新: 九月 13, 2026 [Linux 与系统] #waypipe #调试问题现象
客户端机器通过 waypipe 连到服务器跑图形程序:
waypipe ssh workpc
weston-dnd
结果终端刷出报错:
error: Kernel is too old (4.16+ required) or unusable for Iris.
Check your dmesg logs for loading failures.
偶发还伴随 waypipe 的 dmabuf 报错:
S607565: 60.485827 [src/dmabuf.c:125] Failed to open drm fd for /dev/dri/renderD128: No such file or directory
关键对照:waypipe --no-gpu ssh workpc 后执行 weston-dnd 完全正常。显然问题在 waypipe 的 GPU 通道(dmabuf 直传)。
本文如实记录一次被错误怀疑带偏的排查——错误的焦点反复落在"服务端/客户端到底谁没有 renderD128"上,而真相在另一个层面。
第一轮误判:怀疑服务端(服务器)缺 renderD128
初始推断很自然:报错里有 Failed to open drm fd for /dev/dri/renderD128,dmabuf 直传要求两端都能打开渲染节点,于是先怀疑服务器。
在服务器上查证:
ls /dev/dri/ # card0-4 + renderD128,存在
uname -r # 7.0.0-28-generic
getfacl /dev/dri/renderD128 # user:peter:rw-, mask rw-
服务器有 renderD128、ACL 正常、python 实测 open() 成功、gbm_create_device() 成功。服务器侧完全正常,排除。
第二轮误判:怀疑客户端没有 GPU 节点
服务器没问题,那按"两端缺一不可"的逻辑,报错应该发生在客户端——客户端 waypipe 进程要打开它自己那台机器的 /dev/dri/renderD128。于是推断"客户端机器有显卡但驱动没加载 render 节点"(比如 NVIDIA 没开 modeset=1、i915 模块被禁用等)。
但用户明确说:客户端是有 GPU 的。
而且注意一个拓扑干扰项:SSH 连接里看到的对端 IP 192.168.4.148 其实是 WireGuard 服务器(中间转发),不是客户端真机——这又增加了"客户端到底在哪"的混乱。实际上真正做 waypipe 客户端的机器是用户面前的物理机。
转向实测:报错到底来自哪一端
靠猜没用,直接实验定位报错来源。把两端 stderr 分开:
waypipe ssh workpc 'weston-dnd 2>/tmp/wp-server-err.log' 2>/tmp/wp-client-err.log
结果:
- 服务器端
/tmp/wp-server-err.log:空(weston-dnd 在服务器上没报任何错) - 客户端端
/tmp/wp-client-err.log:正是那两行 Iris 报错
报错文本来自客户端 waypipe 进程自身,不是服务器,也不是 weston-dnd。第一轮"服务器缺 GPU"彻底排除,且"客户端没有 renderD128"也被推翻了——因为客户端明明有:
ls /dev/dri/ # card0 + renderD128
lspci # Intel UHD 770 (Raptor Lake-S)
决定性一步:客户端 Mesa 其实全在软渲染
客户端 GPU 节点存在,但 iris 驱动本身可能有问题。用 glxinfo / eglinfo 看客户端 Mesa 实际用的渲染器:
glxinfo -B | grep -i renderer
# OpenGL renderer string: llvmpipe (LLVM 19.1.7, 256 bits)
关键发现:客户端所有 OpenGL 都是 llvmpipe(软件渲染),根本没有用 i915 硬件加速! 连 gnome-shell 桌面都在软渲染。
本地直接测 gbm_create_device() 也能复现那两行 Iris 报错(与 waypipe 无关):
python3 -c "import os,ctypes; ...gbm_create_device(os.open('/dev/dri/renderD128', os.O_RDWR))"
# error: Kernel is too old (4.16+ required) or unusable for Iris.
# gbm_create_device: OK ← 回退到 llvmpipe 后仍能创建设备
这说明:不是"没有 GPU 节点",而是"iris 驱动加载失败,Mesa 静默回退到 llvmpipe"。waypipe 的 GPU 通道坚持用 iris,失败后就把报错打出来。
真正根因:i915 GuC 固件缺失,GPU wedged
报错提示 "Check your dmesg logs",用 sudo 看内核日志:
sudo dmesg | grep -iE 'i915|xe|drm'
i915 0000:00:02.0: firmware: failed to load i915/tgl_guc_70.1.1.bin (-2)
i915 0000:00:02.0: [drm] *ERROR* GT0: GuC firmware i915/tgl_guc_70.bin: fetch failed -ENOENT
i915 0000:00:02.0: [drm] *ERROR* GT0: GuC initialization failed -ENOENT
i915 0000:00:02.0: [drm] *ERROR* GT0: Failed to initialize GPU, declaring it wedged!
根因锁定:客户端的 i915 驱动因为缺 GuC 固件初始化失败,GPU 被内核标记为 wedged(不可用)。 于是 Mesa 的 iris 驱动初始化失败 → 报 Kernel is too old (4.16+ required) or unusable for Iris → 回退 llvmpipe。
检查固件目录:
ls /lib/firmware/i915/ # 只有 dg2_dmc_ver2_07.bin,无 tgl_guc*
apt-file search tgl_guc # 属于 firmware-intel-graphics 包
apt-cache policy firmware-intel-graphics # 未安装
解决:安装固件包 + 重启
sudo apt install firmware-intel-graphics
sudo reboot # i915 被 Wayland 桌面会话占用,无法热卸载,必须重启
验证固件进入 initramfs(确保重启后能加载):
lsinitramfs /boot/initrd.img-$(uname -r) | grep tgl_guc
# usr/lib/firmware/i915/tgl_guc_70.bin ...
重启后预期:glxinfo -B 渲染器从 llvmpipe 变成 Mesa Intel(R) Raptor Lake-S,waypipe GPU 通道不再报错。
复盘:这次排查为什么被带偏
-
报错文本双来源混淆。
Failed to open drm fd是 waypipe 的,Kernel is too old for Iris是 Mesa 的——两者都指向"GPU 不可用",但一个让人联想到"缺节点/权限",一个让人联想到"内核太旧"。真正原因(GPU wedged)藏在 dmesg 里,不靠日志只看表象必然误判。 -
"两端缺一不可"的框架太粗糙。渲染节点存在 ≠ 驱动可用。客户端明明有
/dev/dri/renderD128,却因 iris 初始化失败实际不可用——ls /dev/dri根本看不出 GPU 是好的。判断 GPU 是否可用要看 Mesa 实际用什么渲染器(glxinfo -B)和内核日志(dmesg),而不是只看有没有节点文件。 -
网络拓扑干扰。WireGuard 中转让 SSH 对端 IP 显示为 WG 服务器而非客户端真机,一度让人纠结"客户端到底是哪台"。先厘清拓扑,再谈哪一端。
-
先分离两端 stderr 再下结论。
waypipe ssh host 'cmd 2>server.log' 2>client.log一次性把"报错来自客户端还是服务端"定死,避免了来回猜。
排查工具速查
| 想确认什么 | 命令 |
|---|---|
| 报错来自哪端 | waypipe ssh h 'cmd 2>s.log' 2>c.log 分别看两端 |
| GPU 是否真可用 | glxinfo -B | grep -i renderer(llvmpipe = 软渲染,坏) |
| 内核驱动状态 | sudo dmesg | grep -iE 'i915|xe|drm' |
| 渲染节点归属 | readlink /sys/class/drm/renderD128/device/driver |
| 固件是否齐全 | ls /lib/firmware/i915/、apt-file search tgl_guc |
| 固件是否进 initrd | lsinitramfs /boot/initrd.img-$(uname -r) | grep tgl_guc |
2026-08-16 复发补充:这次不是没装固件,是没重启 + 两端都要加 render 组
8 月 16 日同款症状再次出现(
waypipe ssh huawei-vm yad报 Iris + dmabuf 报错), 但这次排查方向完全不同,记录两个 08-09 版本没覆盖的坑。
症状
error: Kernel is too old (4.16+ required) or unusable for Iris.
S20933: 0.007984 [src/dmabuf.c:129] Failed to open drm fd for /dev/dri/renderD128: Permission denied
(yad:20929): Gdk-CRITICAL **: ... gdk_x11_window_get_xid: assertion 'GDK_IS_X11_WINDOW (window)' failed
注意 dmabuf 报错从 No such file or directory(08-09)变成了 Permission denied——上一轮修完的机器已无此问题,
本次报错来自另一台机器(waypipe 客户端,192.168.2.100)。照旧先分离两端 stderr 定位来源:
waypipe ssh huawei-vm 'yad 2>/tmp/wp-server-err.log' 2>/tmp/wp-client-err.log。
坑一:固件装了 ≠ 生效,wedged 状态只能重启恢复
客户端 dmesg 明明是 8 月 7 日开机时 tgl_guc_70.bin: fetch failed -ENOENT、GPU wedged,
但 firmware-intel-graphics 8 月 9 日已装好、lsinitramfs 也确认 tgl_guc_70.bin 已在 initrd 里——
对比时间线发现:开机(08-07 21:44)→ 装固件 + 重建 initramfs(08-09 22:16)→ 之后一直没重启。
i915 被 Wayland 桌面会话占用无法热卸载,wedged 状态从开机起就固定了,装再多固件也不影响已加载的驱动。
判断 GPU 是否真修好必须看当前会话的 glxinfo -B(llvmpipe = 还是坏的),而不是看 initrd 里有没有固件。
坑二:两端都要有 render 组权限,VM 内也要加
修复 Iris 后 dmabuf 报错仍在(Permission denied),客户端 usermod -aG render peter 后
报错消失一半——剩 Permission denied 转到了服务端 huawei-vm(VM 内 peter 只有 video 组,
/dev/dri/renderD128 属组是 render)。VM 内同样要加:
# VM 内(或经 qemu-guest-agent 以 root 执行)
usermod -aG render peter
# 组变更不作用于已登录会话,重新 ssh 即可;客户端侧同理
坑三:yad 的 Gdk-CRITICAL 是 wayland 下的无害断言
gdk_x11_window_get_xid: assertion 'GDK_IS_X11_WINDOW' failed 是 yad(GTK3)内部获取
X11 窗口 ID 的代码路径在 wayland 后端下触发的断言——窗口仍能正常弹出,忽略即可,不属于故障。
本次完整链路小结
Iris 报错(客户端)→ 固件在 initrd 里但没重启 → 重启
dmabuf Permission denied(客户端)→ usermod -aG render
dmabuf Permission denied(服务端 VM)→ VM 内同样 usermod -aG render
Gdk-CRITICAL → 无害,忽略
2026-08-26 复发补充:第三种形态——服务端就是 QXL,永远没有 renderD128
8 月 26 日同款报错再次出现(
cat ~/.ssh/id_ed25519.pub | clipcopy后终端刷出), 但与前两次排雷方向都不同:这一次没任何 GPU 问题是可修的,纯粹是拓扑+参数问题。
症状
blog % cat ~/.ssh/id_ed25519.pub | clipcopy
S45742: 56.574026 [src/dmabuf.c:125] Failed to open drm fd for /dev/dri/renderD128: No such file or directory
和前两次的关键区别:报错文本是 No such file or directory(08-09 同款文本),
而不是 08-16 的 Permission denied——这次不是"有节点但权限不足",而是节点本身不存在。
定位:服务端(目标机)是 QXL 虚拟显卡,无渲染节点
报错来自 waypipe 服务端,即本次 SSH 的目标机(his-host,192.168.2.156 虚拟机)。查:
ls /dev/dri/
# crw-rw---- 1 root video 226, 1 ... card1 ← 只有显示节点
# 无 renderD128 ← 没有渲染节点
lspci | grep -i vga
# 00:01.0 VGA compatible controller: Red Hat, Inc. QXL paravirtual graphic card
QXL 是纯 2D 的哑虚拟显卡(CPU 描画、无 3D 硬件),内核驱动本来就不注册渲染节点, 与 08-09/08-16 里"客户端机器有 renderD128 但驱动坏了/没权限"完全是两码事——这台机器永远不会有 renderD128, 再怎么装固件、加 render 组都没用(芯片没这功能)。CHANGELOG 里的待办"QXL → virtio-gpu 3D(virgl)" 就是给虚拟显卡模拟 3D 后,renderD128 才会出现。
(2026-09-13 更新:该 VM 已换成 virtio-vga-gl,renderD128 已出现,见文末收尾。)
复发的直接原因:会话没带 --no-gpu
08-09 的修复约定是客户端 waypipe --no-gpu ssh(禁用 GPU 协议、改走共享内存),
只要带了,即使服务端没渲染节点也不报错。但本次的 waypipe server 进程是 8/21 重建的会话,
看进程 cmdline 就知道客户端当时没用 --no-gpu(若带了,server 侧命令会带 -n):
waypipe -c lz4 --login-shell --unlink-socket -s /tmp waypipe-server-...
于是剪贴板复制时服务端照样尝试 dmabuf 直传 → 打开 /dev/dri/renderD128 → No such file。
repo 里两份"入口文档"仍写着不带 --no-gpu 的旧命令,这正是复发温床:
dotfiles/.cheat/waypipe.:waypipe ssh -o controlpath=none peter@<旧IP>(无 --no-gpu,IP 还是 192.168.7.99)- IP 也已变(192.168.7.99 → 192.168.2.156),旧会话是照着旧 cheat 连的
三种形态判别速查
| 报错文本 | 含义 | 方向 |
|---|---|---|
No such file or directory | 打开 renderD128 时节点不存在 | 该端是 2D-only 卡(QXL/virtio-gpu 2D/bochs),只能 --no-gpu |
Permission denied | 节点存在但用户无权限 | 该端 usermod -aG render(重新 ssh 生效) |
Kernel is too old ... for Iris | 设备存在但驱动初始化失败(GPU wedged) | 查 dmesg:装固件 + 重启 |
本次修复
- 客户端重连会话,用
waypipe --no-gpu ssh -o controlpath=none peter@192.168.2.156(连着旧会话的窗口重开) - 顺手更新
dotfiles/.cheat/waypipe.为带--no-gpu的新命令 - 长期:VM 升级 virgl(virtio-gpu 3D)后 renderD128 出现,届时才可去掉
--no-gpu(2026-09-13 已完成,见下)
2026-09-13 收尾:renderD128 已出现
his-host 已完成 QXL → virtio-vga-gl 迁移(实测过程见 工具链迁移 Wayland 的「根治方案」章节):
ls /dev/dri/ # card1 + renderD128
dmesg | grep -i virgl
# [drm] features: +virgl +edid -resource_blob -host_visible
本文三种形态至此全部闭环:客户端 Iris(固件/重启)、两端 render 组权限、服务端 QXL 无渲染节点(迁移解决)。本机 waypipe 隧道可以去掉 --no-gpu 了(已建立的隧道要重连才生效)。