LWN:Rust 开发者们要入侵啦!

Rust语言正在逐步进入Linux内核开发,虽然尚不确定何时会被主线接纳。最新的Rust补丁集增加了大量代码,引入了硬件随机数生成器访问、C字符串类型以及改进的spinlock实现。然而,Rust与内核社区的文化冲突和依赖管理问题成为挑战。一些开发者呼吁采用Rust的包管理工具,但内核开发者坚持控制外部依赖以保持内核的独立性。讨论中提出,Rust的条件编译和泛型特性可能有助于编写同时适用于用户空间和内核空间的代码,这可能降低内核开发的门槛并带来效率提升。然而,如何平衡内核的严格要求和Rust生态系统的需求仍是一个待解决的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关注了就能看到更多这么棒的文章哦~

Rustaceans at the border

By Jonathan Corbet
April 14, 2022
DeepL assisted translation
https://lwn.net/Articles/889924/

对 Rust 语言开发的支持正朝着内核的前进,尽管不确定何时会在 mainline 上出现。不过,Rust patch 确实正在取得进展,并开始吸引到内核社区之外的关注了。当两种语言——以及两个不同的开发社区——走到一起时,可能会产生一种文化冲突。Rust in the kernel 就出现了一些早期迹象。如果由此产生的摩擦能够被解决,那么很可能可以为每个人提供更好的开发环境。

最新一轮的 Rust patch 是由 Miguel Ojeda 在 3 月 17 日发布的。这一次,Rust 支持代码已经推进到了 Rust 语言 1.59.0 版本,这个版本中已经把几个重要的功能(对内核而言)稳定了下来。这些 patch 增加了一个新的模块(module),把对硬件随机数生成器的访问抽象了出来。还为 C 字符串增加了 CString 类型。spinlock 的实现也得到了改进。总的来说,这组已经在 linux-next 仓库中的 patch set,增加了超过 35000 行的代码和文档,这个工作是一个相当大的体量了。

目前还没有公开讨论过这些补丁何时可以进入内核 mainline。Rust 的支持甚至连开发者自己也都认为是 "实验性的";这种情况可能会持续一段时间(甚至持续到这项工作被并入 mainline 之后),直到这种语言能证明自己适合内核开发工作。

显然,一些开发者已经开始使用它了,而且他们并不都是传统的内核开发者。最近,Nándor Krácser 在 Rust-for-Linux 邮件列表中询问了将 crates.io 仓库中的 Rust 模块纳入内核构建的可能性。这个请求,似乎不是那么容易:

目前我正在试验会用在我的 module 里面的各种 crate,序列化库、数学库等,甚至还有更复杂的那些,真的很难直接作为源码库(source library)拉进来(也就是把代码复制到模块中),如果他们还有互相依赖关系,那就更复杂了。

此后不久,Chris Suter 也提出了类似的要求。那些在开发 kernel module 的 Rust 开发者似乎想要更多的功能,而不是目前的 kernel crate 提供的那些。

这应该并不让人感到意外。跟许多较新的语言一样,Rust 是跟语言相关的包管理系统以及相应的中心存储库紧密关联在一起的;在 Rust 环境里就是 Cargo 包管理器和 crates.io。这类语言的开发者很快就会习惯于用一个简单的命令来把新的模块(以及它们可能有的任何依赖关系)都加入进来,并习惯于在构建新程序时能让 build 系统神奇地处理好依赖关系。对于这些开发者来说,非常难以接受那些在加入一个复杂的库是无法通过几个命令简单完成的工作环境。

不过,内核并不是按他们期望的方式工作的。对于我们这些没有在这种开发环境中长大的人来说,那些花哨功能看起来就像一个会导致臃肿、错误以及安全问题的毒瘤。依赖中心存储库就会使项目出现问题,比如著名的 leftpad 事件,或者更糟的是有人会故意植入恶意软件。并且缺乏对 API 兼容性的关注,导致需求的版本各有不同,解决包之间的依赖性问题也非常困难,以至于现在开始有用机器学习系统来处理这些问题。另外,这一切看起来都是那么无序和混乱。

