技术知识库

设备节点缺失或设备号失配导致 FASYNC 测试失败

设备节点缺失或设备号失配导致 FASYNC 测试失败

摘要

FASYNC 测试程序最初先后报 No such file or directory 和 No such device or address。前者是 /dev/mydemo0 尚未创建;后者是节点虽然存在,但模块已卸载或节点保存的主设备号与本次动态分配结果不一致。加载模块、从 /proc/devices 查询真实主设备号并重建设备节点后,FASYNC 实验验证成功。

环境

内核:Linux 5.0.0+ ARM64
模块:mydemo_fasync.ko
测试程序:test
测试程序打开路径:/dev/mydemo0
驱动注册名:mydemo_dev

现象一:ENOENT

./test
fasync test: No such file or directory

test ELF 已经成功执行;文本前缀来自程序的 perror("fasync test")。失败的是:

open("/dev/mydemo0", O_RDWR);

驱动只调用 alloc_chrdev_region() 和 cdev_add(),没有调用 class_create()、device_create(),所以不会自动生成节点。

现象二:ENXIO

手动创建 247:0 节点后出现:

fasync test: No such device or address

当时 /proc/devices 中没有 mydemo_dev,说明模块已经卸载;或者节点里的 247 不是当前模块的动态主设备号。设备节点只是一个保存 major:minor 的入口,名字存在不代表背后仍有对应 cdev。

修复步骤

先加载模块:

insmod ./mydemo_fasync.ko

查询本次真实设备号:

grep -w mydemo_dev /proc/devices

若旧节点存在,删除并按实际号码重建:

rm /dev/mydemo0
mknod /dev/mydemo0 c 247 0
chmod 666 /dev/mydemo0
ls -l /dev/mydemo0

这里的 247 是本次实际结果,不是驱动的固定主设备号。以后重新加载仍应再次查询。

验证结果

demodrv_open: major=247, minor=0, device=mydemo_dev0
demodrv_write kill fasync
demodrv_write:mydemo_dev0 pid=315, actual_write =13
demodrv_read:mydemo_dev0, pid=389, actual_readed=13

设备节点、cdev 和 FASYNC 数据路径均已接通。

结论

  • ENOENT:路径不存在。
  • ENXIO:路径存在,但 major:minor 没有当前有效的字符设备实现。
  • chmod 只修改权限,不能修复设备号或重新注册驱动。
  • mknod: File exists 只表示路径冲突,不证明节点有效。

关联

待验证

  • 无;故障已修复并完成 FASYNC 实际验证。