在用户空间中编写文件系统驱动程序是不是比在内核空间中更容易?

Posted

技术标签:

【中文标题】在用户空间中编写文件系统驱动程序是不是比在内核空间中更容易?【英文标题】:Is it easier to write filesystem drivers in userspace than in kernel space?在用户空间中编写文件系统驱动程序是否比在内核空间中更容易? 【发布时间】:2011-02-17 22:04:41 【问题描述】:

我将以 Linux NTFS 驱动为例。

Linux 内核 NTFS 驱动程序仅在内核中提供非常有限的写入支持,5 年后仍被认为是实验性的。

同一开发团队创建了 ntfsmount 用户空间驱动程序,具有几乎完美的写入支持。

同样,由不同团队编写的 NTFS-3G 项目也有近乎完美的写入支持。

为什么内核驱动器需要这么长时间?开发难度更大吗?

说已经存在一个像样的用户空间应用程序并不是内核驱动程序不强制的原因。

注意:不要将此迁移到 superuser.com。从编程的角度来看,我想要一个编程重的答案,而不是实际使用的答案。如果这个问题不适合 SO,请告诉我为什么这样我可以编辑它。

【问题讨论】:

拥有内核驱动程序有什么好处? 速度,不依赖第三方软件... 【参考方案1】:

我不知道 NTFS linux 驱动程序开发的内幕,但我可以想象一些事情会使用户空间的开发比内核空间的开发更快:

更简单的 API - 用户态库(例如内存管理)提供的更高层次的抽象无疑简化了开发 更容易调试 - 调试用户空间进程比调试内核更容易 进程隔离 - 这是我要说的一件事,它负责加快用户空间的开发。您的用户空间文件系统驱动程序做坏事在最坏的情况下会导致文件系统损坏并且您的驱动程序进程死亡,而在内核空间中则可能导致整个系统崩溃。这会导致更快的调试周期,从而导致整体开发速度越来越快地处理错误。

【讨论】:

【参考方案2】:

需要注意的是,特别是对于 Linux,experimental 也可能意味着“有人丢弃在这里的代码,当时看起来可以接受,但可能没有得到积极维护”。

我非常喜欢将文件系统保存在用户空间中,但我也应该指出我是一个大microkernel enthusiast。我发现将文件系统保留在用户空间中是实用且可取的,原因如下:

用户空间文件系统更易于维护

花点时间看看ext3cow file system,这是一个在很短的时间内就获得了相当大的关注的 PHD 项目。它的作者毕业了,然后开始了职业生涯,几乎没有时间研究文件系统。由于它是树外的,Linux 在不同版本之间不断变化的内部结构要求任何想要在现代内核上使用它的人都拥有很多人不具备的深入知识。

如果它使用 FUSE API,它会更容易维护,并且将 ext3 转换为写入文件系统的副本的实际工作将获得更多曝光。这也与积累霉菌的内核代码有关,因为没有人足够勇敢(或足够无聊)去触摸它。

用户空间文件系统更容易调试

在用户空间中,您拥有非常棒的工具,例如 Valgrind(以及它的朋友,例如 massif),它们是非常宝贵且易于使用的工具。与内核调试相关的学习曲线对于许多人来说通常太长而无法直接进入并编写代码。请注意,我明确区分了 FUSE 和微内核架构,如 in this answer 所述。一些基于微内核的系统非常难以调试,主要是由于正在运行的服务(vfs、块设备、文件系统、ipc)之间的通信竞争。在这两种情况下,代码都更容易调试,因为它在内核之外,前提是它在内核之外不会引入奇怪的复杂性。

无论如何,我将在任何一天使用 GDB 和 Valgrind 进行嘈杂的printk() 调试,或者尝试从 Linux 中存在的相当神秘的内核调试钩子中弄清楚。我还将享受使用我选择的任何调试(甚至garbage collecting)malloc() 实现的能力。我选择的 C 库也是如此,前提是它可以与 FUSE 一起使用。我没有拒绝 Linux 的内核库,但我喜欢我的物质享受。

用户空间文件系统更易于使用

对于弱势用户来说,能够挂载和维护他们想要使用的任何文件系统是一个很大的好处,但这实际上是最终的结果。如果您的文件系统在内核之外,它可以独立于内核前进,这意味着用户可以升级调整到您的 发布周期。可以想象,在 Linux 升级到下一个候选版本所需的时间内,您可以实现 6 个里程碑版本。这也允许发行版和 OEM 供应商将您的 FS 放到野外,它可以比内核模块更快地获得所需的测试。

Norman Ramsey already described 与文件系统相关的可靠性因素,即微内核架构中的服务。但是,可靠性意味着不需要需要一种倾向于隐藏(或推迟)错误和其他问题的轮回服务。我确实同意这样的观点,即如果失败的根挂载不会引发内核中止,这很好,但是这对于启用 FUSE 的单片内核也是可能的。

总而言之,编写一个文件系统已经够难了,而不必处理在内核空间中运行的问题。我更愿意使用 FUSE API,或者研究基于微内核的操作系统中的 IPC / VFS 服务实现,而不是将其编写为内核模块。

【讨论】:

【参考方案3】:

内核代码必须满足比用户模式代码更高的安全性和安全性(即无错误)标准。

【讨论】:

同意,当有人认为投反对票是不言而喻的批评时,这很难说... 可能因为内核 ntfs 驱动比用户空间驱动差。【参考方案4】:

您可以在用户空间使用更多好东西,因此开发软件更容易。如果文件系统位于用户空间,文件系统中的故障就更难导致整个内核崩溃。

这一原则在Mach 和Windows NT 等项目中发挥到了极致,其中系统设计为microkernel,并在用户空间中放置了尽可能多的服务。

【讨论】:

值得注意的是,除非经过深思熟虑,否则服务之间的 IPC 调用将成为调试和性能瓶颈的主要难题。例如,GNU HURD 是在与 Mach 结婚后才发现这一点的,他们现在正在努力纠正这个错误。 虽然 NT 在架构上是一个微内核,但它通常不会被考虑一次,因为出于性能原因,许多不严格属于内核的服务仍处于内核模式(最值得注意的是,例如窗口管理器) ) 我希望开发可以在用户空间运行的文件系统会比开发与内核集成的文件系统更容易。另一方面,我也希望内核有 a 文件系统可用于诸如独立于用户模式任务的分页之类的事情也会有所帮助。系统是否有一个用于引导/交换磁盘的内核模式文件系统和用于其他目的的用户模式?

以上是关于在用户空间中编写文件系统驱动程序是不是比在内核空间中更容易?的主要内容,如果未能解决你的问题,请参考以下文章

mmap() 在内核空间和用户空间中是不是相同?

Linux内核目录文件和最新内核版本升级

再学零拷贝与mmap

6 io

用户空间驱动

用户空间驱动