Linux基础知识 ·

init及其配置文件/etc/inittab 与 runlevel

[隐藏]

在核心加载完毕、进行完硬件侦测与驱动程序加载后,此时你的主机硬件应该已经准备就绪了 (ready) , 此时核心会主动的呼叫第一支程序,那就是 /sbin/init (systemV 现已逐渐被替换为 systemd)。使用 ps 命令查看,你就会发现 init 的 PID 号码是 1 。 /sbin/init 最主要的功能就是准备软件运行的环境,包括系统的主机名称、网络配置、语系处理、文件系统格式及其他服务的启动等。 而所有的动作都会通过 init 的配置文件,亦即是 /etc/inittab 来规划,而 inittab 内还有一个很重要的配置项目,那就是默认的 runlevel (启动运行等级) 啦!

Run level:运行等级

Linux 就是由配置 run level 来规定系统使用不同的服务来启动,来让 Linux 的使用环境不同。基本上,其依据有无网络与有无 X Window 而将 run level 分为 7 个等级,分别是:

  • 0 - halt (系统直接关机)
  • 1 - single user mode (单用户维护模式,用在系统出问题时的维护)
  • 2 - Multi-user, without NFS (类似底下的 runlevel 3,但无 NFS 服务)
  • 3 - Full multi-user mode (完整含有网络功能的纯文字模式,也叫多用户模式)
  • 4 - unused (系统保留功能)
  • 5 - X11 ( 与 runlevel 3 类似,但加载使用 X Window,可以使用图形化界面 )
  • 6 - reboot (重新启动)

由于 run level 0, 4, 6 不是关机、重新启动就是系统保留的,所以:『 您当然不能将默认的 run level 配置为这三个值 』, 否则系统就会不断的自动关机或自动重新启动....

/etc/inittab 的内容

我们启动是通过 /etc/inittab 的配置来取得系统的 run level ! 那么我们来看一下 /etc/inittab 的内容。

如果需要改变默认 run level 只用将 id:3:initdefault: 中的 3 级别改为所需级别就好。

 

/etc/inittab中,有几个特殊的特性,允许init重新激活特殊事件。这些特殊特性都是用第三个字段中的特殊关键字标记出来的。比如:

1. powerwait:允许init在电源被切断时,关闭系统。其前提是具有U P S和监视U P S并通知init电源已被切断的软件。

2. ctrlaltdel:允许init在用户于控制台键盘上按下C t r l + A l t + D e l组合键时,重新启动系统。注意,如果该系统放在一个公共场所,系统管理员可将C t r l + A l t + D e l组合键配置为别的行为,比如忽略等。

3. sysinit:系统启动时准备运行的命令。比如说,这个命令将清除/tmp。

上面列出的特殊关键字尚不完整。其他的关键字及其使用详情,可参考你的inittab手册页。

一个重要的运行级别就是单用户模式(运行级别1),该模式中,只有一个系统管理员使用特定的机器,而且尽可能少地运行系统服务,其中包含登录。单用户模式对少数管理任务(比如在/usr分区上运行fsck)而言,是很有必要的,因为这需要卸载分区,但这是不可能的,除非所有的服务系统已被杀死。

一个正在运行的系统可以进入单用户模式,具体做法是利用init,请求运行级别1。内核启动时,在内核命令行指定single或emergency关键字,就可进入运行级别1了。内核同时也为init指定命令行, init从关键字得知自己不应该采用默认的运行级别(内核命令行的输入方式和你启动系统的方式有关)。

有时,以单用户模式进行启动是必要的,这样一来,用户在装入分区之前,或至少在装入分散的/usr分区之前,能手工运行fsck(在分散的文件系统上,任何活动都可能使其更为分散,所以应该尽可能地运行fsck)。

如果自动化的fsck在启动时失败了,启动脚本init的运行将自动进入单用户模式。这样做是为了防止系统使用不连贯的文件系统,这个文件系统是f s c k不能自动修复的。文件系统不连贯的现象极为少见,而且通常会导致硬盘的不连贯或实验性的内核释放,但最好能做到防患于未然。

由于安全上的考虑,在单用户模式下,启动外壳脚本之前,配置得当的系统会要求用户提供root密码。否则,它会简单地为L I L O输入合适的一行代码,以 root 的身份登录(当然,如果/etc/passwd已经由于文件系统的问题而不连贯了,就不适合这里的原则了,为对付这种情况,你最好随时准备一张启动盘)。

