Rust 接棒 C 语言 :Rust for Linux 中正在发生的技术变革
Linus :选择 Rust 的原因之一是让 Linux 内核社区融入新鲜血液
“在近日日本举办的 开源峰会(OSS Japan )上,Linux和Git的创造者Linus Torvalds与Verizon开源项目办公室负责人Dirk Hohndel的对话视频[1] 中谈到 Rust ,这里摘录相关对话,为听译总结性记录,如果有误敬请指正,括号中内容为本人插入个人点评。
Dirk: 你如何看待目前 Rust 在 Linux 中的位置?
Linus: 我们有在去年合并了 Rust 初始基础设施,它一直在不断增长,但是内核还没有真正依赖它的部分。但 Rust 对我来说,更重要的是,作为内核和开发人员,我们并没有停滞不前。我总是因为尝试新事物而感到兴奋。目前 Rust 并没有真正释放出它的能力,但是我认为明年(2024)我们实际上会开始会积极使用 Rust 来集成驱动程序甚至一些主要的子系统(Major Subsystems),所以这需要数年时间的积累才能让 Rust 成为内核的重要组成部分,Rust 肯定会成为其中之一。
Drik: 所以你在写 Rust 代码吗?你正在审查 Rust 代码。
Linus: 我一直在阅读(审查)Rust 代码,以便其中包含了某种可怕的事情,我需要做出判断。但我必须承认,我们依赖的内核每个版本都有数千人参与。但这数千人中的大部分人只是为了解决自己关注的问题而提交小补丁给内核。当谈到 Rust 时,我其实不会成为管理 Rust 代码的人,我称我自己是 技术主管,我的日常工作不是编程,而是合并代码,当然也会包括 Rust 代码。
“这次访谈中提到了20年前 Linus 朝屏幕竖中指吐槽 NAVIDA 驱动那张流传甚广的照片,Linus 称不会再这样了,20年其实有了很大变化,相比当年的Linux硬件驱动和文档缺乏的情况现在已经好多了。
Drik: 如何改善 Linux 维护者整体“疲软”的问题?
Linus: 找到开发者很容易,但是找到维护者很难。作为维护者,并不是指那种全能的超级开发者,而是可以判断其他人的代码,并且其中一些可能是需要在一个项目锻炼很多年才能成为维护者。这么多年来,我们有很多优秀的维护者,但是问题是,你必须一直寻找其他维护者,以便我们可以度假。几个月前我在度假的时候我还带着我的笔记本,如果我没有带笔记本我就会感到无聊,因为我喜欢做我现在做的事情。但是我意识到这不是生活,尤其是当你必须为此投入多年的生命时。对于维护者的问题,我们一直没有解决。
Drik: 现在 Linux 内核的核心维护者们,确实已经严重老化,随着时间推移,这些人年龄会越来越大。所以你认为会发生什么?
Linus: 我们的维护者们头发确实在不断变白,每年的维护者峰会大约有 30 人参加,这 30 人中有 3 个人已经存在超过 30 年了。所以,他们在 Linux 诞生第一年就已经在了。他们的头发确实已经灰白了,但是这也意味着 Linux 社区确实会让一些人留下来。
Drik: 但这(年龄)绝对是一个双刃剑。
Linus: 绝对是。所以我喜欢 Rust 进入内核的一个原因是,新的 Rust 维护者显然比大多数维护者年轻得多。我们可以清楚地看到某些内核的区域在吸引更多的年轻人。拿文件系统维护者来说,因为文件系统如果出了问题,用户的数据可能会消失,所以文件系统维护者会非常小心地编写他们的代码,保证 100% 正确。所以这方面比驱动的维护者来说更好一些,尤其是 GPU 驱动(玩梗)。在驱动方面,你可以更容易地找到年轻人。
下面是关于 Linus 如何看待大语言模型和 AI 辅助编程的问题。
Drik: 你认为你会在 Linux 提交的代码中看到大模型生成的代码吗?
Linus: 我认为这件事很可能已经发生了。也许人们是在一个更小的代码规模上使用它来辅助编码。但是很明显,自动化一直在帮助人们。我的意思是,这根本不是什么新鲜事。我们不写机器代码,不写汇编,是因为我们用 C 语言代替了它们,现在又用 Rust 代替 C。所以我不认为它(用 AI 生成代码)是一件革命性的事。每天的新闻都是关于人工智能的,这显然不是我的工作领域。我依然喜欢底层硬件细节,这就是为什么我还在 Linux 内核工作。
Drik: 你认为大模型能达到可以帮助你们审查代码的程度吗?以便解决前面提到的维护者持续性的问题。
Linus: 我希望如此。我希望大模型真正发光发热的能力是帮助我们找出那些明显的愚蠢的错误,因为我也写了很多 Bug ,也看到很多其他人的 Bug,我发现大部分 Bug 只是你没有想到的愚蠢错误,这些错误并不是需要依赖任何更高的智能才能找到他们。但是如果有一些工具,比如编译器的警告(如 Rust 编译器在这方面做的很好),能提示我们就很好,大模型也许可以警告更微妙的错误,只是这种模式可能不像我们日常编码的常规模式。我认为大模型可以帮助我们做的更好,我一直很乐观, Hopeful 是我的中间名(笑)。
Drik: 但是听说大模型还存在很多幻觉问题,这些幻觉会影响我们的生成的代码很生活吗?
Linus: 我觉得无所谓,反正没有大模型我们也会每天写出 Bug 。
Rust for Linux 维护者峰会中关于 Rust 的深入讨论
在 11 月的内核峰会上,Airlie(Dave Airlie,DRM 图形子系统维护者)指出,目前 Rust 的发展受到了一种先有鸡还是先有蛋的困境的影响。在没有用户的情况下,相关的抽象层无法被合并,而同时,依赖这些抽象层的代码又在多个子系统中陷入等待。因此,Rust 开发人员不得不依赖大量的补丁来保证代码的正常运作。要打破这种僵局,有必要允许一些尚无立即用户的抽象层被合并进来。Ojeda(Rust for Linux 的核心开发者)同意这个问题一直在阻碍进展,但他尽量避免向维护者施加合并代码的压力。具有讽刺意味的是,网络方面的Rust 开发人员不得不要求网络维护者放慢合并 Rust 代码的步伐[2]。
Greg Kroah-Hartman 表示,合并 binder 驱动程序将是一个很好的下一步;这是一个独立的模块,拥有单一的、致力于其维护的用户群,并且不会影响内核的其他部分。Dave Chinner 对维护者是否具备审查新合并抽象层所需的专业知识表示担忧。Airlie 回应说,现在的维护者们已经合并了许多 C API,但并不真正理解它们的工作原理。尽管在这个过程中犯了很多错误,但“我们还在这里”。一旦发现错误,就可以对其进行修复,如果代码已经进入上游,修复过程将更为迅速。
Ted Ts'o 对引入 Rust 代码给维护者带来的额外负担表示担忧。他指出,Rust 开发者正在设定比过去更高的标准。确实,合并高质量的抽象层很重要,但谁来负责审查驱动程序,以及如何处理整个代码树的变化呢?他强调,Rust 的发展正在影响着社区日渐扩大的一部分。
Hellwig 指出,真正的问题在于 Rust 绑定和提供的抽象层与现有的 C API 工作方式不同;新的 API 可能更加高效,但它们仍然是全新的 API。他认为,应首先修复 C API,使其可以被 Rust 代码直接使用。他建议,在考虑引入 Rust 代码的每个子系统中,应先花一两年时间清理其 API。Ojeda 表示,这种 API 改进已经在一些子系统中发生。
Linus Torvalds 提到,他注意到文件系统和驱动程序维护者之间存在分歧。文件系统的开发人员通常更加保守,而驱动程序领域则更像是“西部荒野”。他指出,驱动程序的开发者往往不理解并发性,那里的很多代码都是有问题的,且难以修复。因此,引入一种更好地支持编写正确和安全代码的语言显得尤为重要。
Brauner 表示,Rust 可以帮助解决许多问题,因为编译器可以阻止许多错误进入内核。但他同时担忧,几年后是否仍会有维护和开发支持。Airlie 再次提到,需要 Rust 代码的外部代码开发者;Cook 回答说,管理该代码的人将成为新的维护者,他们的引入将带来新的维护责任。Airlie 补充说,这些新维护者正是内核社区希望吸引的年轻开发人员。
Chinner 表示,他希望看到 ext2 文件系统在 Rust 中被重新实现。它是一个完整的文件系统,广泛使用内核的 API,但足够小以便于阅读和理解。如果 Rust 的 API 能够支持 ext2 的实现,那么它们也应足以支持其他文件系统。同时,ext2 的实现将成为维护者的良好参考,他们可以将其与 C 版本进行比较。
Airlie 表示,他正在考虑为一个现有的 C 驱动程序实现一个虚拟图形驱动程序。他还提到了适用于 Apple M1 GPU 的驱动程序。他感受到了相当大的压力,并希望看到对 NVIDIA GPU 的 Nouveau 驱动程序进行重写(实际上,Nouveau 驱动后端编译器已经用 Rust 重写了)。
Arnd Bergmann 指出,工具链尚未准备好广泛支持 Rust 驱动程序的开发。他提到了内核频繁版本升级的问题,指出内核 6.7 已经升级到了 Rust 1.73.0 版本。他表示,一旦内核所依赖的关键功能稳定下来,升级过程最终将停止,并将设定一个最低的 Rust 版本。他还强调,他一直在努力将内核代码纳入 Rust 的持续集成测试中,以确保它在编译器和语言演变时仍然正常工作。Bergmann 表示,直到 Rust 可以使用 GCC 进行编译(GCC Rust 前端仍在开发中),他才会认真研究 Rust 语言。
总结:内核社区是否真正决定全力支持 Rust 还有待观察;但几乎可以确定的是,不久的将来会有 PR 提交大量的 Rust 代码。
Rust 代码审查与网络开发节奏的冲突
上文说到,在网络方面,Rust 开发人员不得不要求网络维护者减慢合并 Rust 代码的速度[3]。
具体情况是,目前 Tomonori Fujita 正在为物理层(PHY)驱动程序添加一些 Rust 抽象。已经进行了大量的审查,并且根据这些审查意见频繁地重新制定了补丁集。不幸的是,Rust-for-Linux 开发人员在跟上这个速度方面遇到了困难。两个社区的开发实践似乎存在一些脱节。
Andrew Lunn(该补丁的审查者)指出,网络补丁不需要经过审核就可以合并;“如果在三天内没有反馈,并且通过了CI(持续集成)测试,那么很可能会被合并。”但 Ojeda (Rust for Linux 核心开发者)表示,CI 测试无法确定抽象是否经过良好和合理的设计,这是 Rust 抽象(重点是安全抽象)所需的关键属性;他希望有人参与其中。Lunn 回答说,最终是人决定是否合并代码,但 API 问题只是像其他 bug 一样,如果发现问题,可以稍后修复。
“我是认同 Ojeda 的观点。因为Rust 抽象,尤其是 Unsafe Rust 安全抽象是需要专门设计的;但是 Linux 中某些模块开发和合并速度太快,人手严重不足,以及 C 那边的人认为 API 后面修改也可以,这是有误解的。其实 Rust 安全抽象在后面修改就已经来不及了,必须在前期就为其做好安全抽象。
然而,网络维护者Jakub Kicinski 表示, "更长的审查周期将使跟踪补丁和讨论变得难以管理。" 他想知道在初始阶段之后,Rust-for-Linux 项目是否会减少对补丁审查的参与。Ojeda 同意这是目标,但初始的抽象集将需要更多的审查时间。
Ojeda 说,还需要花一些时间来“让人们对 Rust 代码和抽象有一个共同的期望”。除了代码的设计和逻辑之外,格式也是需要解决的一部分。Lunn 在他的 Review 中指出的一个问题是最大行长度,这只是一个“微不足道的例子”。Ojeda 表示,Rust-for-Linux 项目希望在整个内核中为其代码提供一致的格式,希望能够以自动化的方式进行维护,因此如果可能的话,这些差异需要在整个内核中解决。计划是提供一个坚实的基础,以便网络开发人员“实际上可以迅速处理任何补丁,而不必等待我们”-但这需要一些时间才能实现。
Ojeda 似乎坚决认为Rust代码在整个内核中将保持一致的格式,这与现有的 C 代码(缺乏)一致性不同。随着时间的推移,我们将看到这将如何发挥作用。讨论突显了当两个不同的开发社区“碰撞”时需要解决的一些问题。PHY抽象和使用它们的驱动程序将是第一个对驱动程序编写者和普通用户都可见的Rust内核特性,因此开发人员想要花时间确保它正确。
Linux的开发速度远远快于大多数其他开发项目,这对于内核Rust项目来说可能过于迅速,至少在目前阶段是如此。另一方面,正如Lunn所指出的,Rust的API并不是必须固定不变的,它们是内核的一部分,因此可以像其他内核API一样进行更改。人们可以感觉到这两个项目将会找到一个对双方都适用的平衡点。
后记
Rust 接棒 C 语言,正在 Rust for Linux 中悄然开启。语言的转换背后,是新一代开发者接棒老一代开发者。相信 Linus 找到了合适的语言,让 Linux 社区持续繁荣。但我们也看到 Rust 接棒 C 还面临很多问题,主要的问题是 Rust 和 C 两个不同的语言社区的开发习惯和思维的冲突,这个问题肯定会被解决,这也是我关注 Rust for Linux 社区的一个原因,这样新旧交替的冲突很精彩。
其实除了 Rust for Linux ,Google 和 Microsoft 也对 Rust 有很大的投入。去年 Google 在安卓 13 中已经取得了内存安全成果。今年 11 月微软安全主管在 Twitter 上面宣布[4],微软将投入1000万美元使其成为其工程系统中的一流语言,并额外投入100万美元用于 Rust 基金会。虽然也有认为 1000 万美元对于微软每年的研发费用来说并不算什么,但是这足以说明微软投入 Rust 的决心了。根据 Reddit 上面微软工程师对此事的评论发现,微软 Win32k Rust 工作组的人员一直在和 Linux 工程师合作,共同探索如何在内核模式下使用 Rust,尤其是 fallible allocation(即,内存分配时不会导致 Panic)[5] 方面。
“微软现在也是一家 Linux 公司,实锤!
近日,又看到国际五眼联盟机构(Five Eyes agencies urge)督促放弃或减少使用 C++ 编程语言,建议优先选择 Rust[6]的一份报告,这说明五眼联盟的五个国家的情报机构在推动这一变化。这可能与国家安全、软件安全性和信息保护有关,表明这些建议有着重要的安全考虑背景。该报告中表明,需要彻底消除内存安全错误。这一点,Google 的安卓中取得的内存安全成果让我们看到了这个可能性。所以,彻底消除内存安全会成为未来五年世界软件巨头的共识。
“五眼(英语:Five Eyes,缩写为 FVEY),又译为五眼联盟,是由五个英语圈国家所组成的情报联盟,在英美协定下组成的国际情报分享团体,成员国包括澳大利亚、加拿大、纽西兰、英国和美国。
国内 Rust 也在逐渐落地。今年华为在 OpenHarmony 中已经开始落地 Rust,华为内部也在大力推进 Rust 的更大范围落地。一些工业和科研领域也开始使用 Rust ,比如理想汽车、鹏城实验室的芯片设计开源 EDA 工具也逐步开始使用 Rust 。今天也听闻这两天成功发射的天仪33卫星载荷采用了北京邮电大学自主研发的基于Rust的双内核实时操作系统RROS,并成功收到了遥测数据。我相信 Rust 语言在国内也会逐步成为系统语言的首选。
参考资料
Linux和Git的创造者Linus Torvalds与Verizon开源项目办公室负责人Dirk Hohndel的对话视频: https://www.youtube.com/watch?v=OvuEYtkOH88&t=336s
[2]Rust 开发人员不得不要求网络维护者放慢合并 Rust 代码的步伐: https://lwn.net/Articles/949270/
[3]Rust 开发人员不得不要求网络维护者减慢合并 Rust 代码的速度: https://lwn.net/Articles/949270/
[4]今年 11 月微软安全主管在 Twitter 上面宣布: https://x.com/dwizzzleMSFT/status/1720134540822520268?s=20
[5]fallible allocation(即,内存分配时不会导致 Panic): https://crates.io/crates/fallible_vec
[6]五眼联盟机构(Five Eyes agencies urge)督促放弃或减少使用 C++ 编程语言,建议优先选择 Rust: https://www.theregister.com/2023/12/07/memory_correction_five_eyes/?td=rt-3a