Linux引导过程与故障排除|第2章:SysVinit管理系统启动过程和服务
Synopsis: SysVinit 是 System V 风格的 init 系统,它源于 System V 系列的 UNIX,比 BSD 风格的 init 更灵活,CentOS 5 的初始化程序就采用了它。SysVinit 采用脚本的方式来串行启动服务(速度较慢),一般设置了 6 个运行级别(runlevel),它的默认配置文件 /etc/inittab 中指明了系统启动的默认运行级别,通常是 3 或者 5,以及每个运行级别需要到哪些目录下执行哪些脚本,比如切换到 runlevel 3 时,就会到 /etc/rc3.d/ 目录下先依次停止以 K 开头的服务脚本,再依次启动以 S 开头的服务脚本
1. runlevel
运行级别(runlevel)
定义了 Linux 系统在各级别下,分别需要启动/停止的服务,从而让系统处于某个状态。每个使用 SysVinit
来管理系统启动过程和服务的 Linux 发行版,所定义的运行级别可能会有些许差异,CentOS 5 中有以下 6 个运行级别:
0
: halt (Do NOT set initdefault to this)1
/S
/s
: Single user mode2
: Multiuser, without NFS (The same as 3, if you do not have networking)3
: Full multiuser mode4
: unused5
: X116
: reboot (Do NOT set initdefault to this)
1.1 查看当前运行级别
1.2 切换运行级别
可以使用 /sbin/init
或 /sbin/telinit
命令更改系统的运行级别,详细帮助文档见 man init
# 关机 [root@CentOS ~]# init 0 # 比如当前运行级别为3,想要切换到图形界面 5 [root@CentOS ~]# runlevel N 3 [root@CentOS ~]# init 5 # 重启 [root@CentOS ~]# init 6
更改系统运行级别后,任何未被新运行级别指定的正在运行的进程将被终止(先发送 SIGTERM 信号,再发送 SIGKILL 信号)
2. SysVinit 如何初始化系统
根据 http://www.madmalls.com/blog/post/linux-boot-process/ 文章的描述,Linux 引导过程的最后一步会执行用户空间的第一个进程 init
(PID=1),比如 CentOS 5 中会执行 /sbin/init
,它是 SysVinit 风格的系统初始化进程
2.1 /etc/inittab
/sbin/init
运行后首先会读取它的默认配置文件 /etc/inittab
:
[root@CentOS ~]# cat /etc/inittab # # inittab This file describes how the INIT process should set up # the system in a certain run-level. # id:3:initdefault: # System initialization. si::sysinit:/etc/rc.d/rc.sysinit l0:0:wait:/etc/rc.d/rc 0 l1:1:wait:/etc/rc.d/rc 1 l2:2:wait:/etc/rc.d/rc 2 l3:3:wait:/etc/rc.d/rc 3 l4:4:wait:/etc/rc.d/rc 4 l5:5:wait:/etc/rc.d/rc 5 l6:6:wait:/etc/rc.d/rc 6 # Trap CTRL-ALT-DELETE ca::ctrlaltdel:/sbin/shutdown -t3 -r now # When our UPS tells us power has failed, assume we have a few minutes # of power left. Schedule a shutdown for 2 minutes from now. # This does, of course, assume you have powerd installed and your # UPS connected and working correctly. pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down" # If power was restored before the shutdown kicked in, cancel it. pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled" # Run gettys in standard runlevels 1:2345:respawn:/sbin/mingetty tty1 2:2345:respawn:/sbin/mingetty tty2 3:2345:respawn:/sbin/mingetty tty3 4:2345:respawn:/sbin/mingetty tty4 5:2345:respawn:/sbin/mingetty tty5 6:2345:respawn:/sbin/mingetty tty6 # Run xdm in runlevel 5 x:5:respawn:/etc/X11/prefdm -nodaemon
/etc/inittab
文件描述了在系统启动时和正常运行期间需要启动的进程(通过 man inittab
查看帮助文档),除了注释的每一行内容都是一个 entry
,它的格式为 id:runlevel:action:process
,各字段的含义如下:
id
: 1至4个字符的唯一标识runlevel
: 表明后面的action
应该在哪个运行级别下被执行,可以包含多个运行级别,比如 2345action
: 要执行什么操作process
: 要对哪个程序或脚本应用前面的action
其中 action
字段的有效操作包括:
initdefault
: 指明系统启动时的默认运行级别为 runlevel,一般会省略后面的 processsysinit
: process 在系统引导期间被执行,process 一般是/etc/rc.d/rc.sysinit
脚本(系统初始化),同时会省略 runlevel 字段wait
: 当进入指定的运行级别时,process 将启动一次,并且init
将等待其终止ctrlaltdel
: 当按下 CTRL-ALT-DEL 组合键时,执行后面的 processrespawn
: 当 process 终止时(比如虚拟终端 getty),会重新启动 process
现在,你应该可以很容易就读懂上面 /etc/inittab
文件中的含义啦:
id:3:initdefault:
: 设置系统启动时的默认运行级别为 3(如何修改默认运行级别? 只需要将 3 修改为其它运行级别即可)si::sysinit:/etc/rc.d/rc.sysinit
: 表示系统启动时要运行此脚本进行初始化工作l3:3:wait:/etc/rc.d/rc 3
: 当进入运行级别 3 时,执行一次/etc/rc.d/rc 3
2.2 /etc/rc.d/rc.sysinit
这个 Shell 脚本在系统启动时被执行一次,内容还挺多的,会 Shell 脚本的慢慢看就明白了,它大致在做以下几个工作:
- 检查 SELinux 的设置,如果
SELINUX=enforcing
则开启它,SELINUX=disabled
则关闭它 - 打印文字横幅
Welcome to CentOS
- 设置系统时钟
- 设置控制台的日志级别,
/bin/dmesg -n $LOGLEVEL
- 初始化硬件,使用
/sbin/modprobe
去加载各驱动内核模块,如果用户有自定义的内核模块/etc/sysconfig/modules/*.modules
,也依次加载 - 设置内核参数
sysctl -e -p /etc/sysctl.conf >/dev/null 2>&1
- 设置主机名
- 如果有软件 RAID 或 LVM,则激活挂载它们
- 以
读写(rw, read write)
的方式重新挂载rootfs
- 挂载
/etc/fstab
中设置的文件系统,如果要挂载 NFS 需要先配置网络,如果指定了fsck
则检查文件系统 - 激活 swap 分区
- 清理
2.3 /etc/rc.d/rc
很显然,不同的运行级别下系统初始化时需要运行的进程或服务是不同的,比如运行级别为 3
时不需要启动 X Display Manager
桌面系统。更改运行级别后,会根据 /etc/inittab
文件中的如下内容来执行各运行级别对应的服务脚本:
l0:0:wait:/etc/rc.d/rc 0 l1:1:wait:/etc/rc.d/rc 1 l2:2:wait:/etc/rc.d/rc 2 l3:3:wait:/etc/rc.d/rc 3 l4:4:wait:/etc/rc.d/rc 4 l5:5:wait:/etc/rc.d/rc 5 l6:6:wait:/etc/rc.d/rc 6
假设系统启动默认运行级别设置为 3,则运行 /etc/rc.d/rc 3
,这个脚本比较简单,会根据这两个命令行参数,找到 /etc/rc3.d
,这是一个软链接,它指向 /etc/rc.d/rc3.d/
目录
然后根据 /etc/rc3.d/
目录下的各脚本的 文件名
来判断是停止还是启动,其中以 K
开头(Kill)的脚本,如果检测到对应的服务已启动则停止它;以 S
开头(Start)的脚本,启动它。K
或 S
后面的数字表示各服务的启动/停止的顺序,因为 /etc/rc.d/rc
脚本中是用 for
循环去列出 /etc/rc3.d/
目录下的脚本,默认是按文件名排序,比如:
[root@CentOS ~]# ls -l /etc/rc3.d/ total 300 lrwxrwxrwx 1 root root 17 Dec 26 05:08 K01dnsmasq -> ../init.d/dnsmasq lrwxrwxrwx 1 root root 24 Dec 26 05:08 K02avahi-dnsconfd -> ../init.d/avahi-dnsconfd lrwxrwxrwx 1 root root 24 Dec 26 05:10 K02NetworkManager -> ../init.d/NetworkManager lrwxrwxrwx 1 root root 17 Dec 26 05:08 K02oddjobd -> ../init.d/oddjobd lrwxrwxrwx 1 root root 16 Dec 26 05:07 K05conman -> ../init.d/conman lrwxrwxrwx 1 root root 19 Dec 26 05:08 K05saslauthd -> ../init.d/saslauthd lrwxrwxrwx 1 root root 17 Dec 26 05:09 K05wdaemon -> ../init.d/wdaemon lrwxrwxrwx 1 root root 16 Dec 26 05:07 K10psacct -> ../init.d/psacct lrwxrwxrwx 1 root root 14 Dec 26 05:07 K10tcsd -> ../init.d/tcsd lrwxrwxrwx 1 root root 15 Dec 26 05:08 K15httpd -> ../init.d/httpd lrwxrwxrwx 1 root root 13 Dec 26 05:10 K20nfs -> ../init.d/nfs lrwxrwxrwx 1 root root 14 Dec 26 05:10 K24irda -> ../init.d/irda lrwxrwxrwx 1 root root 19 Dec 26 05:10 K35vncserver -> ../init.d/vncserver lrwxrwxrwx 1 root root 17 Dec 26 05:14 K35winbind -> ../init.d/winbind lrwxrwxrwx 1 root root 20 Dec 26 05:08 K50netconsole -> ../init.d/netconsole lrwxrwxrwx 1 root root 15 Dec 26 05:08 K50snmpd -> ../init.d/snmpd lrwxrwxrwx 1 root root 19 Dec 26 05:08 K50snmptrapd -> ../init.d/snmptrapd lrwxrwxrwx 1 root root 20 Dec 26 05:10 K69rpcsvcgssd -> ../init.d/rpcsvcgssd lrwxrwxrwx 1 root root 16 Dec 26 05:14 K73ypbind -> ../init.d/ypbind lrwxrwxrwx 1 root root 14 Dec 26 05:07 K74nscd -> ../init.d/nscd lrwxrwxrwx 1 root root 14 Dec 26 05:34 K74ntpd -> ../init.d/ntpd lrwxrwxrwx 1 root root 15 Dec 26 05:09 K85mdmpd -> ../init.d/mdmpd lrwxrwxrwx 1 root root 20 Dec 26 05:07 K87multipathd -> ../init.d/multipathd lrwxrwxrwx 1 root root 24 Dec 26 05:08 K88wpa_supplicant -> ../init.d/wpa_supplicant lrwxrwxrwx 1 root root 14 Dec 26 05:09 K89dund -> ../init.d/dund lrwxrwxrwx 1 root root 18 Dec 26 05:07 K89netplugd -> ../init.d/netplugd lrwxrwxrwx 1 root root
0 条评论
评论者的用户名
评论时间暂时还没有评论.