Linux 诞生于 1991 年,距今已经 30 年了。虽然它一开始只是 Linus 的一个个人项目,而非出于要开发一个新操作系统的伟大梦想,但如今的 Linux 早已无处不在。
30 年前,当 Linus Torvalds 第一次发布 Linux 内核时,他还是赫尔辛基大学的一名 21 岁的学生。他宣布说:“我正在开发一个(免费的)操作系统(这只是个爱好,不会做得很大,也不会很专业……)”。30 年后,500 强超级计算机和 70% 以上的智能手机都在运行 Linux。很显然,Linux 不仅大,而且很专业。
30 年来,Linus Torvalds 一直在领导着 Linux 内核的开发,启发了无数开发者和开源项目。2005 年,Linus 开发了 Git,用来管理内核开发过程。Git 现在已经成为最流行的版本控制系统,受到无数开源和私有项目的信任。
正值 Linux 诞生 30 周年之际,Linus Torvalds 通过电子邮件回复了 Tag 1 咨询公司的创始合伙人/首席执行官 Jeremy Andrews 的访谈问题(《An Interview With Linus Torvalds: Linux and Git – Part 1》),回顾并总结了过去这些年他在领导大型开源项目过程中得到的真知灼见。本文着重介绍 Linux 内核开发和 Git。InfoQ 对访谈内容进行了翻译,以飨读者。
Linux 内核开发
Jeremy Andrews:Linux 无处不在,它是整个开源世界的灵感源泉。当然,事情并不是从一开始就这样的。1991 年,你在 comp.os.minix Usenet 新闻组中发布了一个 Linux 内核。十年后,你写了一本书,叫作“Just for Fun: The Story of an Accidental Revolutionary”(中译名:《只是为了好玩:Linux 之父林纳斯自传》),对那段历史进行了深度回顾。今年 8 月,Linux 将迎来它的 30 周年纪念日!在这个过程中,你是在什么时候开始意识到 Linux 并不仅仅是一个“爱好”的?
Linus Torvalds: 这听起来可能有点荒谬,实际上我很早就开始意识到了。在 1991 年末(以及 1992 年初),Linux 已经比我预想的要大得多。
那时候可能只有几百个用户(确切地说不是“用户”,因为人们还要不断地对它进行修修补补),从没想过 Linux 后来能够发展壮大。在我看来,最大的转折点是当我意识到其他人正在使用它,并对它感兴趣,它开始有了自己的生命。人们开始发送补丁,这个系统能做的事情比我最初预想的要多得多。
1992 年 4 月的某个时候,X11 被移植到 Linux 上(其实我也记不太清具体时间了,毕竟那是很久以前的事了),这是一个重大进步,Linux 系统突然间有了 GUI 和一系列全新的功能。
我一开始并没有什么大计划。这只是一个个人项目,并不是出于要开发一个新操作系统的伟大梦想。我当时只是想了解我的新 PC 硬件的来龙去脉。
所以,在发布第一个版本时,实际上更多的是想“看看自己都做了些什么”。当然,我希望其他人会觉得它有趣,但它并不是一个真正可用的操作系统。它更多的是一种概念验证,而且只是一个我在当时做了几个月的个人项目。
从“个人项目”到其他人开始使用它、给我反馈(和 bug 报告)和发送补丁,对我来说是一个巨大的转变。
举个最基本的例子:最初的版权许可是“你可以以源代码的形式发布它,但不能用它赚钱”。
对于当时的我来说,商业版 Unix 太贵了(作为穷学生,我已经为了买新 PC 花光了所有钱),所以我希望这个操作系统的源代码是公开可用的(这样人们就可以提供补丁),我希望将它开放给像我这样负担不起昂贵电脑和操作系统的人。
1991 年末(或是 1992 年初),我把许可改为 GPLv2,因为有人想把它以软盘的形式分发给本地 Unix 用户组,但又想收回软盘的成本,并补偿他们拷贝软盘所花费的时间。我觉得这很合理,因为“免费”与否并不是最重要的,最重要的是要“公开源码”。
最终的结果是:人们不仅在 Unix 用户组中发布它,在几个月之内还出现了 SLS 和 Slackware 的软盘发行版。
与最初的那些根本性的变化相比,后来的一切都是“增量式”的。当然,有些增量式的变化也是大跨步(IBM 的加入、Oracle 数据库的移植、Red Hat 的首次公开募股,Android 在手机上的应用,等等),但在我看来,它们仍然不如最初的“我不认识的人都在使用 Linux”那样具有革命性。
Jeremy Andrews:你是否曾经后悔修改了许可协议?或者说,其他人或公司用你开发的系统赚了很多钱,你因此感到后悔吗?
Linus Torvalds: 我从来没有后悔过。
首先,我过得还不错。我不是特别富有,但我是一个薪水很高的软件工程师,可以按照自己的节奏做我喜欢做的事情。
关键是我百分之百认为这个许可是 Linux(以及 Git)取得成功的重要原因。我认为,当所有人都认为他们有平等的权利,没有人在这方面有特权的时候,他们才会变得更快乐。
有很多项目采用了“双重许可”,一方面,原作者保留了商业许可(“只要你支付了许可费用,就可以使用它”),另一方面,项目也可以在 GPL 许可下开源。
我认为要在这种情况下建立好的社区是非常困难的,因为开源那一方知道自己是“二等公民”。另外,为了让享有特权的那一方一直享有特殊的权利,需要做很多许可文书工作,这给项目带来了额外的阻力。
另一方面,我见过很多基于 BSD(或 MIT 等类似的许可)许可的开源项目,当它们变得足够强大,大到具备商业价值时,它们就开始分裂,相关的公司不可避免地会将自己的那部分变成专有的。
我认为 GPLv2 能够在“每个人都处于相同的规则之下”和“要求人们回馈社区”之间取得完美的平衡。每个人都知道,所有参与者都受到相同的规则的约束,所以这是非常公平的。
当然,你的投入总会得到回报。如果你只是想轻度参与项目,或者只是想作为一名用户,那也是可以的。如果你真的只是这样,就也无法控制这个项目。如果你真的只需要一个基本的操作系统,而 Linux 已经具备你想要的所有功能,那也完全没有问题。但如果你有特殊的需求,想要为这个项目做一点事情,那么唯一的方法就是参与其中。
这让每个人都秉持诚实的态度,包括我在内。任何人都可以 fork 这个项目,用他们自己的方式,然后说“再见了,Linus,我要维护自己的 Linux 版本”。我之所以“特别”,仅仅是因为人们相信我能把工作做好。
“任何人都可以维护自己的 Linux 版本”,这让一些人对 GPLv2 产生了怀疑,但我认为这是一种优势,而不是劣势。我认为,这实际上是避免 Linux 出现分裂的原因:每个人都可以创建自己的项目分支。事实上,这也是“Git”的核心设计原则之一——代码库的每一个克隆都是一个分支,人们(和公司)再 fork 出自己的版本,完成开发工作。
所以,分支不是问题,只要你能把好的部分合并回来。这就是 GPLv2 发挥作用的地方。能够拉取分支,并按照自己的方式修改代码,拥有这些权利很重要,但另一方面也同样重要——当一个分支被证明取得了成功,有权利把它合并回去。
另一个问题是,除了要有支持这种工作流的工具,也要有可以支持它的心态。合并分支的一大障碍不仅是许可问题,还有“嫌隙”问题。如果分支是源于对立,那么要合并两个分支就非常困难——不是因为许可或技术方面的原因,而是因为分支之间太过对立。我认为 Linux 避免了这种情况的发生,主要是因为我们一直认为分支是一件很自然的事情。而且,当一些开发工作被证明取得了成功,尝试将其合并回来也是很自然的。
虽然这个答案有点偏离正题,但我认为它很重要——我不后悔修改了许可,因为我真的认为 GPLv2 是 Linux 取得成功的一个重要原因。
金钱不是一种很好的激励方式,它无法让人们团结在一起。我认为,参与一个共同的项目,并感觉到自己可以成为这个项目的合作伙伴,这样才能激励人们。
Jeremy Andrews:现在,人们基于 GPLv2 发布源代码通常是因为 Linux。你当时是怎么找到这个许可的?你在调研其他许可方面又投入了多少时间和精力呢?
Linus Torvalds: 那个时候,有关 BSD 和 GPL 的争论非常激烈。我在阅读各种新闻组(比如 comp.arch、comp.os.minix 等)时看到了一些有关许可的讨论。
其中两个最主要的原因可能是 gcc 和 Lars Wirzenius。gcc 对 Linux 的发展起到了很大作用,因为我肯定需要一个 C 语言编译器。Lars Wirzenius 是我在念大学时另一个说瑞典语(瑞典语在芬兰是小语种)的计算机系学生。
Lasu 比我更喜欢讨论与许可相关的事情。
在我看来,选择 GPLv2 并不算是什么重大的政治问题,主要是因为我最初在选择许可时太过仓促,后来需要做出修改。况且,我很感恩有 gcc,并且 GPLv2 更符合我对“你必须把源代码合并回来”这种想法的期望。
因此,与其另起炉灶新建一个许可,不如选择一个人们已经知道并且有一些律师参与其中的许可。
Jeremy Andrews:通常情况下,你的一天是怎么过的?其中有多少时间花在写代码上,多少花在评审代码上,多少花在电子邮件上?你如何平衡个人生活和 Linux 内核开发工作?
Linus Torvalds: 我现在写的代码很少,而且已经很久没写了。再要写代码,通常是因为人们对某些特定的问题存在争议。我修改代码,并将其作为补丁发布出去,作为对解决方案的解释说明。
换句话说,我写的大部分代码更多的是作为解决方案的示例,而补丁是一种非常具体的例子。人们很容易陷入理论讨论的陷阱,而我发现描述解决方案最好的方式是写代码片段,不一定要完整的程序,只要让解决方案具体化一些即可。
我的工作时间都花在电子邮件上了。主要是沟通,而不是写代码。事实上,我认为这种与记者和技术博主之间的交流就是我工作的一部分——它可能比技术讨论优先级低一些,但我也花了相当多的时间在这类事情上。
当然,我也会花一些时间在代码评审上。但老实说,当我收到一个 PR 时,有问题的代码通常已经被其他人评审过了。所以,虽然我仍然会看一下补丁,但实际上会更多地去关注注解,以及补丁的演化过程。但对于那些与我共事很久的人,我不会这么做:他们是自己子系统的维护者,我不需要对他们的工作指手画脚。
所以,很多时候,我的主要工作就是“待在那里”,执行管理和发布任务。换句话说,我的工作通常更多地是关于维护过程,而不是底层代码。
Jeremy Andrews:你的工作环境是怎样的?比如,你是喜欢黑暗、不会受人打扰的房间,还是喜欢能看到风景的房间?你喜欢在安静的环境下工作,还是喜欢一边听音乐一边工作?你通常使用哪种硬件?你是在终端上使用 vi 来评审代码,还是使用某种奇特的 IDE?你是否有偏爱的 Linux 发行版作为开发环境?
Linus Torvalds: 我的房间并不“暗”,但我确实把桌子旁边窗户上的百叶窗关上了,因为我不想要强烈的阳光。所以,我的房间没有什么风景视野,只有一张(凌乱的)桌子,配了两个 4k 显示器,桌子下面有一台强劲的电脑主机。还有几台笔记本电脑供我测试和在路上用。
我喜欢安静地工作。我很讨厌机械硬盘的滴答声,所以我把它们扔进了垃圾桶,现在只使用 SSD。这样已经 10 多年了。嘈杂的 CPU 风扇声也是不可接受的。
代码评审都是在传统的终端上完成的,不过我没有使用 vi。我使用的是“micro-emacs”这个令人讨厌的东西。它与 GNU emacs 完全没有关系,只是有些键绑定与它相似。我在赫尔辛基大学时就习惯用它了,到现在还没改掉这个习惯。几年前,我给它增加了(非常有限的)utf-8 支持,但它确实很老旧了,所有的迹象都表明它是在 80 年代开发的,我使用的版本是一个自 90 年代中期以来就没有更新过的分支。
赫尔辛基大学选择了这个工具,因为它可以在 DOS、VAX/VMS 和 Unix 上运行,这也是为什么我也会用它。到现在,我的手指已经对它形成肌肉记忆了。我真的需要换个有人维护并支持 utf-8 的工具,只是我增强的那部分功能用起来还好,所以一直没有强迫我的手指去接受新的工具。
我的工作桌面相当简单:几个文本终端,一个打开了电子邮箱的浏览器(还打开了其他几个标签,主要是新闻和科技网站)。我喜欢大的桌面空间,因为我习惯使用大终端窗口(100×40 是我的默认初始大小),并且并排打开好几个。我使用了两个 4k 显示器。
我在所有的机器上都安装了 Fedora 发行版,并不是因为我偏爱它,而是因为我习惯了。我并不太关心使用哪个发行版——对于我来说,选择发行版只是在机器上安装 Linux 和开发工具的一种方式。
Jeremy Andrews:Linux 内核邮件组(https://lore.kernel.org/lkml/)是人们公开交流内核开发的地方,流量非常高。你是怎么处理这么多电子邮件的?你尝试过邮件组之外的其他协作和沟通解决方案吗?或者说,这种简单的邮件组对你的工作来说足够好吗?
Linus Torvalds: 我没有直接阅读内核邮件组里的邮件,而且好几年都没有。邮件太多了。
内核邮件组里的邮件会被抄送到所有的讨论当中。当新人加入讨论时,他们可以通过查看内核邮件组来了解相关的历史和背景。
过去我会订阅邮件组,让所有没有抄送给我的电子邮件自动归档,默认不看它们。当一些问题需要我介入时,我可以找到所有相关的讨论,因为它们都在我的电子邮件里,只是在需要时才会出现在我的收件箱里。
现在,我使用的是 lore.kernel.org 提供的功能,因为它很好用,而且我们还基于它开发了一些工具。这样就不需要让邮件自动归档了,我们换了一种讨论方式,但基本的工作流程是一样的。
但很显然,我仍然会收到很多邮件——但从很多方面来看,这些年来情况变得越来越好,而不是越来越糟。其中很大一部分原因是 Git 和内核发布流程的改进:我们过去在代码流程和工具方面存在很多问题。在本世纪初是最为糟糕的,当时我们仍然在处理巨大的补丁炸弹,我们的开发流程存在严重的可伸缩性问题。
邮件组模式确实运作得很好,但并不是说人们就不使用除电子邮件之外的其他沟通方式了:有些人喜欢各种实时聊天工具(比如传统的 IRC)。虽然我不是很喜欢这样,但很显然有些人喜欢用它们来进行头脑风暴。但这种“邮件组存档”模式运作得非常好,并且能够无缝地与“开发者之间以邮件的形式发送补丁”和“以邮件的形式发送问题报告”相结合。
所以电子邮件仍然是主要的沟通渠道,并且因为邮件中可以包含补丁,我们可以更容易地讨论技术问题。而且邮件可以跨越时区,当参与者分布在不同地区时,这一点非常重要。
Jeremy Andrews:我密切关注内核开发大约有 10 年了,并在 KernelTrap 上写与内核有关的博文,大概是在 3.0 内核发布时停止更新博客。3.0 内核的发布与 2.6.x 内核的发布相隔了 8 年。请总结一下自 3.0 版本以来内核开发中发生的一些有趣的事情。
Linus Torvalds: 那是很久以前的事了,我不知道该从哪里开始总结。从 3.0 版本到现在已经 10 年了,在这 10 年中发生了很多技术上的变化。ARM 已经发展成熟,ARM64 已经成为我们的主要架构之一,并出现了大量新的驱动程序和核心功能。
如果说过去 10 年有什么有趣的事情,那一定是我们努力保持开发模式的稳定,以及那些没有发生改变的东西。
在过去的几十年里,我们经历了多种不同的版本号方案和不同的开发模式,3.0 版本最终确定了后来一直使用的模式。它让“基于时间发布,版本号只是数字,与特性无关”这一说法落地了。
在 2.6.x 版本中,我们就有了基于时间的发布模式,所以它并不是什么新东西,但 3.0 版本确实是让这种模式板上钉钉的至关重要的一步。
我们以前使用随机编号方案(主要是在 1.0 版本之前),然后用“奇数表示开发版内核,偶数表示稳定的生产就绪版内核”,然后在 2.6.x 版本中,我们开始进入基于时间的发布模式。但人们仍然对“什么时候需要增加主版本号”存在疑问。3.0 版本正式发布后,宣告了主版本号没有任何意义,我们尽量简化数字,不要让它们变得太大。
因此,在过去的 10 年里,我们做了巨大的改变(有了 Git,就可以很容易地得到一些数字统计数据:超过 1.7 万人提交了大约 75 万次代码),但开发模式仍然相当稳定。
但并非一直都是这样的,内核开发的前 20 年经历了相当痛苦的开发模式变更,只是在过去 10 年中,发布可预测性才得到大幅提升。
Jeremy Andrews:目前,最新的版本是 5.12-rc5。现在的发布流程标准是怎样的?例如,-rc1 和 -rc2 有什么不同?你会在什么情况下决定正式发布其中一个给定的版本?如果在正式发布之后出现了大量的回归会怎样?这种情况发生的频率是怎样的?这些年来,这个过程是如何演变的?
Linus Torvalds: 我之前提到过,这个过程本身是很标准的,并且在过去十年里一直如此。在此之前,它经历了几次演变,但实际上从 3.0 开始它就像时钟一样走得很稳定。
到现在为止,我们的发布节奏是这样的:先是两周的合并时间窗口,然后是大约 6 到 8 周的候选版本,然后是最终版本。这样子差不多 15 年了。
规则一直都是一样的,尽管它们并不总是被完全严格执行:合并时间窗口是针对那些被认为已经“经过测试和准备就绪”的新代码,然后在接下来的大约两个月里进行修复,以确保所有的问题都得到解决。有时候,那些所谓的“就绪”代码会在发布之前会被禁用或完全推翻。
这个过程会重复,所以我们大约每 10 周发布一次。
达到可以发布的标准是我对候选版本有足够的信心,而这是以各种问题报告为基础的。如果某些方面在 rc 后期仍然会出问题,我就极力推翻这些内容,并建议将其放在后续的版本中。但总体而言,很少会出现这种情况。
这样就完全没有问题了吗?不是的。一旦内核发布了,就会有新用户,他们会发现一些在 rc 版本中没有被发现的问题。这几乎是不可避免的。这也是为什么我们需要“稳定内核”树。在发布之后,我们可以继续修复代码。一些稳定内核比其他版本内核维护的时间更长,被称为 LTS(“Long Term Support”)版本。
所有这些在过去十年里都没有什么变化,尽管后来有了更多的自动化流程。一般来说,内核测试自动化是很困难的——因为很多内核是驱动程序,十分依赖硬件的可用性。不过,我们有几个测试场同时进行引导和性能测试,以及各种随机负载测试。这些在这几年有了很大的改善。
Jeremy Andrews:去年 11 月,有人说你对苹果公司在部分新款电脑中使用的 ARM64 芯片十分感兴趣。Linux 会支持它们吗?我看到一些代码被合并到 for-next。即将到来的 5.13 内核有可能在苹果 MacBook 上启动吗?你有可能是它的早期采用者吗?ARM64 有什么重大的意义?
Linus Torvalds: 我偶尔会跟进一下,但现在说这些还为时过早。正如你所说的,早期支持可能会被合并到 5.13 中,但这只是一个开始,并不能说明 Linux 和苹果电脑将来会怎样。
主要问题不是 arm64 架构,而是与之相关的所有硬件驱动程序(特别是 SSD 和 GPU)。到目前为止,一些底层的东西得到了支持,但除了可以启用硬件之外,没有任何有用的结果。要想达到可以被人们使用的程度,还需要一些时间。
不仅仅是苹果的硬件得到了改进——arm64 架构总体上也已经成长了很多,内核在服务器领域也更具竞争力了。不久前,arm64 在服务器领域的竞争力还很弱,但亚马逊的 Graviton2 和安培的 Altra 处理器——都是基于改进后的 ARM Neoverse IP——比几年前的产品要好很多。
我已经等了十多年都没能等到一个可用的 ARM 机器,可能还要继续等下去,但情况明显比以前好了一些。
事实上,我很早之前就想要一台 ARM 机器。当我还是个少年,我真正想要的是一台 Acorn Archimedes,但可用性和价格让我最终选择了 Sinclair QL(M68008 处理器),然后几年后换成了 i386。
所以,这个想法已经酝酿了几十年。但到现在它们还没有被广泛使用,而且对于我来说,它们在价格和性能方面都不具竞争力。希望在不久的将来,这个想法能够变成现实。
Jeremy Andrews:内核中有什么东西需要进行完全的重写才能达到最优的吗?或者说,内核已经有 30 年的历史了,知识、编程语言和硬件在这 30 年里发生了很大的变化:如果现在让你从头开始重写,你会做出哪些改变?
Linus Torvalds: 如果有必要的话我们会这么做的。我们真的很擅长重写,那些本来会造成灾难的东西很久以前就被我们重写了。
我们有很多“兼容”层,不过它们一般不会造成太大问题。如果从头开始重写,这些兼容层是否要去掉,我们还不清楚——它们存在的目的是为了与旧二进制文件向后兼容(通常是与旧架构向后兼容,例如在 x86-64 上运行 32 位的 x86 应用程序)。因为我认为向后兼容是非常重要的,所以即使重写,我也希望保留这些兼容层。
所以很明显,有很多东西并不是最优的,毕竟任何东西都有改进的空间。但就你提的这个问题,我不得不说,我不鄙视任何东西。有一些遗留驱动程序,可能没有人关心,也没有人去清理,会做一些丑陋的事情,但这主要是因为“没有人关心”。这些在过去不是问题,而一旦成为问题,我们就会积极把这些没人关心的东西移除掉。多年来,我们已经移除了很多驱动程序,当维护不再有任何意义时,我们会放弃整个架构支持。
“重写”的主要原因是:整个架构不再有意义,但仍然存在一些应用场景。最有可能的情况是,一些小型嵌入式系统并不需要 Linux 提供的所有东西,它们的硬件很小,需要的是更简单、更少的系统功能。
Linux 已经有了长足的发展。现在,即使是小硬件(比如手机等)也比当初开发 Linux 所使用的机器强大得多。
Jeremy Andrews:如果用 Rust 来重写一部分系统会怎样?在这方面还有改进的余地吗?在内核开发方面,你觉得是否有可能用另一种语言(比如 Rust)来取代 C 语言?
Linus Torvalds: 我不认为我们会用 Rust 取代 C 语言来开发内核,但可能会用来开发一些驱动程序,也许是整个驱动子系统,也许是文件系统。所以不是“取代 C 语言”,而是“在一些有意义的地方扩展我们的 C 代码”。
当然,驱动程序几乎占了内核的一半代码,有非常大的重写空间,但我不认为所有人都会很期待使用 Rust 全盘重写现有的驱动程序。可能“有些人会用 Rust 开发新驱动程序,或者适当地重写一部分旧驱动程序”。
现在更多的是“人们在尝试和体验”Rust,仅此而已。Rust 优势的背后肯定存在复杂性,所以我会采取观望的态度,看看这些优势是否真的奏效。
Jeremy Andrews:内核中是否有你个人感到最自豪的部分?
Linus Torvalds: 我最想说的是 VFS 层(虚拟文件系统,特别是路径名查找)和 VM。前者是因为 Linux 在做一些基础任务(在操作系统中查找文件名确实是一个核心的操作)时比其他系统都要好得多,后者主要是因为我们支持 20 多种架构,但仍然在使用一个基本统一的 VM 层,我认为这一点很了不起。
但与此同时,这很大程度上取决于“你最关注内核的哪一部分”。内核很大,不同的开发者(和不同的用户)会关注不同的方面。有些人认为调度是内核中最令人感到兴奋的部分,有些人则关注设备驱动程序的细节(我们有很多这样的驱动程序)。我个人在 VM 和 VFS 这两个方面参与得更多,所以自然会提到它们。
Jeremy Andrews:我看了这个关于路径名查找的描述(https://www.kernel.org/doc/html/latest/filesystems/path-lookup.html),它比我预想的要复杂。是什么让 Linux 在这方面比其他操作系统做得更好?你说的“更好”是什么意思?
Linus Torvalds: 路径名查找是一个非常常见和基础的任务,以至于大多数非内核开发者不认为它会是一个问题:他们只知道打开文件,并认为这是理所当然的。
但要做好其实是相当复杂的。确切地说,因为几乎所有地方都在用路径名查找,所以对性能要求很高,而且大家都希望它在 SMP 环境中具有良好的伸缩性,而在锁定方面又很复杂。你不想发生 IO,那么缓存就非常重要。路径名查找是如此的重要,以至于你不能把它留给底层的文件系统,因为我们有 20 多种不同的文件系统,让它们各自拥有自己的缓存和锁定机制将是一场彻头彻尾的灾难。
所以,VFS 层的一个主要任务是处理所有路径名组件的锁定和缓存问题,以及所有的序列化和挂载点遍历问题,这些都是通过无锁算法(RCU)来完成的,但也会有一些非常智能的锁(Linux 内核的“lockref”锁是一种非常特殊的“带有引用计数的自旋锁”,表面上看是为 dcache 缓存而设计的,但本质上是一个专门的锁感知引用计数,可以在某些常见情况下消除锁)。
最终结果是:底层文件系统仍然需要对未缓存的内容进行查找,但它们不需要关心缓存和一致性规则以及与路径名查找相关的原子性规则。VFS 会为它们处理好所有这些问题。
而且它的性能比任何其他操作系统都要好,基本上可以在拥有数千个 CPU 的机器上完美运行。
所以不仅仅是“更好”,而是“大写”的更好。没有什么能与之相提并论的了。Linux dcache 是独一无二的。
Jeremy Andrews:过去的一年对全世界来说是艰难的一年。新冠疫情对内核开发进程带来了哪些影响?
Linus Torvalds: 实际上,得益于我们一直以来的工作方式,它的影响非常小。电子邮件真的是一个很好的工具,我们并不依赖面对面的会议。
是的,它确实影响了去年的年度内核峰会(今年的峰会仍悬而未决),大多数会议被取消或转为线上进行。以前在办公室工作的人大都开始在家里工作(但很多核心内核维护者在之前已经这么做了)。所以,周围的很多东西都发生了改变,但内核开发还是像以前一样。
很显然,新冠疫情在其他方面影响了我们所有人的生活,但总的来说,作为几乎完全通过电子邮件进行交流的内核开发人员,我们可能是受影响最小的。
版本控制系统 Git
Jeremy Andrews:Linux 只是你对开源做出的众多贡献中的一个。在 2005 年,你还创建了 Git,一个非常流行的分布式源代码控制系统。你快速地将 Linux 内核源代码树从专有的 Bitkeeper 迁移到开源的 Git 系统中,并在同年将维护工作移交给了 Junio Hamano。这里有很多有趣的故事,是什么原因促使你这么快就将项目的领导权移交了出来,你是如何找到并选择了 Junio 的?
Linus Torvalds: 答案可以分为两个部分。
首先,我并不想创建一个新的源代码控制系统。开发 Linux 是因为硬件和软件之间的底层接口很吸引我——基本上是出于个人的热爱和兴趣。相反,开发 Git 是因为确实有这个需要:不是因为我觉得源代码控制很有趣,而是因为我十分鄙视市面上的大多数源代码控制系统。而我觉得最合适的、在 Linux 开发当中很好用的 BitKeeper 已经无法维持下去了。
我开发 Linux 已经超过 30 年了(距离第一个版本的周年纪念还有几个月,但在 30 年前我就开始研究 Linux 的“前身”了),并且一直在维护它。但 Git 呢?我从来没有想过我真的想要长期维护它。我喜欢用它,而且在某种程度上,我认为它是最好的 SCM,但它并不是我的兴趣所在。
所以我总是希望别人来为我维护 SCM——事实上,如果当初我不用自己开发这个 SCM,我会很开心。
以上就是故事的背景。
至于 Junio,他实际上是最早加入 Git 开发队伍的人员之一。他在我将 Git 的第一个非常粗糙的版本公开后的几天内提交了第一次变更代码,所以 Junio 在 Git 一开始就参与其中了。
但我之所以把项目交给 Junio,并不是因为他是第一批参与项目的人。在维护了 Git 几个月之后,让我决定将项目交给 Junio 维护者的真正原因是“好品味”——一个很难描述的概念。我真的想不到还有什么更好的描述:编程主要是为了解决技术问题,但如何解决这些问题以及如何思考也很重要。随着时间的推移,你开始意识到:有些人就有这种“好品味”,他总能选择正确的解决方案。
我不想将编程说成是一门艺术,因为它实际上主要是关于“好的工程”。我很喜欢托马斯·爱迪生的那句“天才是百分之一的灵感加上百分之九十九的汗水”:编程涉及的几乎都是细枝末节的东西和日常繁重的工作。但是,那百分之一的“灵感”,也就是“好品味”,不仅要解决问题,而且要干净、漂亮地解决。
Junio 就有那种“好品味”。
每次提到 Git,我都想试着讲清楚:我在一开始提出了 Git 的核心思想,并经常因为这部分工作而获得太多荣誉。Git 的这 15 年,我也只是在第一年真正参与了项目。Junio 是一个优秀的维护者,是他让 Git 变成现在的样子。
顺便说一下,关于“好品味”,以及找到拥有好品味的人,并信任他们——不仅仅 Git 是这样,Linux 也是这样。与 Git 不一样的是,Linux 这个项目我仍然在积极维护,但与 Git 一样的是,Linux 也是一个有很多人共同参与的项目。我认为,Linux 的一大成功是它拥有数百名维护者,他们都具备了“好品味”,并维护着内核的不同部分。
Jeremy Andrews:你有没有过这样的经历:把控制权交给维护者,然后发现这是一个错误的决定?
Linus Torvalds: 我们的维护体系从来就不是非黑即白的,所以不会出现这种情况。事实上,我们甚至没有将维护权正式记录下来:我们确实有一个 MAINTAINERS 文件,但那只是为了让你在遇到问题时能够找到对的人,并不是某种排他所有权的标志。
所以,“谁负责什么东西”更像是一种流动的指南,以及“这个人很活跃,工作做得很好”,而不是“我们把所有权给了那个人,然后他搞砸了”。
从某种意义上说,我们的维护体系也是流动的。假设你是某个子系统的维护者,如果你需要另一个子系统的东西,是可以跨界的。通常人们在这样做之前都会进行广泛的沟通,而且这种事情确实发生了。这并不是“你只能动这个文件”之类的硬性规定。
实际上,这与前面讨论的有关许可的事情有些联系。“Git”的另一个设计原则是“每个人都有自己的代码树,但没有哪一个代码树是特殊的”。
因为很多其他项目都使用了工具——比如 CVS 或 SVN——这些工具会让一些人变得“特殊”,赋予了他们某种“所有权”。在 BSD 世界里,他们称之为“commit bit”:给一个维护者“commit bit”意味着他可以将代码提交到中央代码库。
我一直很讨厌这种模式,因为它会不可避免地导致政治“小团体”的出现。在这种模式下,总有一些人是特殊、隐性受信任的。问题的关键甚至不在于“隐性受信任”,而在于硬币的另一面——其他人不被信任,他们被定义成局外人,必须受制于监护者。
同样,在 Git 开发中也不存在这种情况。每个人都是平等的,任何人都可以克隆代码,做自己的开发,做好了,就可以合并回来。
所以,没有必要给人们特权,也不需要“commit bit”。这样就可以避免出现政治“小团体”,也不需要“隐性信任”。如果他们做得不好——或者更常见的是,最终消失了,并转向了另一个兴趣——他们的代码就不会被合并回来,也不会阻碍其他有新想法的人。
Jeremy Andrews:Git 有没有哪些新特性让你印象深刻,并成为你工作流的一部分?还有哪些特性是你想要增加的?
Linus Torvalds: 我对 Git 的需求总是最早得到满足的,所以,对于我来说,Git 没有“新”特性。
这些年来,Git 确实有很大的改进,有一些在我的工作流中已经体现出来了。例如,Git 的速度一直都很快——毕竟这是我的设计目标之一——但它的大部分特性最初是围绕 shell 脚本而构建的。多年来,大多数 shell 脚本都已经消失了,这意味着我可以比原来更快地应用 Andrew Morton 的补丁。这一点令人感到欣慰,因为这实际上是我早期用于性能测试的基准之一。
所以,Git 对我来说一直都很好,而且变得越来越好。
Git 最大的改进在于“普通用户”的使用体验变得更好了。一部分原因是人们在学习 Git 工作流的过程中逐渐习惯了它,但更多的是因为 Git 本身变得更易于使用。