UNIX 和 Linux 系统上的初始化进程
Init 是所有进程的父进程,由内核在系统引导过程中执行。它的主要作用是从存储在/etc/inittab文件中的脚本创建进程。它通常包含条目,这些条目会导致 init 在用户可以登录的每一行上生成 getty。它控制任何特定系统所需的自主进程。
读取此文件后,init 将确定每次运行级别中系统应如何设置,并设置默认运行级别。init 在为系统设置默认运行级别后启动所有后台进程。
运行级别
运行级别是系统的软件配置,它只允许选定的进程组存在。为每个运行级别由 init 生成的进程在/etc/inittab文件中定义。
Init 可以处于这八个运行级别之一:0-6 和S 或s。特权用户可以通过运行telinit来更改运行级别,该命令向init发送适当的信号,告诉它要更改到哪个运行级别。
这里:
0,1,6 - 保留的运行级别。
S 或 s 相同。
7-9 是有效的运行级别,尽管它们并没有真正作为“传统”Unix 变体记录在案,因为它们未使用。运行级别 S 和 s 事实上是相同的。在内部,它们是同一运行级别的别名。
运行级别 | 功能 |
---|---|
0 | 停止系统 |
1 | 使系统进入单用户模式 |
2 | 进入无网络的多用户模式 |
3 | 进入有网络的多用户模式 |
4 | 未使用 |
5 | 进入带有网络和 X 窗口的多用户模式 |
6 | 重启系统 |
S 或 s | 不直接使用。 |
启动
在内核引导序列的最后一步调用 init 后,它会查看文件/etc/inittab中是否存在类型为initdefault的条目。initdefault条目确定系统的初始运行级别。如果没有这样的条目(或根本没有/etc/inittab),则必须在系统控制台中输入运行级别。
更改运行级别
指定所有进程后,init 将等待其子进程之一死亡、电源故障信号或直到telinit发出信号以更改系统的运行级别。当上述三个条件之一发生时,它会重新检查/etc/inittab文件。
init 仍然等待上述三个条件之一发生。为了提供即时响应,telinit Q 或q 命令可以唤醒init以重新检查/etc/inittab文件。
如果 init 不处于单用户模式并收到电源故障信号 (SIGPWR),它将读取文件/etc/powerstatus。然后,它将根据此文件的内容启动命令:
标签 | 描述 |
---|---|
F(AIL) | 电源即将失效,UPS 正在供电。执行powerwait和powerfail条目。 |
O(K) | 电源已恢复,执行powerokwait条目。 |
L(OW) | 电源即将失效,并且 UPS 电池电量不足。执行powerfailnow条目。 |
如果/etc/powerstatus包含除字母F、O或L之外的任何内容,或者不存在,则 init 将表现得好像它读取了字母F。
不鼓励使用SIGPWR和/etc/powerstatus。如果有人想要与init交互,应该使用/dev/initctl控制通道——有关此方面的更多文档,请参阅sysvinit包的源代码。
当请求 init 更改运行级别时,它会向在新运行级别中未定义的所有进程发送警告信号SIGTERM。然后,它等待 5 秒钟,然后再通过SIGKILL信号强制终止这些进程。
Init 假设所有这些进程及其子进程都保留在 init 最初为它们创建的同一进程组中。如果任何进程更改其进程组关联,则它将不会接收这些信号。此类进程需要单独终止。
TELINIT
/sbin/telinit链接到/sbin/init,它接受一个字符参数,并向init发出信号以执行相应的操作。以下参数作为telinit的指令:
标签 | 描述 |
---|---|
0,1,2,3,4,5 或 6 | 告诉init切换到指定的运行级别。 |
a, b, c | 告诉init仅处理/etc/inittab文件中具有运行级别a、b或c的条目。 |
Q 或 q | 告诉init重新检查/etc/inittab文件。 |
S 或 s | 告诉init切换到单用户模式。 |
U 或 u | 告诉init重新执行自身(保留状态)。不会重新检查/etc/inittab文件。如果运行级别不是Ss12345之一,则请求将被静默忽略。 |
它还可以告诉init在向进程发送 SIGTERM 和 SIGKILL 信号之间应等待多长时间。默认值为 5 秒,但这可以使用-t sec选项更改。
只有具有相应权限的用户才能调用telinit。
通过查看其进程 ID,init 二进制文件检查它是否是init或telinit;真正的 init 进程 ID 始终为1。因此,作为快捷方式,可以只使用init代替telinit。