10年前,systemd被宣布,并迅速上升为近代史上最具争议性和两极分化的软件之一,尤其是在GNU/Linux世界。辩论的质量和性质从2012-2014年前后的重大火焰战中丝毫没有得到改善,而且无论是从技术层面还是从社会层面上,对系统D的理解和研究仍然很少,尽管人们对它的关注程度不成比例,这是自相矛盾的。
我写这篇文章既是为了安慰自己,所以我最终可以把它平息下来,也是希望我的分析能为这场长达十年的闹剧提供一些背景,而不是像本诺·赖斯(Benno Rice)现在著名的描述那样,是悲剧。
在第一章中,在当代邮件列表帖子的基础上,我讨论了在system d之前对init、rc和服务管理进行现代化的努力,以及当时的主要动机是什么。我首先介绍不同类别的Linux用户之间的文化鸿沟。
在第二章中,我讨论了system d的早期历史和设计理念,以及什么因素推动了它的采用。
第三章是对系统的技术批判。本文假设您事先熟悉systemd,并且大量讨论实现细节。我还包括一些基于错误报告的“案例研究”,以更好地说明一些较为枯燥的理论。
第四章讨论了自由/开源软件开发中与systemd在历史上的其他相似之处,总结了第一章和第二章中的一些线索,并对低级Linux用户空间的未来进行了一些猜测。
对Linux的碎片化本质的抱怨几乎和第一个发行版一样古老,因为它是单个白盒组件拼凑成发行版的无政府主义集市,以及各种长期试图“解决”这个固有问题的努力。
1994年6月接受“Linux日报”采访时,Linux TCP/IP协议栈的早期贡献者弗雷德·范·肯彭(Fred Van Kempen)表示:
就我个人而言,我认为Linux社区将不得不习惯于(A)为他们使用的软件(例如,共享软件和商业应用程序)支付一些费用,以及(B)系统本身的更封闭的开发环境。很多很多人会不同意,而这个项目恰恰是阻止Linux在现实世界中取得重大突破的原因。
按照这位早期先驱的估计,热闹的集市需要与大教堂和专有软件做出妥协。
1998年,克里斯托弗·B·布朗(Christopher B.Browne)发表了一篇题为“Linux与分散发展”的文章,这篇文章是在ESR发表了一篇著名的关于大教堂和集市的文章之后,在评论界掀起的一场风暴中写的。文章开头写道,“过去几年里,许多人抱怨说,应该有某种形式的”中央“Linux组织。”
Browne继续为分散开发的优点争辩,但最终确实承认了他所称的“Linux基金会”的用处,并继续描述了这样一个组织的资金来源和资金来源,这确实会在不久之后成为现实。
除了命运多舛的Linux Standard Base之外,标准化统一的“Linux”API的早期尝试之一是现在已被遗忘的EL/IX规范,该规范由Cygnus Solutions于1999年底起草,不久之后被Red Hat收购。它专门用于所谓的“深度嵌入”平台,当时定义为“汽车控制、数码相机、手机、寻呼机”,并与eCos等实时操作系统竞争。请注意,在常见问题解答中,我们读到“RedHat致力于确保Linux的可移植性和维护选择的自由”--这一观点在我们这个时代并不是很受欢迎。EE Times上同期的一篇文章透露,当时其他使用嵌入式Linux的供应商对EL/IX的宣布反应不一。
Linux“社区”的主要文化裂痕可以归结为两件事:它与GNU历史和自由软件运动的纠缠,以及它作为“革命OS”的形象-这是一种自由文化的产物,由业余爱好者和志愿者在即将从收缩包装的软件供应商和尖发老板手中解放出来,或者是窥探云服务提供商,作为更现代的等价物。
因此,专业的Linux管道工和普通的业余爱好者占据了两个不同的世界。在Desktop Linux和DevOps中间件的先锋部门工作的人,作为受薪员工,与那些使用无用软件、从头开始构建基于MUSL的发行版并拥护极简主义和自给自足价值观的人没有共同点。对于后一阵营中的许多人来说,他们是从自由软件的信息中来到Linux的,他们最终意识到,现实世界的Linux开发越来越多地被大型云提供商的商业利益主导,就像Linux基金会的白金会员所代表的那样,几乎类似于一个共产主义真正的信徒在目睹托洛茨基同志残暴地惩罚克朗施塔特叛乱的水兵后幻想破灭。寡头政治的铁律仍然一如既往地占据统治地位,而不考虑对进步和平等的借口。
尽管宅基地爱好者的时代已经过去很久了,但这个形象仍然存在。自由软件的社区精神永远不可能从GNU/Linux的DNA中完全抹去,但它可能会越来越多地沦为一种无关紧要的好奇心。理查德·斯塔尔曼(Richard Stallman)、GNU和FSF等人越来越多地被视为一个需要克服的尴尬,他们倾向于更“专业”和“包容”的场景,这很可能意味着专业地向用户展示他们作为圆环中数据条目的位置,而不是像公认的乌托邦白日梦所设想的那样,一个自由独立的自耕农。
现实会很早就把业余黑客搞得面目全非。在2000年4月为“渥太华公民报”采访红帽创始人鲍勃·杨时,他说:
关于这项业务有两大误区,第一个是只有一个Linux操作系统。Linux是Corel和Red Hat等公司生产的600MB操作系统中的16MB内核。Linux可能是你汽车的引擎,但是如果你在车道上弄坏了一个引擎,你就不能开车送你的孩子上学了。
我们的工作是让人们理解这场革命是关于开源软件的,而不是关于Linux的。Linux仅仅是这场运动的代言人。另一个误区是Linux是由18岁的年轻人在地下室里编写的,而实际上大部分都是由专业的工程团队编写的。
另一个先兆是互联网泡沫--被遗忘已久的Linux公司开始利用IPO热潮的数量是巨大的。Turbolinux、LynuxWorks、StorMix、Linuxcare、Cobalt Networks和LinuxOne只是几个突然消失的企业。这是一个LWN.net运行股票上市并仔细涵盖所有与Linux相关的金融工具的时期。然而,那个时代最大的新闻可能是IBM宣布它打算从2001年起在未来三年内在Linux上投资10亿美元。关于IBM的开放源码战略c.2005的讨论可以在这里获得。
在2020年,这款游戏的名字是“本地云”,而埋藏在中间件层下的操作系统旨在将其抽象为一个可复制的应用程序服务器,目的是有效地部署最新、最伟大的方式来做你多年来一直能够做的事情,但作为一项联网服务。在鲁道夫·温斯托克(Rudolf Winestock)的“永恒的大型机”(The Eternal Mainframe)中描述的这种分时共享的回归,带来了作为软件替代品的服务的伦理问题,这让理想主义爱好者感到不安,而老练的专业人士则漠不关心或热情高涨。
多年来,GnomeOS一直是一个高水平的目标,其动机是专业人士对Linux发行版作为应用程序部署中的中间人的不满,它有自己的打包指导方针、策略、对上游默认设置的更改,甚至是“包管理”的概念。托拜厄斯·伯纳德(Tobias Bernard)在“没有‘Linux’平台”一书中表达了这一观点。根据伯纳德的说法,碎片化造成的损害包括下游维修者在DE上“增加了一个永久的码头,桌面上的图标,重新启用了系统托盘”。据推测,这种不负责任的行为可能会导致未来的恐怖,就像人们实际上正在阅读源代码一样。无论哪种方式,实现GnomeOS愿景的最新尝试都涉及Flatpak、OSTree、BuildStream和Freedesktop SDK(本质上是由BuildStream文件制作的发行版)等工具,这似乎也是持续时间最长、最有可能成功的。“传统”发行版将如何适应这个美丽的新世界仍然是一个悬而未决的问题。
然而,GNOME开发者Emmanuele Bassi对统一主义观点最明确的表述是:
如果桌面环境是向集中化和全面的、集成的功能公开的结果,那么使用但不一定对它们有贡献的人,使用他们自己的发布时间表、他们自己在构建系统、选项、编码风格和贡献策略方面的特性,将模块拆分到他们自己的存储库中,应该与这种集中化的努力背道而驰。去中心化造成了项目之间和维护人员之间的冲突;它创建了模块化和API障碍;它产生了依赖关系,这反过来又产生了冲突的可能性,不仅阻碍了贡献,而且阻碍了分发和升级。
自由和开放源码软件的主流分析框架告诉我们,一旦组件达到临界质量,社区就会有意识地最终拆分组件,而不是集中功能;社区成员更喜欢委派和组合具有定义良好的边缘以及组件之间的交互的组件,而不是在定义不佳的抽象层次结构之上堆积功能和API。他们喜欢小组件,因为维护人员重视这样的设计理念,即允许他们为使用其软件的人提供选择,并使有洞察力的用户能够通过松散连接的接口来构建符合其需求的操作系统。
你不知道我需要多少镜头才能在不笑的情况下度过这一切。
具有多个贡献者在多个组件上工作的复杂自由软件项目偏爱较小的模块,因为这使得每个维护人员更容易将东西保存在他们的头脑中,而不会变得彻头彻尾的疯狂。较小的模块使项目更容易与自以为是的维护人员隔离,并让其他自以为是的维护人员绕过他们不喜欢的东西。自包含的模块使利基问题变得容易处理,或者至少它们包含了损害。
当然,如果我们预先宣布这一点,将使每个人的生活变得更容易,因为它将传达一套明确的预期;另一方面,这将产生揭示皇帝衣柜故障的副作用,这意味着我们必须将康威定律的这种意想不到的副作用打扮成“关于选择”,或者“机制,而不是政策”,或者“网络对象模型”。
那么,如果“关于选择”是光谱的一端,那么另一端又是什么呢?也许是一种类似公司的结构,一个项目由少数几个人的愿景驱动,并由其他所有订阅该愿景的人实施-或者至少是通过支付实现愿景的费用来实现的。
当然,当某人决定提出他们的愿景,或者努力实现它,或者说服人们遵循它的时候,就是他们敞开心扉接受批评的时刻。如果你的项目没有一个基本的框架,没有人可以指责你做错了什么;但是,如果你确实有,那么可能性就会消失,剩下的就是人们要努力解决的有形的东西-无论是好是坏。
如果我们进一步使用“革命OS”这个比喻,那么巴西的立场与斯大林在列宁主义(1924年)的基础上捍卫一个先锋政党的需要没有什么不同,而那些因此反对托洛茨基派、季诺维耶夫派和极左翼分子的人则是:“崇拜自发的理论坚决反对赋予自发运动一个有政治意识的、有计划的特征。它反对党走在工人阶级的前面,反对党把群众提高到政治觉悟的高度,反对党领导运动,反对不妨碍运动走自己的路的政治觉醒因素,只赞成党听从自发的运动,拖着运动的尾巴。“。
人们无法劝阻这种有远见卓识的人,就像我们无法劝阻费边协会(Fabian Society)的一名成员放弃全球人道主义政府的美德一样,但到时候,外省乡下人的呼声也不会对对抗它起到任何作用。一个人只能坚忍地听天由命于不可阻挡的必然性的拉动。
专业人士注定要永远从事统一和集成的Linux生态系统这项西西弗式的任务,即使这意味着将内核变成BPF虚拟机的运行时,或者像最近的趋势那样,制造一台由构建和部署管道组成的Rube Goldberg机器,这注定是他们所有的虚荣。业余爱好者注定要在没有人听到的情况下在空地上大喊大叫。在这场悲剧中,唯一的胜利者是混乱和不和谐本身,它伪装成“进步”。所有的保证都是通过不断的革新来实现永久的革命,我们所说的革命是指绕着圈子跑。穿西装打领带的人已经忘记了什么是伊比人,对他们来说,伊皮斯人是被想法迷住的傻瓜,而不是有想法的人。
从2001年到2010年,除了最著名的Upstart例子之外,还有相当多的努力试图补救sysvinit和initscript的问题。查看许多这些旧的邮件列表帖子不仅提供了一个有趣的时间胶囊,而且还表明Linux开发人员在2000年代中期更新守护进程管理和启动的许多动机与systemd出现后所表达的动机有很大的不同。
Henrique de Moraes Holscheh在2002年第三届Debian大会上发表的题为System Init Scripts and the Debian O.S.的论文全面概述了当时的启动管理状况。de Moraes Holscheh查看了NetBSD当时最新的rc.d、Runit、Richard Gooch的simpleinit、Felix von Leitner的minit、jinit和Serel依赖项管理器。
Sysvinit占用大量内存。在ia32系统上,它需要大约1280千比字节的虚拟空间和480千比字节的RSS。在如今的KDE/GNOME时代,这相当于很少的内存,但很难用于内存匮乏的嵌入式系统。
此外,根据他的证词,“大多数system V初始化脚本系统实际上都相当不错。”/etc/rc?.d中的符号链接场以及随之而来的排序问题是主要的抱怨。他提出的所有改进都是渐进式的:用于dpkg维护程序脚本的Invoke-rc.d和policy-rc.d之类的工具以及更容易管理的符号链接场、initscript注册表,以及最激进但也相当假设的建议是用init-Provide、init-pre和init-After这样的依赖指令替换运行级。这个假设的系统仍将基于initscript,并与telinit指令兼容以切换运行级别。任何时候都没有提出任何新的声明性配置格式、对日志记录或事件驱动特性的重大改造-更不用说统一分发版了。
2002年,Richard Gooch在Linux Boot Scripts上为一个名为simpleinit的程序写下了他的建议书。在这里,initscript通过一个名为Need(8)的程序协作解决它们自己的依赖关系,其中init守护进程以任何顺序运行脚本。simpleinit的实现早在几年前就作为util-linux的一部分而存在,后来Matthias S.Brinkmann创建了一个称为simpleinit-MSB的增强。simpleinit-msb仍然是Source Mage GNU/Linux的默认设置。在这里可以找到一个旧的邮件列表讨论,证明它的使用是合理的。更容易与包管理集成、脚本更短、并行性和显式依赖处理被认为是优点。
在simpleinit-msb的来源中,Matthias S.Brinkmann发表了一篇题为“为什么sysvinit设置很糟糕”的咆哮。值得全文引用:
-太难看了!如果你觉得“K123做的事”是个好听的名字,那你就算幸运了,但帮我个忙,在给你的孩子取名时听取你亲戚的建议;-)
-除非你是天皇的黑带,否则你很快就会迷失在SysVinit的设置中。大多数脚本在文件系统中至少有3种表示形式:脚本本身、S符号链接和K符号链接。不过,较高的符号链接计数并不少见。
-您必须手动指定引导脚本的执行顺序。而且您必须对所有引导脚本执行此操作,即使只在重要的情况下指定这些脚本的顺序会更自然。您可能会自欺欺人地认为这是一个控制问题,但老实说,您真的在乎是在系统时钟设置之前还是之后加载键映射吗?如果您想要这种控制,那是可以的,但问题是SysVinit将其强加给您。
-它没有依赖项管理。当然,给服务A指定数字100,给服务B指定数字200将保证A在B之前开始,但有时这还不够。如果服务B需要运行服务A怎么办?SysVinit在这方面帮不了你。它在B之前启动A,但如果A失败,SysVinit仍将尝试运行B。如果挂载文件系统失败,它仍将尝试所有剩余的服务,即使是那些需要写入磁盘的服务。最后,您的系统什么都没有运行,但是SysVinit的运行级程序会很高兴地告诉您,您处于运行级5,正在运行X Window系统和整个网络。
-很难修改。为什么人们要编写花哨的GUI程序来将脚本添加到运行级或从运行级删除脚本?因为手动创建或删除六个符号链接,所有符号链接都具有不同的名称,即使是一个输入错误的字母也可能导致系统崩溃,这简直是疯了。老实告诉我,您不是更喜欢执行“mvrunlevel.3/telnetd unuse/”来卸载telnetd服务,然后再执行“mvunuse/telnetd runlevel.3/”来重新添加它吗?
-它的伸缩性不好。看看LFS:它使用三位数来表示序列号,并且每个服务都有一个数百位的数字。在一个只有10个引导脚本的系统上很有意义,不是吗?问题是,每当您添加引导脚本时,您都需要将其放入序列中,如果您必须在编号为N的脚本和编号为N+1的脚本之间启动引导脚本,则只有一个解决方案:重新索引所有的引导脚本。这让我想起了一段被遗忘已久的过去,当时我还在用带有行号的BASIC解释器编写程序。有时我需要在N行和N+10行之间插入9行以上的行。幸运的是,“renum”命令可以帮我做到这一点。但是当然,您可以为您的符号链接编写一个shell脚本来实现这一点。没问题。SysVinit管理员热爱运动。
-它在自动安装时不能很好地工作。如果要生成允许用户选择PAC的安装工具。
..