原文地址:http://www.ibm.com/developerworks/cn/linux/1407_liuming_init1/index.html

本文在原文基础上适当做一些笔记。


什么是 Init 系统,init 系统的历史和现状

首先,Linux系统的初始化init进程经历过两次演变,从sysvinit到UpStart再到systemd,各有特点。


Linux系统的启动首先从BIOS开始,接下来进入bootloader,由bootloader载入内核,然后内核进行初始化。内核初始化的最后一步就是启动pid为1的init进程。这个进程是所有进程的祖先。


init系统能够定义、管理和控制init进程的行为。它负责组织相关的初始化工作,让系统进入用户预设的某种运行级别。仅仅将内核运行起来是没有用的,必须由init系统将系统带入可操作的状态。像是启动一个外壳shell,便可以进行交互,从而让计算机执行一些有意义的任务,或是启动X图形界面。这里的字符界面的shell和X图形界面都是一种预设的运行级别,换句话说,也就是/etc/inittab文件中的各种runlevel。
大多数的Linux发行版的init系统是和System V兼容的,被称为sysvinit。而像Slackware采用的是BSD风格的init系统,Gentoo采用的是自己定制的。Ubuntu和RHEL采用Upstart,(貌似RHEL 7 好像采用的是systemd)Fedora从版本15开始采用systemd。


运行级别

Sysvinit用runlevel来定义运行级别,它首先检查/etc/inittab中是否有initdefault项,来采用默认启动级别。虽然各发行版本对运行级别的定义都不太一样,但0表示关机,1表示单用户,6表示重启则都是一致的。

sysvinit 运行顺序

Sysvinit巧妙地用脚本,文件命名规则和软链接来实现不同的运行级别。首先,sysvinit读取/etc/inittab文件,分析这个文件,得到如下配置信息:
系统需要进入的runlevel
捕获组合键的定义
定义电源fail/restore脚本
启动getty和虚拟控制台


得到配置信息后,sysvinit顺序执行以下步骤,从而将系统初始化为预设的runlevel
/etc/rc.d/rc.sysvinit
/etc/rc.d/rc和/etc/rc.d/rcX.d(X代表runlevel)
/etc/rc.d/rc.local
X Display Manager(若需要的话)


首先运行rc.sysvinit以便执行一些重要的初始化任务,例如:
激活udev和selinux
设置定义在/etc/syctl.conf中的内核参数
设置系统时钟
加载keymaps
使能交换分区
设置主机名
根分区检查和remount
激活RAID和LVM
开启磁盘配额
检查并挂载所有文件系统
清除过期的locks和pid文件


完成这些后根据不同的runlevel进入不同的目录中运行启动脚本。以S开头的就是启动脚本,后面的数字是启动顺序,都是一些软链接文件,真实的脚本文件在/etc/init.d中。

Sysvinit 和系统关闭

系统关闭时是进入对应runlevel的目录中执行以K开头的脚本,按顺序执行。

Sysvinit 的管理和控制功能

此外在系统启动后,管理员还需要对已经的启动的进程进行管理和控制。sysvinit软件包包含一些工具,像是halt、init、killall5、last、lastb、poweroff、shutdown等。

Sysvinit 的小结

sysvinit的优点是简单,service开发人员只要编写启动和停止脚本,将service添加和删除到某个runlevel时只要添加或删除软链接。其次,sysvinit的另一个优点是确定启动顺序,一个运行完再运行下一个,这非常有益于排错,但同时也导致运行效率慢。像upstart和systemd支持并发启动,但排错不易。



Slackware之init系统

而Slackware的init系统则比较特别。首先前文说Slackware是用BSD风格的init系统的。我对BSD风格的init系统不了解,但上网稍微认识了一下后,发现其实不然。BSD风格的init系统是不讨论什么runlevel的,而且启动文件不是/etc/inittab,而是/etc/ttys,这和Slackware不同。其实Slackware也是使用sysvinit的,在安装过程中此软件包为必装项,只不过是按照BSD的风格在用。


Slackware也是从/etc/inittab开始的,关于Slackware的inittab文件我写过一篇博客。地址:http://liandesinian.blog.51cto.com/7737219/1548933

仔细看一下/etc/inittab文件,可以看到Slackware分为7个运行级别。

首先当系统启动时会先运行/etc/rc.d/rc.S脚本,然后若是单用户级别,则运行/etc/rc.d/rc.K,若是多用户级别,则运行/etc/rc.d/rc.M脚本。init会等到一个脚本运行结束后再运行下一个。在这之后,init会启动虚拟控制台tty1-tty6。最后若是进入图形界面运行级别,则会运行/etc/rc.d/rc.4。

Slackware所有的启动脚本都放在/etc/rc.d目录中,而决定运行哪些脚本则是分别在/etc/rc.d/rc.X(X:0,4,6,S,K,M)脚本中定义。而不是像其他sysvinit系统那样分目录使用软链接。Slackware的这种做法简洁又清楚。
当然,Slackware也兼容其他sysvinit风格的启动脚本,在/etc/rc.d中有一个rc.sysvinit脚本用来进行兼容。