8.2. init 进程

程序 init 是进程 ID 为 1 的进程,负责以要求的方式初始化系统。init 具有特殊作用。它由内核直接启动,并且信号 9(该信号通常会停止进程)对它不起作用。所有其它程序由 init 直接启动,或由它的其中一个子进程启动。

init 在 /etc/inittab 文件中进行集中配置,其中运行级别已定义(请参见第 8.2.1 节 “运行级别”)。该文件还指定了在每个级别有哪些服务和守护程序可用。根据 /etc/inittab 中的项,init 将运行若干个脚本。为了清楚起见,这些称作 init 脚本的脚本都位于目录 /etc/init.d 中(请参见第 8.2.2 节 “Init 脚本”)。

启动和关闭系统的整个过程是由 init 维护的。从这一点来看,可以将内核视为一个后台进程,其任务是维护所有其它进程,以及根据其它程序的请求来调整 CPU 时间和硬件访问。

8.2.1. 运行级别

在 Linux 中,运行级别定义了系统如何启动以及正在运行的系统中有哪些服务可用。在引导后,系统会按照 /etc/inittab 中的 initdefault 行所定义的方式启动。通常是 35。请参见 表 8.1 “可用运行级别”。也可以选择在引导时指定运行级别(例如,在引导提示符处指定)。任何不直接由内核本身求值的参数均将被传递给 init。

表 8.1. 可用运行级别

运行级别

说明

0

系统暂停

S

单用户方式;从引导提示符进入,仅限 US 键盘映射

1

单用户方式

2

没有远程网络的本地多用户方式(NFS 等)

3

有网络的完全多用户方式

4

未使用

5

有网络和 X 显示管理器的完全多用户方式 — KDM、GDM 或 XDM

6

系统重引导

[Important]避免运行级别 2 与通过 NFS 装入的分区

如果您的系统通过 NFS 装入了 /usr 分区,则不应使用运行级别 2。如果程序文件或库丢失,系统可能会异常运行,因为 NFS 设备不能以运行级别 2(没有远程网络的本地多用户方式)提供。

要在系统运行时更改运行级别,请输入 telinit 和作为参数的相应数字。仅允许系统管理员执行该操作。下表总结了运行级别区域中最重要的命令。

telinit 1shutdown now

系统更改为单用户方式。该方式用于系统维护和管理任务。

telinit 3

启动了所有基本的程序和服务(包括网络),允许普通用户登录并在不具备图形环境的系统中工作。

telinit 5

启用了图形化环境。通常启动诸如 XDM、GDM 或 KDM 之类的显示管理器。如果启用 autologin,则本地用户便可登录到预先选择的窗口管理器(GNOME 或 KDE 或其它任何窗口管理器)中。

telinit 0shutdown -h now

系统暂停。

telinit 6shutdown -r now

系统暂停后重引导。

运行级别 5 是所有 SUSE Linux 标准安装中的默认运行级别。提示用户使用图形界面登录,或者默认用户将自动登录。如果默认运行级别是 3,必须按照 第 14 章 X 窗口系统 中的说明正确配置 X 窗口系统,才能将运行级别切换为 5。完成切换后,请通过输入 telinit 5 来检查系统是否以预期方式运行。如果一切合乎预期,就可以使用 YaST 将默认运行级别设置为 5

通常情况下,更改运行级别时会发生两件事情。首先是启动当前运行级别的停止脚本,同时关闭当前运行级别必需的一些程序。然后启动新运行级别的启动脚本。在大多数情况下,这时会启动多个程序。例如,将运行级别从 3 更改到 5 时会发生以下情况:

  1. 通过输入 telinit 5,管理员 (root) 要求 init 更改为另一个运行级别。

  2. init 根据它的配置文件 (/etc/inittab) 来确定它是否应该以新运行级别作为参数来启动 /etc/init.d/rc

  3. rc 现在调用当前运行级别的所有停止脚本,但仅限新运行级别中没有启动脚本的那些停止脚本。在本例中,这些就是位于 /etc/init.d/rc3.d(旧的运行级别是 3)中以 K 开头的所有脚本。K 后面的数字指定启动的顺序,因为这时要考虑某些依赖性。

  4. 最后要启动的是新运行级别的启动脚本。在本例中,这些是位于 /etc/init.d/rc5.d 中以 S 开头的脚本。有关它们的启动顺序的相同过程在这里也适用。

