首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

浅析 Linux 初始化 init 系统,第 2 部分 UpStart 简介与概念

浅析 Linux 初始化 init 系统,第 2 部分 UpStart 简介与概念

Upstart 简介假如您使用的 Linux 发行版是 Ubuntu,很可能会发现在您的计算机上找不到/etc/inittab 文件了,这是因为 Ubuntu 使用了一种被称为 upstart 的新型 init 系统。
开发 Upstart 的缘由大约在 2006 年或者更早的时候, Ubuntu 开发人员试图将 Linux 安装在笔记本电脑上。在这期间技术人员发现经典的 sysvinit 存在一些问题:它不适合笔记本环境。这促使程序员 Scott James Remnant 着手开发 upstart。
当 Linux 内核进入 2.6 时代时,内核功能有了很多新的更新。新特性使得 Linux    不仅是一款优秀的服务器操作系统,也可以被用于桌面系统,甚至嵌入式设备。桌面系统或便携式设备的一个特点是经常重启,而且要频繁地使用硬件热插拔技术。在现代计算机系统中,硬件繁多、接口有限,人们并非将所有设备都始终连接在计算机上,比如 U 盘平时并不连接电脑,使用时才插入 USB 插口。因此,当系统上电启动时,一些外设可能并没有连接。而是在启动后当需要的时候才连接这些设备。在 2.6 内核支持下,一旦新外设连接到系统,内核便可以自动实时地发现它们,并初始化这些设备,进而使用它们。这为便携式设备用户提供了很大的灵活性。
可是这些特性为 sysvinit 带来了一些挑战。当系统初始化时,需要被初始化的设备并没有连接到系统上;比如打印机。为了管理打印任务,系统需要启动 CUPS 等服务,而如果打印机没有接入系统的情况下,启动这些服务就是一种浪费。Sysvinit 没有办法处理这类需求,它必须一次性把所有可能用到的服务都启动起来,即使打印机并没有连接到系统,CUPS 服务也必须启动。
还有网络共享盘的挂载问题。在/etc/fstab 中,可以指定系统自动挂载一个网络盘,比如 NFS,或者 iSCSI 设备。在本文的第一部分 sysvinit 的简介中可以看到,sysvinit 分析/etc/fstab 挂载文件系统这个步骤是在网络启动之前。可是如果网络没有启动,NFS 或者 iSCSI 都不可访问,当然也无法进行挂载操作。Sysvinit 采用 netdev 的方式来解决这个问题,即/etc/fstab 发现 netdev 属性挂载点的时候,不尝试挂载它,在网络初始化并使能之后,还有一个专门的 netfs 服务来挂载所有这些网络盘。这是一个不得已的补救方法,给管理员带来不便。部分新手管理员甚至从来也没有听说过 netdev 选项,因此经常成为系统管理的一个陷阱。
针对以上种种情况,Ubuntu 开发人员在评估了当时的几个可选 init 系统之后,决定重新设计和开发一个全新的 init 系统,即 UpStart。UpStart 基于事件机制,比如 U 盘插入 USB 接口后,udev 得到内核通知,发现该设备,这就是一个新的事件。UpStart 在感知到该事件之后触发相应的等待任务,比如处理/etc/fstab 中存在的挂载点。采用这种事件驱动的模式,upstart 完美地解决了即插即用设备带来的新问题。
此外,采用事件驱动机制也带来了一些其它有益的变化,比如加快了系统启动时间。sysvinit 运行时是同步阻塞的。一个脚本运行的时候,后续脚本必须等待。这意味着所有的初始化步骤都是串行执行的,而实际上很多服务彼此并不相关,完全可以并行启动,从而减小系统的启动时间。在 Linux 大量应用于服务器的时代,系统启动时间也许还不那么重要;然而对于桌面系统和便携式设备,启动时间的长短对用户体验影响很大。此外云计算等新的 Server 端技术也往往需要单个设备可以更加快速地启动。
UpStart 满足了这些需求,目前不仅桌面系统 Ubuntu 采用了 UpStart,甚至企业级服务器级的 RHEL 也默认采用 UpStart 来替换 sysvinit 作为 init 系统。
Upstart 的特点UpStart 解决了之前提到的 sysvinit 的缺点。采用事件驱动模型,UpStart 可以:
  • 更快地启动系统
  • 当新硬件被发现时动态启动服务
  • 硬件被拔除时动态停止服务
