init
init(为英语:initialization的简写)是Unix和类Unix系统中用来产生其它所有进程的程序。它以守护进程的方式存在,其进程号为1。Linux系统在开机时加载Linux内核后,便由Linux内核加载init程序,由init程序完成余下的开机过程,比如加载执行级别,加载服务,启动Shell/图形化界面等等。
Unix系列中(如System III和System V)init的作用,和研究中的Unix和BSD派生版本相比,发生了一些变化。大多数Linux发行版是和System V相兼容的,但是一些发行版如Slackware采用的是BSD风格,其它的如Gentoo是自己定制的。后来Ubuntu[1][2]和其他一些发行版采用Upstart[3]来代替[4]传统的init进程。至2015年,大部分Linux发行版都已采用新的systemd替代System V和Upstart,但systemd向下兼容System V。
BSD风格
BSD init运行存放于/etc/rc的初始化shell脚本,然后启动基于文本模式的终端(getty)或者基于图形界面的终端(窗口系统,如X)。这里没有运行模式的问题,因为文件rc决定了init如何执行。
值得注意的是,现代的BSD派生系统一直支持使用rc.local文件的方式,它将在正常启动过程接近最后的时间以子脚本的方式来执行。这样做减少了整个系统无法启动的风险。然后,第三方软件包可以将它们独立的start/stop脚本安装到一个本地的rc.d目录中(通常这是由ports collection/pkgsrc完成的)。FreeBSD和NetBSD现在默认使用rc.d,该目录中所有的用户启动脚本,都被分成更小的子脚本,和SysV类似。rcorder通常根据在rc.d目录中脚本之间的依赖关系来决定脚本的执行顺序。
SysV风格
System V init检查'/etc/inittab'文件中是否含有'initdefault'项。这告诉init系统是否有一个默认运行模式。如果没有默认的运行模式,那么用户将进入系统控制台,手动决定进入何种运行模式。
运行模式
System V中运行模式描述了系统各种可能的状态。通常会有8种运行模式,即运行模式0到6和S或者s。其中运行模式3为"保留的"运行模式:
- 0.关机
- 1.单用户模式
- 6.重启
除了模式0,1,6外,每种Unix和Unix-like系统对运行模式的定义不太一样。通常在/etc/inittab文件中定义了各种运行模式的工作范围。
目前绝大多数Linux发行版已经基于新的systemd,systemd一般不再使用/etc/inittab文件,也使用新的target取代System V的执行等级,但仍然兼容System V的执行等级。若要设置系统默认的执行模式,需要使用systemctl default targetname.target命令。
默认的运行模式
操作系统 | 默认的运行模式 |
---|---|
AIX | 2 |
Arch Linux | 3 |
CentOS | 3 |
Debian GNU/Linux | 2 [5] |
Gentoo Linux | 3 |
Mandriva Linux | 5 |
Mac OS X | 3 |
Red Hat Linux / Fedora | 3 or 5 |
Slackware Linux | 3 |
Solaris | 3 [6] |
SUSE Linux | 5 [7] |
Ubuntu | 2 [5] |
上面的表中有两种Linux发行版默认的运行模式为5,模式5是多用户图形环境(X Window System),通常还包括X显示管理器。然而在Solaris操作系统中,模式5被保留用来执行关机和自动切断电源。
大多数操作系统的用户可以用下面的命令来判断当前的运行模式是什么:
$ runlevel
$ who -r
在root权限下,运行telinit或者init命令可以改变当前的运行模式。/etc/inittab文件中设置的默认的运行模式在:initdefault:项中。
跳过init
Linux系统中,现代的bootloader(如LILO或者GRUB),用户可以在初始化过程中最后启动的进程来取代默认的/sbin/init
。
通常是在bootloader环境中通过执行init=/foo/bar
命令。例如,如果执行init=/bin/bash
,启动单用户root的shell环境,无需用户密码。
BSD的变种,大多数平台,bootstrap程序是可以被打断的,然后执行boot -s
命令进入单用户模式。
单用户模式并不没有跳过init,它仍然可以执行/sbin/init
,但是它将使init询问exec()
将要执行的命令(默认为/bin/sh
)的路径,而不是采用正常的多用户启动顺序。如果内核启动时在/etc/ttys
文件中被标注为"不安全"(在某些系统中,当前的"安全模式"可能会有些变化),在允许这种情况(或者回退到单用户模式,如果用户执行CTRL+D
),init将首先询问root用户的密码。
如果该程序退出,内核将在多用户模式下重新执行init。如果系统从多用户模式切换到单用户模式,还将碰到上述的情况。
如果内核加载后,init不能被正常启动,这将导致panic错误,此时系统将不可使用。想要通过init自身来改变init的路径,不同的版本情况不太一样(NetBSD中可执行boot -a
;FreeBSD中利用init_path
命令装载变量)。
其他风格
很多人一直努力地从某些方面改进传统的init守护进程,使它变得更完善。下面列出的是一些改进(排序不分先后):
- SystemStarter:用来替代launchd—AppleMac OS X开启进程
- Initng:完全代替init,可以异步开启进程
- Upstart:完全代替init,可以异步开启进程,曾由Ubuntu等使用
- Service Management Facility:完全代替/重新设计Solaris启动Solaris 10
- runit:跨平台的完全代替init可以并行启动服务
- BootScripts:GoboLinux
- Mudur:用Python写成的init替代品,可以异步开启进程,PardusLinux发行版
- systemd:完全替代init,可并行启动服务,并能减少在shell上的系统开销,相比传统的System V是一大革新,已被大多数Linux发行版所使用
下面列出的项目还没有大范围的使用:
- eINIT,完全代替init,可以异步开启进程,但是完成这个过程可以不使用shell脚本
- svscan 来自daemontools被用作1号进程 - 似乎将被runit替代
- cinit
- twsinit,部分用x86汇编写成,只是用来证明一种概念
- minit
- OpenRC,由Gentoo客制
参考文献
- ^ 存档副本. [2009-06-09]. (原始内容存档于2016-03-06).
- ^ 存档副本. [2009-06-09]. (原始内容存档于2009-06-02).
- ^ 存档副本. [2009-09-12]. (原始内容存档于2009-09-04).
- ^ 存档副本. [2009-06-09]. (原始内容存档于2017-03-14).
- ^ 5.0 5.1 存档副本. [2009-06-09]. (原始内容存档于2021-02-01).
- ^ 存档副本. [2011-06-13]. (原始内容存档于2007-08-18).
- ^ 存档副本 (PDF). [2009-06-09]. (原始内容 (PDF)存档于2006-11-04).
外部链接
- Linux init man page
- FreeBSD init man page(页面存档备份,存于互联网档案馆)
- boot-scripts
- runit(页面存档备份,存于互联网档案馆)
- minit(页面存档备份,存于互联网档案馆)
- rc.d(页面存档备份,存于互联网档案馆)
- busybox(页面存档备份,存于互联网档案馆)
- smf and milestones in Solaris 10(页面存档备份,存于互联网档案馆)
- cinit
- twsinit(页面存档备份,存于互联网档案馆)
- Mudur
参见
- pidof或者killall5,从System V开始在很多发行版中使用的另一种程序