为什么 Linux NFS 服务器在内核中实现,而不是在用户空间中实现?

为什么 Linux NFS 服务器在内核中实现,而不是在用户空间中实现?

我只是想知道为什么 Linux NFS 服务器是在内核中实现的,而不是在用户空间应用程序中实现的?

我认识一个用户空间 NFS 守护进程存在,但它不是提供 NFS 服务器服务的标准方法。

我认为将 NFS 服务器作为用户空间应用程序运行将是首选方法,因为它可以通过在用户空间而不是内核中运行守护程序来提供额外的安全性。它还符合 Linux 的常见原则:只做一件事并做好它(并且守护进程不应该成为内核的工作)。
事实上,我能想到的在内核中运行的唯一好处是上下文切换带来的性能提升(这是一个有争议的原因)。

那么,是否有任何有记录的原因说明为什么要这样实施呢?我尝试用谷歌搜索但找不到任何东西。


似乎有很多混乱,请注意,我不是在询问有关安装文件系统的问题,而是在询问有关提供网络文件系统的服务器端。有一个非常明显的区别。在本地挂载文件系统需要内核支持该文件系统,前提是它不支持(例如 samba 或 unfs3)。

答案1

unfs3据我所知已经死了;甘尼萨是目前最活跃的用户空间 NFS 服务器项目,尽管它还没有完全成熟。

尽管 Samba 服务于不同的协议,但它是在用户空间中运行的成功文件服务器的一个示例。

我还没有看到最近的性能比较。

其他一些问题:

  • 普通应用程序通过路径名查找文件,但nfsd需要能够通过文件句柄查找它们。这很棘手,需要文件系统的支持(并非所有文件系统都可以支持它)。在过去,不可能从用户空间执行此操作,但最近的内核添加了 系统调用name_to_handle_at(2)open_by_handle_at(2)
  • 我似乎记得阻止文件锁定调用是一个问题;我不确定用户空间服务器现在如何处理它们。 (你是占用等待锁的服务器线程,还是进行轮询?)
  • 较新的文件系统语义(更改属性、委托、共享锁)可能首先在内核中更容易实现(理论上——它们大多还没有实现)。
  • 您不想手动检查权限、配额等,而是希望更改您的 uid 并依赖通用内核 vfs 代码来完成此操作。 Linux 有一个系统调用 ( setfsuid(2)) 可以做到这一点。由于我忘记的原因,我认为事实证明在服务器中使用它比应有的要复杂。

一般来说,内核服务器的优势是与 vfs 和导出的文件系统更紧密的集成。我们可以通过提供更多的内核接口(例如文件句柄系统调用)来弥补这一点,但这并不容易。另一方面,现在人们想要导出的一些文件系统(例如 gluster)实际上主要存在于用户空间中。这些可以由内核 nfsd 使用 FUSE 导出——但同样,更新的功能可能需要对 FUSE 接口进行扩展,并且可能存在性能问题。

简短版:好问题!

答案2

Olaf Kirch 最初开发了 NFS 服务器的用户空间和基于内核的版本。他在 2000 年出版的《Linux 网络管理》一书中说道:

2.2.0 内核支持由 Olaf Kirch 开发并由 HJ Lu、G. Allan Morris 和 Trond Myklebust 进一步开发的基于实验性内核的 NFS 服务器。基于内核的 NFS 支持显着提高了服务器性能。

我认为,一旦 NFS 服务器被移入内核以提高性能,就没有人认为有任何理由再次将其取出。

答案3

Starnamer 是正确的(我是 Beta 测试人员之一)。

将其放入内核是为了改善糟糕的性能(主要是针对 PCNFS 客户端),一旦该问题得到解决,就没有人再关注它了。

在内核中使用 NFS 有许多缺陷,其中最重要的是它不能很好地与接触同一文件系统的其他任何东西一起使用(存在严重的腐败风险),但当时(1993-4)我们没有没有意识到这会成为一个问题。

我们更年轻,更愚蠢,等等。

答案4

第 3 条这些幻灯片讨论内核空间与用户空间 NFS 服务器实现。本演示有利于 NFS 服务器的用户空间实现(NFS-Ganesha 就是这么做的)

另一方面,有一篇深入探讨的博客文章这里显示内核空间实现速度要快得多。

那么为什么是内核空间:简短的答案是更好的性能。

相关内容