现在的位置: 首页 > 综合 > 正文

Linux启动:用Upstart 代替传统init

2013年08月07日 ⁄ 综合 ⁄ 共 3181字 ⁄ 字号 评论关闭

 长期以来,多数Linux发行版一直在使用Unix System V引入的 init 系统。init 由内核自身产生,任务是启动系统剩余部分,产生并监视所有其它进程,看其是否停止或僵死。System V init 虽然过去一直运行的很好,但它已经有些迟暮了。这就是 Ubuntu 6.10(Edgy Eft) 为什么使用Upstart来代替正在老化的 init 系统。

 设计 Upstart 的目标就是提供一种代替 System V Init (sysvinit)的机制,并与其它已经开发好的 init 替代者目的有所不同。由于现在的桌面计算机和服务器跟十年前相比已经非常不同了,在 Ubuntu 里试图继续运转系统时碰到了一些问题。

 过去,启动时的操作相对简单,比如检查和挂载文件系统。仅支持有限的硬件,上电时连接设备,掉电时断开。内核知道磁盘类型和数目,所以用户空间的启动进程检查和挂载它们毫不费力。

处理新的硬件

 目前的系统必需处理新产生的硬件,它们可以几乎无数目限制地被连接到更复杂的拓扑总线上。这些新设备可以即插即用,使用前不需供电,这意味着当硬件改变时内核接要收到这些信息。发现硬件连接时初始化产生的问题是:没有获取响应的方法。

 遇到无线网络文件系统时,问题更大,我们不仅要等待服务器回应,网络接口自己也要被配置。涉及了通过无线接入点上载固件到卡,从网络服务器上请求IP地址,并登入网页获得Internet 接入。

 针对这些问题的解决办法已经存在。例如,Ubuntu 找到跟文件系统后检测很可能存在的硬件,循环等待预期硬件检测完毕。这些方法依靠启动时等待,而且前提是已知等待的硬件。用户一般希望启动越快越好,启动等待方法无法持久。提前知道硬件信息也许可行,但硬件不断引入新特性打破了该假定。

 我们也许可以通过后台服务程序解决。比如 HP Linux 打印图像系统,它随机器启动而运行,一旦硬件连接,立刻就能够使用。这种方式使得拥有该硬件的用户受益,同时没有这些硬件的用户也没什么损失。但更令人感兴趣的是:仅当硬件连接时才运行服务程序。

 Linux内核在硬件支持上变得越来越好,随着udev的引入,内核驱动核心、用户空间都能知道硬件连接信息。尽管如此,我们仍然依赖为启动程序设置的一些shell脚本。启动进程里关于哪些硬件可用仍做了假定。

试图更新 init 系统的其它方式

 以前替代 init 系统的方法,例如 LSB 规范和 initNG 都聚焦于自动决定脚本顺序,允许脚本并行启动。两者都减轻了开发者的负担, 加快了启动速度。

 其它系统如 Solaris SMF 和 runit,用来解决服务管理问题,允许系统管理员查询和改变正在运行服务的状态和设置。 最后,Apple的 launchd 没有解决任何问题,它提供一个后台代替传统的 Unix 服务:init, cron, inetd等。

 以上系统都未解决我们要解决的问题。我们需要一个init 后台,它可以让我们通过从init系统之外( 如udev )传来的事件对脚本进行选择和排序,而不是仅让脚本自身来决定。实际上,我们需要的init顺序就是要由这些事件和它们自身决定。

 为了避免推倒从来,我们首先看看修改现存方法需要多大精力。Sun SMF 和 Apple launchd 因许可问题直接被排除。解决方案首先要很明确是"free"的,遵循GPL,这样其它发行版本可以采用。

 来看InitNG,udev发布前,问题能否依靠脚本解决受质疑,但我们不认为它比已有方法更好。使用 LSB 规范引入的特性,不需替代 init 后台程序,使用已有init脚本同样可以实现。

 我们需要的系统是:/etc/fstab列出的文件系统在内核检测块设备时检查并加载。同样的,当内核检测网络时配置网卡,若已获取一个 IP 地址,试图加载远程系统。如果当脚本完成后自身产生事件,其它脚本和后台服务就可以开始了。