当更改为与当前运行级别相同的运行级别时,init 仅检查 /etc/inittab 的更改,并启动相应的步骤(例如,在另一个界面上启动 getty 所需的步骤)。使用命令 telinit q 也达到到相同的作用。

8.2.2. Init 脚本

/etc/init.d 中有两种类型的脚本:

由 init 直接执行的脚本

仅在引导进程中或在立即关闭系统(电源故障或用户按下了 Ctrl-Alt-Del)时才会发生这种情况。这些脚本的执行是在 /etc/inittab 中定义的。

由 init 间接执行的脚本

这些脚本在更改运行级别时运行并始终调用主脚本 /etc/init.d/rc,后者能够确保相关脚本以正确顺序运行。

所有脚本位于 /etc/init.d 中。引导时运行的脚本是通过指向 /etc/init.d/boot.d 的符号链接调用的。用于更改运行级别的脚本也是通过符号链接从一个子目录(/etc/init.d/rc0.d/etc/init.d/rc6.d)进行调用的。这仅仅是为了清楚起见,并避免在多个运行级别使用时出现重复脚本。因为每个脚本既可以作为启动脚本也可以作为停止脚本来执行,这些脚本必须理解 startstop 参数。这些脚本还必须理解 restartreloadforce-reloadstatus 选项。表 8.2 “可能的 init 脚本选项” 对这些不同的选项进行了解释。由 init 直接运行的脚本没有这些链接。需要时,可以从运行级别独立运行它们。

表 8.2. 可能的 init 脚本选项

选项

说明

start

启动服务。

stop

停止服务。

restart

如果服务正在运行,则首先将其停止,然后重启动。如果服务未在运行,则启动服务。

reload

在不停止和重启动服务的情况下重装载配置。

force-reload

如果服务支持,则重装载配置。否则,要执行的步骤与指定 restart 时相同。

status

显示服务的当前状态。

每个特定于运行级别的子目录中的链接使将脚本与不同的运行级别相关联成为可能。在安装或卸载包时,在程序 insserv(或使用 /usr/lib/lsb/install_initd,它是调用此程序的一个脚本)的帮助下可添加和去除这些链接。有关详细信息,请参见手册页 insserv(8)。

下面分别简要介绍最先或最后启动的引导和停止脚本,并对脚本的维护进行了说明。

boot

在使用 init 直接启动系统时执行。它与选择的运行级别无关,而且仅执行一次。这时将装入 procpts 文件系统,并激活 blogd(引导日志记录守护程序)。如果在更新或安装后首次引导系统,则会启动初始系统配置。

blogd 守护程序是由 boot 和 rc 启动的第一个服务。它在完成以上脚本触发的操作(例如运行很多子脚本)后停止运行。blogd 将任何屏幕输出写入日志文件 /var/log/boot.msg,但前提是必须以可读写方式装入 /var。否则,blogd 将缓冲所有屏幕数据,直到 /var 可用。有关 blogd 的详细信息,请参见手册页 blogd(8)。

脚本 boot 还负责启动 /etc/init.d/boot.d 中名称以 S 开头的所有脚本。在这里,将检查文件系统并根据需要配置回路设备。同时设置系统时间。如果在自动检查和修复文件系统时出错,系统管理员可以在输入根口令后进行干预。最后执行的是脚本 boot.local

boot.local

在这里,输入引导时在更改为某个运行级别之前执行的其它命令。这类似于 DOS 系统上的 AUTOEXEC.BAT

boot.setup

在从单用户方式更改为任何其它运行级别时均执行该脚本,它负责许多基本设置,如键盘布局和虚拟控制台的初始化。

halt

仅当更改为运行级别 0 或 6 时执行该脚本。它在这里作为 haltreboot 来执行。是关闭系统还是重引导系统取决于调用 halt 的方式。

rc

此脚本调用当前运行级别的相应停止脚本和新选择的运行级别的启动脚本。

您可以创建自己的脚本并方便地将它们集成到上面描述的方案中。有关格式化、命名和组织自定义脚本的说明,请参见 LSB 的规范以及 initinit.dinsserv 的手册页。此外还可以参见 startprockillproc 的手册页。

[Warning]有问题的 init 脚本可能会使您的系统暂停

有问题的 init 脚本可能会使您的计算机挂起。应认真编辑这些脚本,如果可能,应在多用户环境中对它们进行严格测试。第 8.2.1 节 “运行级别”中提供了有关 init 脚本的一些有用信息。

