我最近遇到了Linux 空块设备驱动程序,,null_blk
同时我对 I/O 堆栈进行基准测试,而不是在特定的块设备上进行基准测试。我发现在此驱动程序下创建的设备(让我们使用设备名称/dev/nullb0
作为示例)非常有趣,特别是考虑到它们的名称与/dev/null
设备的相似性。由于我在 Stackoverflow 上找不到有关该主题的任何现有问题,因此我决定寻求澄清。
我的主要问题是:/dev/null
和设备驱动下创建的块设备有什么区别null_blk
?
到目前为止:我已经注意到了一些区别。
- 首先,(据我了解),空设备
/dev/null
不经过任何驱动程序。但是,在其下创建的设备null_blk
是数据必须经过的真正的块驱动程序。我还通过fio
在两台设备上运行来证实了这一点;/dev/null
在随机读取 IOPS 和提交延迟方面表现更好。 - 其次,我们知道读取
/dev/null
会产生 EOF(例如,cat /dev/null
),但当我尝试 时cat /dev/nullb0
,它不会返回 EOF 而是挂起。 - 此外,作为旁注,内核文档提到了
null_blk
配置参数,但我没有看到任何类似的/dev/null
配置选项。
看来,相似的名字下却存在着很大的差异。有人可以对这些差异提供进一步的正式见解或澄清吗?谢谢!
答案1
答案2
/dev/null
是一个“字符设备”,所有读取都返回空,所有写入完全完成,没有额外的副作用。这些是自 1974 年 V5 UNIX 以来的语义,并且由 POSIX 强制执行 - 没有任何参数可以对其进行参数化。
驱动程序创建的设备null_blk
是“块设备”,这意味着它们具有固定的大小和缓存含义。提供的设备null_blk
忽略所有写入并返回所有零,使它们更像/dev/zero
.
的目的/dev/null
和提供的设备null_blk
是不同的:/dev/null
经过极其优化,返回 0(用于读取)或写入大小(用于写入),因为这就是它所做的一切。相反,每文档,null_blk
用于对各种块层实现进行基准测试
这意味着它会执行相关的 I/O 请求管理代码,就像请求是真实的一样,并且只有那时将请求标记为已完成,而不实际执行任何读/写操作。这意味着每个请求需要做更多的工作/dev/null
,并解释了您的fio
结果。