基于事件的init daemon

 该设计采用的术语是 event-based init daemon。要管理的事情分为两种:脚本和二进制,事件产生触发它们运行或停止。init daemon 在特定点产生特定事件,如启动和关机及其它任何可以改变状态的任务。其它事件可由系统其它部分产生,如udev。

 和基于依赖关系的 init daemons 如initNG 做个比较。它的每个任务对应于一个依赖的列表,需要该任务时启动它所依赖的部分。这就需要一个最终的目标集合,来确保该启动的都启动,一般使用不同的runlevels解决。

 基于依赖关系的 init daemon 启动网络是因为 Apache 需要它,挂载文件系统是因为 Apache 和 gdm 需要这样。如果gdm 或 Apache 启动失败,意味着网络不会有效,除非网络本身是目标集合中的一个。

 基于事件的 init daemon 启动源于一个单独的事件如 "startup" 。它不需 runlevels,只要硬件有效,系统就可启动。对于发行版而言,默认安装更灵活。只要网卡有效网络就会启动。在基于依赖关系的系统里,如果网卡启动时刻未连接 Apache 不会启动。对于基于事件的系统,如果网卡几分钟后插入, Apache 会自动启动。

挂载文件系统的任务流程如下:

   1. "startup" 事件使 udev 后台启动.
   2. udev 后台配置并发出一个 "块设备被添加" 事件给所有新的块设备.
   3. 如果在fstab列表里,"块设备被添加" 事件使得设备被检测和挂载.
   4. 当所有在fstab列出的FHS指定的文件系统被挂载后,发送"fhs-filesystem" 事件.

此外,我们还可配置网络接口并挂载远程文件系统:

   1. udev 后台发送一个 "网络接口被添加" 事件给所有新的网络接口.
   2. 如果在/etc/network/interfaces列表里,"网络接口被添加" 事件使得该接口激活并被配置.
   3. 获取 IP 地址引发 "网络接口激活" 事件被发送.
   4. 设置默认网关引发 "默认网关激活" 事件被发送.
   5. 这些事件使系统尝试挂载远程文件系统,引发 "fhs-filesystem" 事件.

 这些事件链,不管用户如何配置,都使系统相应部分开始运转。如果系统不依赖任何网络文件系统,也不必调整任务的依赖关系,事件会使它自动配置。

定义事件

 事件本身是简单的字符串,配合环境变量传递更详细的信息给处理事件的任务。增加参数或来源来识别增加了什么设备或哪个任务停止了。使用 "initctl" 工具,系统任何部分都能发出事件,或者通过Unix domain 套接字与 init 直接通讯。

 /etc/event.d目录定义了Jobs,最简单的就是:二进制文件名,或shell 代码。稍复杂有:任务开始前或结束后有要执行的shell代码, 以及资源限制和环境设置。Jobs 启动时机:列表中任一事件发生。当另外一事件发生,它们可正常中止自身,停止或重新执行。

 该项目目标是简化系统配置。目前,用户必需自己配置任务,无论是启动时、网络设备激活后、AC电源连接上、或系统休眠时。

 由于事件能够被系统任何其它进程捕获,我们想修改其它后台以便代替执行脚本目录,他们发送事件给 init 然后所有这些任务能在/etc/event.d被配置。未来潜力包括:根据用户习惯执行任务,基于时间的事件代替 cron, anacron 和 atd ,代替 inetd 后台。

 使用 Upstart 可以解决许多问题,使 Linux 更加友好,避免竞争和丑陋的工作区,使系统管理员更轻松。

 Upstart 适用于任何 Linux 发行版来代替 sysvinit。注意,与其它替代机制一样,它也有自己的配置,它不会执行已存在的init 脚本除非配置允许执行。推荐的移植计划是( Ubuntu 所遵循的): 执行已存在的 System V rc 脚本,并且让它负责遗留 init 脚本。

 Edgy Eft 仓库里包含 Upstart,立刻安上它试试 Upstart 吧。
 

抱歉!评论已关闭.