要为给定程序或服务创建自定义 init 脚本,请使用文件 /etc/init.d/skeleton 作为模板。以新名称保存此文件的备份,然后根据需要编辑相关程序和文件名、路径及其它详细信息。您可能还需要用自己的部分来增强此脚本,以便 init 过程可以触发正确的操作。

位于顶部的 INIT INFO 块是脚本的一个必需部分,应进行编辑。请参见 例 8.1 “最小的 INIT INFO 块”

例 8.1. 最小的 INIT INFO 块

### BEGIN INIT INFO
# Provides:          FOO
# Required-Start:    $syslog $remote_fs
# Required-Stop:     $syslog $remote_fs
# Default-Start:     3 5
# Default-Stop:      0 1 2 6
# Description:       Start FOO to allow XY and provide YZ
### END INIT INFO
    

INFO 块第一行上 Provides: 后,指定由此 init 脚本控制的程序或服务的名称。在 Required-Start:Required-Stop: 行中,指定在启动或停止服务本身之前需要启动或停止的所有服务。这些信息稍后用于生成脚本名的编号(可以在运行级别目录中找到)。在 Default-Start:Default-Stop: 下,指定应自动启动或停止的服务所在的运行级别。最后,在 Description: 下,提供对相关服务的简短说明。

要创建从运行级别目录 (/etc/init.d/rc?.d/) 到 /etc/init.d/ 中相应脚本的链接,请输入命令 insserv new-script-name。insserv 程序对 INIT INFO 标题进行求值,以便为运行级别目录 (/etc/init.d/rc?.d/) 中的启动和停止脚本创建必要的链接。此程序还负责保证每个运行级别的启动和停止顺序正确无误,方法是在这些链接的名称中包含必要的数字。如果要使用图形工具来创建这样的链接,请按照第 8.2.3 节 “使用 YaST 配置系统服务(运行级别)”中说明的方法使用 YaST 提供的运行级别编辑器。

如果应将已存在于 /etc/init.d/ 中的脚本集成到现有运行级别方案中,请立即通过 insserv 或启用 YaST 的运行级别编辑器中的相应服务在运行级别目录中创建链接。您的更改将在下次重引导时生效 — 新服务将自动启动。

不要手工设置这些链接。如果 INFO 块中出错,则在稍后为其它服务运行 insserv 时将会出现问题。下次运行 insserv 时将除去手工添加的服务。

8.2.3. 使用 YaST 配置系统服务(运行级别)

使用 YaST+系统+系统服务(运行级别)启动此 YaST 模块后,它将显示一个概要,列出所有可用的服务和每个服务的当前状态(禁用或启用)。确定是以简单方式还是以专家方式使用此模块。默认的简单方式足以完成大多数操作。左边的列显示服务的名称,中间的列指示其当前状态,而右边的列则给出简短说明。窗口下部提供了对所选服务的更为详细的说明。若要启用某个服务,请首先在表中选定它,然后选择启用。同样的步骤可用于禁用服务。

图 8.1. 系统服务(运行级别)

系统服务(运行级别)

要对所启动或停止的服务所在运行级别进行更具体的控制,或者更改默认运行级别,请先选择专家方式。将在顶部显示当前默认的运行级别或 “initdefault”(默认情况下将系统引导至的运行级别)。通常情况下,SUSE Linux 系统的默认运行级别是 5(有网络和 X 的完全多用户方式)。运行级别 3(有网络的完全多用户方式)是合适的替代选择。

此 YaST 对话框用于选择一个运行级别(如表 8.1 “可用运行级别”中所列)作为新的默认运行级别。此外,可使用此窗口中的表来启用或禁用各个服务和守护程序。此表列出可用的服务和守护程序,显示它们当前是否已在您的系统上启用,如果已启用,则指示它们用于哪些运行级别。用鼠标选择其中的一行后,请单击表示运行级别(B012356S)的复选框来确定所选服务或守护程序的运行级别。最初,未对运行级别 4 进行定义,目的是供用户创建自定义运行级别。表概要下方提供了当前所选服务或守护程序的简要说明。

启动、停止或刷新来确定是否应激活某服务。刷新状态用来检查当前状态。设置或重设置用于选择是将更改应用到系统,还是恢复启动运行级别编辑器之前存在的设置。选择完成即可将已更改的设置保存到磁盘。

[Warning]有问题的运行级别设置可能会对您的系统造成损害

有问题的运行级别设置可能会导致系统无法使用。在应用您的更改之前,请确保您清楚这些设置可能产生的结果。