不同的运行级有不同的用处,也应该根据自己的不同情形来设置。例如,如果丢失了root口令,那么可以让机器启动进入单用户状态。在启动后的 lilo 提示符下输入:init=/bin/sh rw 使机器进入运行级1 ,并把 root 文件系统挂为读写。他会跳过所有系统认证,让你可以使用 passwd 程序来改变root口令,然后启动到一个新的运行级。

init 的处理流程

事实上 /etc/inittab 的配置也有点类似 shell script ,因为该文件内容的配置也是一行一行的从上往下处理的, 因此我们可以知道 CentOS 的 init 依据 inittab 配置的处理流程会是:

1、先取得 runlevel 即默认运行等级的相关等级;

2、使用 /etc/rc.d/rc.sysinit 进行系统初始化

3、运行 runlevel 对应的环境定义脚本 /etc/rc.d/rc*.d/*

4、运行用户定义的其他配置,没有就略过。

5、启动终端机让用户登录

 

规定启动的默认 run level 是纯文字的 3 号或者是具有图形界面的 5 号 ,可经由 『 id:3:initdefault: 』那个数字来决定!

init 在取得 run level 之后,接下来要干嘛? 上面 /etc/inittab 文件内容不是有提到 sysinit 吗?准备初始化系统了吧!

init 处理系统初始化流程 (/etc/rc.d/rc.sysinit)

在开始加载各项系统服务之前,得先做好整个系统环境,系统主要利用 /etc/rc.d/rc.sysinit 这个 shell script 来配置好系统环境的。这个文件的文件在不同的 distributions 当中都不相同, 例如 SuSE server 9 就使用 /etc/init.d/boot 与 /etc/init.d/rc 来进行的。 所以,最好还是自行查看官方说明。

/etc/rc.d/rc.sysinit 的主要的工作大致有这几项:

1、取得网络环境与主机类型:读取网络配置文件 /etc/sysconfig/network ,取得主机名称与默认网关 (gateway) 等网络环境。

2、测试与挂载内存设备 /proc 及 U盘 设备 /sys:除挂载内存设备 /proc 之外,还会主动侦测系统上是否具有 usb 的设备, 若有则会主动加载 usb 的驱动程序,并且尝试挂载 usb 的文件系统。

3、决定是否启动 SELinux :SELinux 在此时进行一些检测, 并且检测是否需要帮所有的文件重新编写标准的 SELinux 类型 (auto relabel)。

4、启动系统的随机数产生器:随机数产生器可以帮助系统进行一些口令加密演算的功能,在此需要启动两次随机数产生器。

5、配置终端机 (console) 字形:

6、配置显示启动过程中的欢迎画面 (text banner);

7、配置系统时间 (clock) 与时区:需读入 /etc/sysconfig/clock 配置值。

8、周边设备的侦测与 Plug and Play (PnP) 参数的测试:根据内核在启动时侦测的结果 (/proc/sys/kernel/modprobe ) 开始进行 ide / scsi / 网络 / 声卡 等周边设备的侦测,以及利用已加载的内核模块进行 PnP 装置的参数测试。

9、使用者自定义模块的加载使用者可以在 /etc/sysconfig/modules/*.modules 加入自定义的模块,则此时会被加载到系统当中

10、加载核心的相关配置:系统会主动去读取 /etc/sysctl.conf 这个文件的配置值,使内核功能成为我们想要的样子。

11、配置主机名称与初始化电源管理模块 (ACPI)

12、初始化软件磁盘阵列:主要是通过 /etc/mdadm.conf 来配置好的。

13、初始化 LVM 的文件系统功能

14、以 fsck 检验磁盘文件系统:会进行 filesystem check

15、进行磁盘配额 quota 的转换 (非必要):

16、重新以可读写模式挂载系统磁盘:

17、启动 quota 功能:所以我们不需要自订 quotaon 的动作

18、启动系统虚拟随机数产生器 (pseudo-random):

19、清除启动过程当中的缓存文件:

20、将启动相关信息加载到 /var/log/dmesg 文件中。

在 /etc/rc.d/rc.sysinit 将基本的系统配置数据都写好了,也就将系统的数据配置完整了!基本上,在这个文件当中所进行的很多工作的默认配置文件,其实都在 /etc/sysconfig/ 当中。

而如果想要知道启动的过程中发生的事情,那么可以是用『 dmesg 』命令来查看。

在 CentOS 的这个过程当中,如果我们想要加载核心模块的话, 可以将整个模块写入到 /etc/sysconfig/modules/*.modules 当中,在该目录下, 只要记得文件名最后是以 .modules 结尾即可。 这个过程是非必要的,因为目前的默认模块实在已经很够用了,除非是您的主机硬件实在太新了, 非要自己加载新的模块不可,否则,在经过 /etc/rc.d/rc.sysinit 的处理后, 你的主机系统应该完整的启动了!就等著你将系统相关的服务与网络服务启动了!

系统自启动服务 /etc/rc.d/rc N

加载内核让整个系统准备接受命令来工作,再经过 /etc/rc.d/rc.sysinit 的系统模块与相关硬件信息的初始化后, CentOS 系统应该已经顺利工作了。

只是,我们还得要启动系统所需要的各项『服务』!这样主机才能提供我们相关的网络或者是主机功能! 这个时候,依据我们在 /etc/inittab 里面提到的 run level 配置值,就可以来决定启动的服务项目了。 举例来说,使用 run level 3 当然就不会启动 X Window 的相关服务了。

而各个不同的 run level 需要启动的服务的 scripts 放置路径:

runlevel 0 在 /etc/rc.d/rc0.d/

runlevel 1 在 /etc/rc.d/rc1.d/

runlevel 2 在 /etc/rc.d/rc2.d/

runlevel 3 在 /etc/rc.d/rc3.d/

runlevel 4 在 /etc/rc.d/rc4.d/

runlevel 5 在 /etc/rc.d/rc5.d/

runlevel 6 在 /etc/rc.d/rc6.d/

上面提到的就是各个 run level 要运行的各项脚本放置路径!主要是通过 /etc/rc.d/rc 这个命令来处理相关任务!

由我使用默认的 runlevel 3 ,因此我们主要针对此解释: /etc/rc.d/rc 3 的意义是这样的 :

  • 通过外部第一号参数 ($1) 来取得想要运行的脚本目录。亦即由 /etc/rc.d/rc 3 可以取得 /etc/rc3.d/ 这个目录来准备处理相关的脚本程序;
  • 找到 /etc/rc3.d/K??* 开头的文件,并进行『 /etc/rc3.d/K??* stop 』的动作;
  • 找到 /etc/rc3.d/S??* 开头的文件,并进行『 /etc/rc3.d/S??* start 』的动作;

通过上面的说明我们可以知道所有的项目都与 /etc/rc3.d/ 有关,那么我们就来看下这个目录的内容:

在这个目录下的文件主要具有几个特点:

  • 文件名全部以 Sxx 或 Kxx ,其中 xx 为数字,且这些数字在文件之间是有相关性的!
  • 全部是链接文件,链接到 stand alone 服务启动的目录 /etc/init.d/ 去

服务的启动主要是以『/etc/init.d/服务文件名 {start,stop}』来启动与关闭的,那么通过刚刚 /etc/rc.d/rc 程序的解说,我们可以清楚的了解到了 /etc/rc5.d/[SK]xx 其实就是跑到 /etc/init.d/ 去找到相对应的服务脚本, 然后分别进行 start (Sxx) 或 stop (Kxx) 的动作而已!

所以,如果有想要启动该 runlevel 时就运行的服务,那么利用 Sxx 并指向 /etc/init.d/ 的特定服务启动脚本后, 该服务就能够在启动时启动啦!

因为各不同的服务其实互有依赖关系的。举例来说,如果要启动 WWW 服务,总是得要有网络,所以 /etc/init.d/network 就会比较先被启动!所以 K 与 S 后面要有数字,那个就是运行的顺序!最后一个被运行的项目就是 S99local ,亦即是:/etc/rc.d/rc.local 这个文件!

在完成默认 runlevel 指定的各项服务的启动后,如果我还有其他的动作想要完成时,可以直接将他写入 /etc/rc.d/rc.local , 那么该工作就会在启动的时候自动被加载!而不必等我们登陆系统去启动!

启动过程主要配置文件 /etc/sysconfig

我们在 /sbin/init 的运行过程中有谈到许多运行脚本,包括 /etc/rc.d/rc.sysinit 以及 /etc/rc.d/rc 等等, 其实这些脚本都会使用到相当多的系统配置文件,这些启动过程会用到的配置文件则大多放置在 /etc/sysconfig/ 目录下。 同时,由于内核还是需要加载一些驱动程序 (内核模块),此时系统自订的设备与模块对应文件 (/etc/modprobe.conf) 就显的挺重要!

关于模块: /etc/modprobe.conf

虽然内核提供的默认模块已经很足够我们使用了,但是,某些条件下我们还是得对模块进行一些参数的规划, 此时就得要使用到 /etc/modprobe.conf 了。

这个文件大多在指定系统内的硬件所使用的模块啦!这个文件通常系统是可以自行产生的,所以你不必手动去订正他! 不过,如果系统捉到错误的驱动程序,或者是你想要使用升级的驱动程序来对应相关的硬件配备时, 你就得要自行手动的处理一下这个文件了。更多的相关说明,请 man modprobe.conf 。

/etc/sysconfig/*

整个启动的过程当中,读取的一些服务的相关配置文件都是记录在 /etc/sysconfig 目录下的!我们找几个重要的文件来谈谈:

  • authconfig
    这个文件主要在规范使用者的身份认证的机制,包括是否使用本机的 /etc/passwd, /etc/shadow 等, 以及 /etc/shadow 口令记录使用何种加密演算法,还有是否使用外部口令服务器提供的帐号验证 (NIS, LDAP) 等。 系统默认使用 MD5 加密演算法,并且不使用外部的身份验证机制;
  • clock
    此文件在配置 Linux 主机的时区,可以使用格林威治时间(GMT),也可以使用本地时间 (local)。基本上,在clock 文件内的配置项目『 ZONE 』所参考的时区位于 /usr/share/zoneinfo 目录下的相对路径中。而且要修改时区的话,还得将 /usr/share/zoneinfo/Asia/Taipei 这个文件复制成为 /etc/localtime 才行!
  • i18n
    i18n 在配置一些语系的使用方面,例如最麻烦的字符界面下的日期显示问题! 如果你是以中文安装的,那么默认语系会被选择 zh_CN.UTF8 ,所以在纯字符界面之下, 你的文件日期显示可能就会呈现乱码!这个时候就需要更改一下这里啦!更动这个 i18n 的文件,将里面的 LC_TIME 改成 en 即可!
  • keyboard & mouse
    keyboard 与 mouse 就是在配置键盘与鼠标的布局;
  • network
    network 可以配置是否要启动网络,以及配置主机名称还有网关 (GATEWAY) 这两个重要信息!
  • network-scripts/
    至于 network-scripts 里面的文件,则是主要用在配置网卡。

总而言之一句话,这个目录下的文件很重要的!启动过程里面常常会读取到的!

Run level 的切换

事实上,与 run level 有关的启动其实是在 /etc/rc.d/rc.sysinit 运行完毕之后。也就是说,其实 run level 的不同仅是 /etc/rc[0-6].d 里面启动的服务不同而已。

不过,依据启动是否自动进入不同 run level 的配置,我们可以说:

  1. 要每次启动都运行某个默认的 run level ,则需要修改 /etc/inittab 内的配置项目, 亦即是『 id:3:initdefault: 』里的数字;
  2. 如果仅只是暂时变更系统的 run level 时,则使用 init [0-6] 来进行 run level 的变更。 但下次重新启动时,依旧会是以 /etc/inittab 的配置为准。

假设原本我们是以 run level 5 登陆系统的,但是因为某些因素,想要切换成为 run level 3 时, 运行『 init 3 』即可切换。

不同的 run level 只是加载的服务不同罢了, 亦即是 /etc/rc5.d/ 还有 /etc/rc3.d 内的 Sxxname 与 Kxxname 有差异而已。 所以说,当运行 init 3 时,系统会:

  • 先比对 /etc/rc3.d/ 及 /etc/rc5.d 内的 K 与 S 开头的文件;
  • 在新的 runlevel 亦即是 /etc/rc3.d/ 内有多的 K 开头文件,则予以关闭;
  • 在新的 runlevel 亦即是 /etc/rc3.d/ 内有多的 S 开头文件,则予以启动;

也就是说,两个 run level 都存在的服务就不会被关闭啦!如此一来,就很容易切换 run level 了, 而且还不需要重新启动呢!查看目前的 run level 直接在 bash 当中输入 runlevel 即可!

参与评论