我对init的了解有限。我所知道的只是 init 是内核启动后启动的第一个进程,并且分配的进程 ID 为 1。
最近在经历的时候GNU 牧羊人,我注意到下面这句话。
它提供了 SysV-init(或任何其他 init)的服务管理功能的替代品,功能强大且美观基于依赖的系统具有方便的界面。
那么,我想知道这里的基于依赖的系统是什么意思?这是它与流行的 SysV 或 Sysmted init 系统的区别特征吗?
答案1
基于依赖关系的初始化系统是其中服务初始化顺序基于服务内部或与服务一起提供的依赖信息的系统。这与 init 系统形成对比,在 init 系统中,顺序是静态确定的(通常依靠字典顺序,如您在问题中包含的图表所示)。
有些系统可以混合使用这两种方法;例如,在使用 的 Debian 系统上sysvinit
,基于依赖关系的层sysvinit
使用 init 脚本中的 LSB 标头来计算初始化顺序,并通过/etc/rc?.d/
适当命名符号链接来存储它。
答案2
很多人都误解了这一点。这里的一些答案甚至是错误的。
首先,让我们澄清一些用词不当的地方:
init
作为进程 #1 运行的程序和作为另一个进程运行的程序之间的区别rc
可以追溯到第一版 Unix。你们讨论的大部分内容不是由进程 #1 完成的在绝大多数服务/系统管理软件中,Upstart 和 systemd 是例外情况而不是规则。- “sysvinit”不是 AT&T Unix System 5
init
+rc
。它是 Miquel van Smoorenburg 最初为 Minix 编写的克隆init
和rc
系统,具有讽刺意味的是,在 AT&T Unix System 5 诞生几年后很大程度上废除了该系统,用称为服务访问设施的东西取代它。
你问的是服务管理,上述 AT&T Unix 上的服务访问工具 (SAF)、AIX 系统资源控制器 (SRC)、Solaris 服务管理工具 (SMF)、systemd、Upstart、daemontools、daemontools-encore、runit、nosh 工具集服务管理的任务、s6 以及一大堆其他工具集。最初的 AT&T Unix System 5rc
在 SAF 和 SRC 出现之前,只是直接分叉了服务进程,并没有真正做到这一点。管理此后的他们。
Linux 上的van Smoorenburg rc
(来自 Minix)仍然这样做。此外,它最初依赖于手动且相当临时的服务启动/关闭顺序。最初的巨型单一rc
文字在 20 世纪 70 年代和 1980 年代初经历了几次突变,人们仍然可以在这里和那里找到化石(例如rc.local
),到 1990 年代范斯穆伦堡克隆时rc
已经成为一套插入子目录中的脚本/etc/
和一些符号链接场(在 的其他子目录中/etc/
)表示这些脚本执行总体rc
任务的顺序。符号链接场基于优先级方案,其中不同的rc
脚本被分配从 0 到 99 的优先级。(20 世纪 90 年代末有一种符号链接场的替代机制,file-rc,但它也使用了优先级系统.)这管理起来很痛苦,因为没有关于优先级选择的通用约定,并且因为“两个软件都想成为第一”问题。 (讽刺的是,你可以看到使用化石方式做事的人在这个 WWW 站点上询问相关问题之一就在昨天.)
基于依赖的服务管理努力做得更好。服务定义,无论以何种形式,都会列出每个服务的服务内容取决于和应相对于当启动和关闭时。没有“第一”和“最后”,但有前和后, 也需要和与冲突。
21 世纪的大部分时间里,它一直存在于rc
Linux 和 BSD 上的旧式系统中。
- Mewburn
rc
和 OpenRC(都是 21 世纪的发明)从之前的系统中学习,并rc
从一开始就采用了表达不同脚本之间相互依赖关系的方法。在 Mewburn 中,各种脚本(例如、、 和)rc
中的注释系统表达了服务之间的相互依赖性,并且一个名为 的程序根据它们计算在每次引导/关闭开始时运行事物的顺序。rc
REQUIRE
PROVIDE
BEFORE
rcorder
- van Smoorenburg从 Debian 人那里
rc
获得了一个名为的程序。insserv
服务之间的相互依赖性通过包含在各种脚本中作为注释的传统“LSB标头”系统来表达rc
,并且在软件安装/卸载时在符号链接中重写优先级insserv
以反映依赖性。在 21 世纪第一个十年的后半段,Debian 及其一些衍生产品大量采用了这一点。看Debian 维基了解更多。
rc
此外,它从一开始就作为一流的机制存在于许多非服务管理器中,从 Solaris SMF 到 systemd。值得注意的例外是 Upstart、daemontools(以及 daemontools-encore、perp 和 runit)和(几年前)s6。
daemontools、runit 等。所有这些最初都采用“巨大的惊群”方法来解决问题,一遍又一遍地启动和重新启动服务,直到它们都熬夜。有些人用技巧对此进行了稍微调整,例如使服务暂停并且在发生其他情况之前不调用其主服务程序的程序,但基本思想仍然是整个“扫描”目录中的所有内容一下子就开始了。
我长期以来一直认为,通过在基础服务管理之上进行一些分层,可以做得更好,并最终通过以下方式证明了这一点:这样做的具体工具集,将启动“扫描”逻辑从实际的服务管理器中取出,将其移至单独的程序中,并围绕基本 daemontools 服务/监督目录结构构建服务捆绑相互依赖关系的系统。 Laurent Bercot 也通过 s6 的附加功能展示了同样的效果,名为s6-rc。甚至 OpenRC 也证明了这一点,因为它的rc
脚本表达了相互依赖性,并且可以使用外部服务管理器(例如 s6)。
具有讽刺意味的是,新贵实际上被设想为(早在 2005 年)作为 2010 年代一些人的想法新的进行服务管理的方式,代替基于依赖关系的服务管理基于事件的服务管理,服务的启动是为了响应发生的事件而不是作为结果计算一组有序的依赖关系。讨论为什么这个概念最终被拒绝超出了这个答案的范围,人们回去到基于依赖关系的服务管理,但重要的是要认识到,到 2010 年代初,基于依赖关系的服务管理已经常态。新贵开发商认为它已经过时了。 van Smoorenburgrc
通过 Debian 工作获得了它,尽管 Fedora 和 SUSE 并没有真正从 Debian 中继承这一点。 Mewburnrc
和 OpenRC 从一开始就拥有它。 systemd 即将随之被发明。 Solaris、Illumos 等。与 SMF 一起使用。等等。
除了 runit 和 Upstart 之外,这并不是一个显着特征。这过去是、现在也是常态。这是其他人已经做过或正在做的事情,甚至在 GNU Shepherd 成立之初也是如此。 GNU dmd,现在称为 GNU Shepherd,于 2003 年发明。Debian 于 2002 年开始转向insserv
;理查德·古奇 (Richard Gooch)need
在 2002 年写过一篇文章; Mewburnrc
于 2000 年发明,Luke Mewburn 关于该主题的原始论文解释了如何使用比文件名中编码的优先级系统更好的东西来表达依赖关系是一种设计功能。
进一步阅读
- 乔纳森·德博因·波拉德 (2018)。
/etc/rc.local
已成为过去。。常见答案。 - 乔纳森·德博因·波拉德 (2015)。System 5 的已知问题
rc
。常见答案。 - 乔纳森·德博因·波拉德 (2018)。 Unix 服务访问工具。常见答案。
- 虚拟现实(2015-09-05)。现代初始化系统的历史(1992-2015)。 darknedgy.net。
答案3
这是它与流行的 SysV 或 Sysmted init 系统的区别特征吗?
嗯,不是来自系统,它“实现了一个精心设计的交易基于依赖的服务控制逻辑”(重点是我的)。
我会引用 Lennart Poettering 的话systemd 的基本原理这里:
所有这些单元之间都可以具有相互依赖性(积极和消极,即“需要”和“冲突”):设备可以对服务具有依赖性,这意味着一旦设备可用,就会启动特定服务。挂载对挂载它们的设备有隐式依赖。挂载还获得对其前缀挂载的隐式依赖关系(即挂载 /home/lennart 隐式获取添加到 /home 挂载的依赖关系)等等。
在旧的 sysv 时代,没有一流的方法来表达系统服务之间的依赖关系。它在使用脚本排序、提交标头等方面是硬性的,但这样的系统本质上是脆弱的。这使得正确订购变得特别困难(例如,该服务需要该网络接口和该安装点启动,但该安装点需要其他一些设备启动等等 - 考虑使用数字手动订购/etc/rcX.D/
)中脚本的前缀。
通过使用适当的系统来表达单元之间的依赖关系,我们可以让 init 系统得出正确的顺序,因为它拥有有关服务如何相互关联以及与系统如何关联的所有信息。
为了进行对比和比较,请考虑 Upstart,它不是直接使用依赖项,而是依赖于事件:
Upstart 通过这些事件进行服务序列化:如果触发 syslog-started 事件,则这将用作启动 D-Bus 的指示,因为它现在可以使用 Syslog。然后,当 dbus-started 被触发时,NetworkManager 就会启动,因为它现在可能使用 D-Bus,等等。
人们可以说,通过这种方式,管理员或开发人员所理解的实际逻辑依赖树被转换并编码为事件和操作规则:管理员/开发人员意识到的每个逻辑“a 需要 b”规则都变成了“当 b 启动时启动 a”加上“当 b 停止时停止 a”。
答案4
在这种情况下,“基于依赖”意味着它通常在运行时查看哪些服务实际需要其他服务提供的功能,并且通常零用户干预,而不是依赖其他因素来确定服务启动的顺序 9(例如词法顺序)文件名)。
这与原始的 SVR4 init 安排形成鲜明对比,该init.d
安排是大多数 Linux 发行版在 systemd 出现之前使用的方法,以及一些较旧的 BSDrc.d
方法,所有这些方法都需要用户/管理员手动提供启动服务的顺序,或者通过手动设置文件名或变量,或者通过运行工具来扫描脚本中嵌入的元数据来执行此操作。
目前正在积极使用的其他基于依赖性init
和服务监管系统的示例包括:
- OpenRC:由 Alpine 和 Gentoo 使用。在 init 脚本本身中使用特殊的函数定义和宏来获取依赖信息(这实际上相当强大,因为您可以表达服务之间的条件依赖关系,例如仅
lvmetad
在 LVM 配置中启用时才需要运行 LVM 设置),并支持“通用”依赖项(例如需要一个正在运行的 syslog 守护进程,但不关心正在运行的是哪一个)。 - Monit:服务主管,
init
在某些情况下可以替代。运行时依赖项计算是否基于为其监视的实体定义的依赖项(在本例中为“实体”而不是服务,因为您可以监视并依赖于网络上其他位置的外部服务或系统上的文件和目录等内容,而不仅仅是服务) 。 init
Upstart: Ubuntu 的旧替代系统。 Upstart 没有直接进行依赖项跟踪,而是让服务根据事件触发状态更改,然后将其用于提供有效的基于依赖项的服务启动顺序。- Systemd:基于依赖关系的排序的当前类型示例(经常被
init
其粉丝错误地声称是第一个此类系统)。在运行时进行依赖性计算,并提供一些功能,这些功能实际上可以减轻某些情况下严格依赖性跟踪的需要。