这些特点使得 UpStart 可以很好地应用在桌面或者便携式系统中,处理这些系统中的动态硬件插拔特性。
Upstart 概念和术语Upstart 的基本概念和设计清晰明确。UpStart 主要的概念是 job 和 event。Job 就是一个工作单元,用来完成一件工作,比如启动一个后台服务,或者运行一个配置命令。每个 Job 都等待一个或多个事件,一旦事件发生,upstart 就触发该 job 完成相应的工作。
JobJob 就是一个工作的单元,一个任务或者一个服务。可以理解为 sysvinit 中的一个服务脚本。有三种类型的工作:
  • task job;
  • service job;
  • abstract job;
task job 代表在一定时间内会执行完毕的任务,比如删除一个文件;
service job 代表后台服务进程,比如 apache httpd。这里进程一般不会退出,一旦开始运行就成为一个后台精灵进程,由 init 进程管理,如果这类进程退出,由 init 进程重新启动,它们只能由 init 进程发送信号停止。它们的停止一般也是由于所依赖的停止事件而触发的,不过 upstart 也提供命令行工具,让管理人员手动停止某个服务;
Abstract job 仅由 upstart 内部使用,仅对理解 upstart 内部机理有所帮助。我们不用关心它。
除了以上的分类之外,还有另一种工作(Job)分类方法。Upstart 不仅可以用来为整个系统的初始化服务,也可以为每个用户会话(session)的初始化服务。系统的初始化任务就叫做 system job,比如挂载文件系统的任务就是一个 system job;用户会话的初始化服务就叫做 session job。
Job 生命周期Upstart 为每个工作都维护一个生命周期。一般来说,工作有开始,运行和结束这几种状态。为了更精细地描述工作的变化,Upstart 还引入了一些其它的状态。比如开始就有开始之前(pre-start),即将开始(starting)和已经开始了(started)几种不同的状态,这样可以更加精确地描述工作的当前状态。
工作从某种初始状态开始,逐渐变化,或许要经历其它几种不同的状态,最终进入另外一种状态,形成一个状态机。在这个过程中,当工作的状态即将发生变化的时候,init 进程会发出相应的事件(event)。
表 1.Upstart 中 Job 的可能状态状态名含义Waiting初始状态StartingJob 即将开始pre-start执行 pre-start 段,即任务开始前应该完成的工作Spawned准备执行 script 或者 exec 段post-start执行 post-start 动作Runninginterim state set after post-start section processed denoting job is running (But it may have no associated PID!)pre-stop执行 pre-stop 段Stoppinginterim state set after pre-stop section processedKilled任务即将被停止post-stop执行 post-stop 段
图 1 展示了 Job 的状态机。
图 1. Job’s life cycle其中有四个状态会引起 init 进程发送相应的事件,表明该工作的相应变化:
  • Starting
  • Started
  • Stopping
  • Stopped
而其它的状态变化不会发出事件。那么我们接下来就来看看事件的详细含义吧。
事件 Event顾名思义,Event 就是一个事件。事件在 upstart 中以通知消息的形式具体存在。一旦某个事件发生了,Upstart 就向整个系统发送一个消息。没有任何手段阻止事件消息被 upstart 的其它部分知晓,也就是说,事件一旦发生,整个 upstart 系统中所有工作和其它的事件都会得到通知。
Event 可以分为三类: signal,methods 或者 hooks。
Signals
Signal 事件是非阻塞的,异步的。发送一个信号之后控制权立即返回。
Methods
Methods 事件是阻塞的,同步的。
Hooks
Hooks 事件是阻塞的,同步的。它介于 Signals 和 Methods 之间,调用发出 Hooks 事件的进程必须等待事件完成才可以得到控制权,但不检查事件是否成功。
事件是个非常抽象的概念,下面我罗列出一些常见的事件,希望可以帮助您进一步了解事件的含义:
  • 系统上电启动,init 进程会发送"start"事件
  • 根文件系统可写时,相应 job 会发送文件系统就绪的事件
  • 一个块设备被发现并初始化完成,发送相应的事件
  • 某个文件系统被挂载,发送相应的事件
  • 类似 atd 和 cron,可以在某个时间点,或者周期的时间点发送事件
  • 另外一个 job 开始或结束时,发送相应的事件
  • 一个磁盘文件被修改时,可以发出相应的事件
  • 一个网络设备被发现时,可以发出相应的事件
  • 缺省路由被添加或删除时,可以发出相应的事件
不同的 Linux 发行版对 upstart 有不同的定制和实现,实现和支持的事件也有所不同,可以用man 7 upstart-events来查看事件列表。



返回列表