至少对这种开发模式的一些批评是合理的,但也不难发现有一点斯德哥尔摩综合症的迹象。对我们中的许多人来说,在我们职业生涯的大部分时间里,已经习惯了要花费很长时间来从源代码中 build 出一个新的程序,也就是习惯了 "尝试 build,再找出它下一步缺失的依赖,安装依赖" 的这种循环。当依赖的模块也有相应的依赖缺失问题时,还会出现递归的情况。习惯于这种工作方式之后就帮助我们更好地理解了我们的系统,而且必定会在某种程度上帮助我们建立了更好的道德品质,所以我们无法理解为什么现在的孩子就是不喜欢这样生活。

内核社区似乎比其他社区更有可能出现抵制较新的开发方法的开发者。内核必须独立存在,它的开发者对它具有的外部依赖一直在坚定地进行控制。内核代码库包含了构建一个可以正常工作的内核所需的全部代码。开发者可以安装很少的一套工具来完成 build 工作,但是安装外部的库才能构建内核的想法是不会被接受的。

因此,当开发者看到像 Suter 发布的这个清单时:

就像我说的,我对未来更感兴趣。为什么它有用:Async Rust 可以说比其他形式的多线程处理更常见,更容易使用。我喜欢的其他 crate 有:anyhow, bincode, byteorder, log, once_cell, pin-project, rand, serde, slab, static_assertions, uuid 加上一些更少见的。

看到这些的第一反应就是想逃掉和躲藏起来,或者以一种可能不符合任何人的行为准则的方式作出回复。

这有一些很好的理由。正如 Greg Kroah-Hartman 所指出的,那些针对用户空间中的有用的代码几乎肯定不会再符合那些强加给内核代码的约束。例如,"Async Rust" 对内核线程或在内核中如何进行上下文切换就是一无所知的。比如说内核代码在分配内存时必须非常小心,也不能使用浮点运算,还不能在 stack 中存储大尺寸的数据结构,不能使用无限制的递归(unbounded recursion),以及还有许多其他规则。大多数用户空间的代码,如果没有考虑到这些规则,在 kernel 环境中运行就会表现得很糟糕。由于这个原因,Kroah-Hartman 说,Rust 程序所需要的任何功能都必须专门编写,并在专门的 kernel crate 中提供。

Rust-for-Linux 的开发者很了解这种情况,并没有设想用 Cargo 这样的工具来添加模块。因此,有趣的是,长期从事内核开发的 Kent Overstreet 是主张采取不同方法的人。他说:"世界正在发生变化",也许现在是时候让内核社区也跟着改变了。他说,如果能在用户和内核空间中运行相同代码,会有很多种好处,而目前实现这个效果会是很痛苦的,对两边的开发者都是一个问题:

解决这类问题的办法是停止认为内核空间和用户空间必须是完全不同的情况,毕竟它们真的并不是必须要不一样的!并开始鼓励不同的思维和工具改进,使我们的生活更容易。

内核和用户空间之间的界限在过去几年中确实变得更加松散。各种子系统提供了 hook,允许以前一些非要内核完成的任务在用户空间进行,而用户空间可以使用 BPF 来运行内核内的代码。但是,这两种环境仍然是完全不同的,其中一个环境中可以运行的代码通常不能在另一个环境里运行。一直以来,人们都没有花很大力气去思考如何缩小这种鸿沟,也许现在真的是改变这种状况的时候了。Rust 语言可能正是这种转变可能可以发生的合适环境。正如 Overstreet 所说:

Rust 的条件编译和泛型故事比我们过去在 C 和 C++中的情况要好得多,这意味着编写在用户空间和内核空间都能工作的 Rust 代码要比过去更有合理性了。

如果这样的倡议能够成功,它可以大大降低未来内核开发者的入门门槛,同时为内核社区提供大量有用的代码。这将是一个不同于我们现在所熟悉的内核的项目,但它可能是一个更有趣、更有生产效率的项目。

当移民者出现在一片新的土地上时,往往会发生有趣的事情。他们往往会在那些已经在那里的人中引起一些反弹——毕竟,新来的人穿着很奇怪,他们做的饭闻起来也很奇怪,有些人甚至把螃蟹当作他们的吉祥物。但他们也可以带来激情和想法,震动他们的新家,使其对每个人来说都更加丰富。如果一群 Rust 开发者来到内核社区,我们可能会看到这样的事情发生。最终的结果可能我们都认不出来了——也许会比我们之前的任何东西都要好。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

49c63d91eab63e30094212f592b95030.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值