技术知识库

dd 测试非阻塞写时误用了 iflag

dd 测试非阻塞写时误用了 iflag

摘要

满 FIFO 的测试最初仍得到 No space left on device,似乎没有进入 O_NONBLOCK 分支。根因不是驱动判断失败,而是命令使用了 iflag=nonblock:它只让输入文件 /dev/zero 非阻塞,输出设备仍按普通方式打开。改为 oflag=nonblock 后,驱动返回 -EAGAIN,用户空间显示 Resource temporarily unavailable。

问题/背景

最初命令:

dd \
  if=/dev/zero \
  of=/dev/kfifo_mailbox \
  iflag=nonblock \
  bs=1024 \
  count=100

实际结果:

dd: error writing '/dev/kfifo_mailbox': No space left on device

根因

dd 的标志按数据方向分别生效:

iflag → if= 指定的输入文件
oflag → of= 指定的输出文件

本次设备位于 of=/dev/kfifo_mailbox,因此只有 oflag=nonblock 才会让设备对应的 struct file::f_flags 包含 O_NONBLOCK。

最终修复

printf X |
  dd \
    of=/dev/kfifo_mailbox \
    oflag=nonblock \
    bs=1 \
    count=1 \
    status=none

验证结果

dd: error writing '/dev/kfifo_mailbox': Resource temporarily unavailable
status=1

Resource temporarily unavailable 对应内核返回的 -EAGAIN,非阻塞写分支验证成功。

证据与来源

  • 本轮 ARM64 Guest 的 dd 实际输出。
  • GNU dd 的 iflag/oflag 参数方向。
  • 驱动中的 file->f_flags & O_NONBLOCK 判断。

关联

待验证

  • 无;非阻塞写已用 oflag=nonblock 验证通过。