`/dev/null` 和 `null_blk` 驱动下的设备之间的差异

`/dev/null` 和 `null_blk` 驱动下的设备之间的差异

我最近遇到了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

/dev/null 由设备驱动程序处理,但是这是一个非常简单的

/dev/null和 的主要区别在于null_blk前者是字符设备,后者是块设备。前者处理字符序列直接实现由使用它的程序调用的操作,在使用设备的系统调用和在驱动程序中实现相应操作的代码之间没有太多间接。后者更复杂,并在整个扇区上运行,支持命令队列等。处理任何单个请求还有更多的事情要做。

当然,目的也有一个主要区别:/dev/null旨在实际直接使用,而它null_blk是为想要对块设备处理堆栈的其他部分进行基准测试的内核开发人员提供的支持功能。

答案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结果。

相关内容